diff --git a/.gitattributes b/.gitattributes index 3ee199bb7c699cf8c44b7227552209adae799c14..f4bb05208abe2e3dfde5c1f896a50c1e98bef272 100644 --- a/.gitattributes +++ b/.gitattributes @@ -259,3 +259,225 @@ py311/lib/python3.11/site-packages/numpy/testing/_private/__pycache__/utils.cpyt py311/lib/python3.11/site-packages/virtualenv/seed/wheels/embed/pip-25.0.1-py3-none-any.whl filter=lfs diff=lfs merge=lfs -text py311/lib/python3.11/site-packages/virtualenv/seed/wheels/embed/pip-25.3-py3-none-any.whl filter=lfs diff=lfs merge=lfs -text py311/lib/python3.11/site-packages/virtualenv/seed/wheels/embed/setuptools-75.3.2-py3-none-any.whl filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/linalg/_decomp_interpolative.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/linalg/_solve_toeplitz.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/linalg/_linalg_pythran.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/linalg/_decomp_lu_cython.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/linalg/_flapack.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/linalg/_cythonized_array_utils.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/linalg/_matfuncs_schur_sqrtm.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/special/__pycache__/_basic.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/sparse/__pycache__/_coo.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_tools.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_reordering.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_traversal.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_matching.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_shortest_path.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_flow.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/sparse/linalg/_propack.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/sparse/linalg/_dsolve/_superlu.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/sparse/linalg/_eigen/arpack/_arpacklib.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/ndimage/__pycache__/_morphology.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/integrate/__pycache__/_lebedev.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/optimize/_trlib/_trlib.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/optimize/__pycache__/_optimize.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/optimize/_highspy/_highs_options.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/optimize/_highspy/_core.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_morestats.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_multivariate.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_mstats_basic.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/stats/_rcont/rcont.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_distn_infrastructure.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_stats_py.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_discrete_distns.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_distribution_infrastructure.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_resampling.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_hypotests.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_continuous_distns.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_qmc.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/stats/_unuran/unuran_wrapper.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/io/matlab/_streams.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/io/matlab/_mio5_utils.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/io/_fast_matrix_market/_fmm_core.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/spatial/__pycache__/distance.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/spatial/transform/_rigid_transform_cy.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/spatial/transform/_rotation_cy.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/spatial/transform/__pycache__/_rotation.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/constants/__pycache__/_codata.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/fft/_pocketfft/pypocketfft.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/interpolate/__pycache__/_bsplines.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/interpolate/__pycache__/_interpolate.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/interpolate/__pycache__/_fitpack2.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/scipy/_lib/_uarray/_uarray.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/sas.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/groupby.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/hashing.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/testing.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/missing.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/parsers.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/tslib.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/reshape.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/writers.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/index.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/interval.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/lib.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/algos.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/hashtable.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/join.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/ops.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/sparse.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/internals.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/arrays.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/__pycache__/generic.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/__pycache__/indexing.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/__pycache__/resample.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/__pycache__/frame.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/__pycache__/series.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/reshape/__pycache__/merge.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/indexes/__pycache__/multi.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/strings/__pycache__/accessor.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/indexes/__pycache__/base.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/groupby/__pycache__/generic.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/groupby/__pycache__/groupby.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/window/__pycache__/rolling.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/internals/__pycache__/managers.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/internals/__pycache__/blocks.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/arrays/__pycache__/categorical.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/arrays/__pycache__/datetimelike.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/core/arrays/arrow/__pycache__/array.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/tslibs/timedeltas.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/tslibs/period.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/tslibs/parsing.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/tslibs/strptime.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/tslibs/timezones.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/tslibs/offsets.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/tslibs/nattype.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/tslibs/np_datetime.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/tslibs/dtypes.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/tslibs/vectorized.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/window/indexers.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/tslibs/timestamps.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/tslibs/fields.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/tslibs/tzconversion.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/tslibs/conversion.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/_libs/window/aggregations.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/io/__pycache__/sql.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/io/__pycache__/stata.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pandas/io/__pycache__/pytables.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/omegaconf/grammar/gen/__pycache__/OmegaConfGrammarParser.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/jinja2/__pycache__/compiler.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/rapidfuzz/distance/metrics_cpp_avx2.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/rapidfuzz/distance/_initialize_cpp.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/rapidfuzz/distance/metrics_cpp.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/mpl_toolkits/mplot3d/__pycache__/axes3d.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/click/__pycache__/core.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pydantic/__pycache__/types.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pydantic/__pycache__/json_schema.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_generate_schema.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/google/_upb/_message.abi3.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/google/protobuf/__pycache__/descriptor_pb2.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/google/genai/__pycache__/types.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/google/genai/__pycache__/models.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/google/ai/generativelanguage_v1beta/services/retriever_service/__pycache__/client.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/google/ai/generativelanguage_v1beta/services/retriever_service/transports/__pycache__/rest.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/rich/__pycache__/_emoji_codes.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/rich/__pycache__/console.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/backends/_backend_agg.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/backends/_tkagg.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/__pycache__/backend_bases.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/__pycache__/patches.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/__pycache__/figure.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/__pycache__/cbook.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/__pycache__/widgets.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/__pycache__/ticker.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/__pycache__/axis.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/__pycache__/pyplot.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/__pycache__/_mathtext.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/__pycache__/_cm_listed.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/__pycache__/transforms.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/__pycache__/collections.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/__pycache__/colors.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +eval_agent/__pycache__/ev2_service_standalone.cpython-313.pyc filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/_cffi_backend.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/30fcd23745efe32ce681__mypyc.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/share/jupyter/nbextensions/pydeck/index.js.map filter=lfs diff=lfs merge=lfs -text +.venv/bin/ty filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-BoldItalic.ttf filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/axes/__pycache__/_base.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/axes/__pycache__/_axes.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Bold.ttf filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-BoldOblique.ttf filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralItalic.ttf filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-BoldOblique.ttf filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif.ttf filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Oblique.ttf filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono.ttf filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Bold.ttf filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Bold.ttf filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Italic.ttf filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralBolIta.ttf filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneral.ttf filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Oblique.ttf filter=lfs diff=lfs merge=lfs -text +py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralBol.ttf filter=lfs diff=lfs merge=lfs -text +.venv/bin/python3.13 filter=lfs diff=lfs merge=lfs -text +.venv/bin/python filter=lfs diff=lfs merge=lfs -text +.venv/bin/python3 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pillow.libs/libharfbuzz-fe5b8f8d.so.0.61121.0 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pillow.libs/libopenjp2-56811f71.so.2.5.3 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pillow.libs/liblcms2-cc10e42f.so.2.0.17 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pillow.libs/libxcb-64009ff3.so.1.1.0 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pillow.libs/libpng16-d00bd151.so.16.49.0 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pillow.libs/libjpeg-8a13c6e0.so.62.4.0 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pillow.libs/libtiff-13a02c81.so.6.1.0 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pillow.libs/liblzma-64b7ab39.so.5.8.1 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pillow.libs/libwebp-5f0275c0.so.7.1.10 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pillow.libs/libfreetype-083ff72c.so.6.20.2 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pillow.libs/libbrotlicommon-c55a5f7a.so.1.1.0 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pillow.libs/libavif-01e67780.so.16.3.0 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/matplotlib/ft2font.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/wrapt/_wrappers.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/matplotlib/_c_internal_utils.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/matplotlib/_qhull.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/matplotlib/_path.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/matplotlib/_image.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/matplotlib/_tri.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/lxml/builder.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/lxml/sax.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/lxml/etree.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/lxml/objectify.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/lxml/_elementpath.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/lupa/lua53.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/lupa/luajit21.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/lupa/lua51.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/lupa/lua52.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/lupa/lua54.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/lupa/luajit20.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/rpds/rpds.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_feather.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_azurefs.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/libarrow_python.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/libparquet.so.2300 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/libarrow_acero.so.2300 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_parquet_encryption.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/libarrow_python.so.2300 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_hdfs.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_compute.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_acero.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_json.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_orc.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_dataset.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_dataset_parquet.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_dataset_parquet_encryption.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_gcsfs.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_substrait.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_csv.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_flight.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/libarrow_python_flight.so.2300 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/libarrow_dataset.so.2300 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/libarrow_substrait.so.2300 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_s3fs.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/lib.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/_parquet.cpython-313-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/libarrow_python.so.2300.1.0 filter=lfs diff=lfs merge=lfs -text +.venv/lib/python3.13/site-packages/pyarrow/libarrow_python_flight.so.2300.1.0 filter=lfs diff=lfs merge=lfs -text diff --git a/.venv/bin/python b/.venv/bin/python new file mode 100644 index 0000000000000000000000000000000000000000..99b8337618d65f565cf709d445ca46540d3ffeb4 --- /dev/null +++ b/.venv/bin/python @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0535f14f86770225e573d5fa06ec422ae8a4d1e9b868ea98dee8d12db71fa199 +size 35565040 diff --git a/.venv/bin/python3 b/.venv/bin/python3 new file mode 100644 index 0000000000000000000000000000000000000000..99b8337618d65f565cf709d445ca46540d3ffeb4 --- /dev/null +++ b/.venv/bin/python3 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0535f14f86770225e573d5fa06ec422ae8a4d1e9b868ea98dee8d12db71fa199 +size 35565040 diff --git a/.venv/bin/python3.13 b/.venv/bin/python3.13 new file mode 100644 index 0000000000000000000000000000000000000000..99b8337618d65f565cf709d445ca46540d3ffeb4 --- /dev/null +++ b/.venv/bin/python3.13 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0535f14f86770225e573d5fa06ec422ae8a4d1e9b868ea98dee8d12db71fa199 +size 35565040 diff --git a/.venv/bin/ty b/.venv/bin/ty new file mode 100644 index 0000000000000000000000000000000000000000..1f0147bfe141fbab2df505f1328ba9a555f9d3b7 --- /dev/null +++ b/.venv/bin/ty @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c50510e61c0d7bcaf2bb30cd9dca61be9b1b164321b97f0580138909d8bef954 +size 22765536 diff --git a/.venv/lib/python3.13/site-packages/30fcd23745efe32ce681__mypyc.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/30fcd23745efe32ce681__mypyc.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..8c965f83614b0071e631644bf6d7a969474bf356 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/30fcd23745efe32ce681__mypyc.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0fd5145e3b41c4d64acaa4f88ceed09d8fd7de4ddbc240844cc869d5acc4aca2 +size 4517624 diff --git a/.venv/lib/python3.13/site-packages/__editable__.shinka-0.0.1.pth b/.venv/lib/python3.13/site-packages/__editable__.shinka-0.0.1.pth new file mode 100644 index 0000000000000000000000000000000000000000..7d059875b4d6a79f93261ffa80779fc70fba3a9b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/__editable__.shinka-0.0.1.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d856a7c7cc50f7367291c07c65ff7fcc8438539cd5a4adc4204502ec56b3e1f4 +size 83 diff --git a/.venv/lib/python3.13/site-packages/_cffi_backend.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/_cffi_backend.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..923ba23a384e4219170afb77e5de58e72921ff2a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/_cffi_backend.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4716712759d392db6b741965c28e4310c12ace1d30af457fb1bbe6eb53cd74a8 +size 348752 diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/__init__.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..013e9db3898fc9455eb5f60621c92cb709a900c8 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/__init__.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/args.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/args.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd35d972c5d8284b3d06593acbe42f5c9847cb93 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/args.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/auth.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/auth.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4a0bf032e49b7c8e12f11dfd15ccf2d207c76417 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/auth.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/awsrequest.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/awsrequest.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c8556290e26dc441536510c90a67b819c37640d Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/awsrequest.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/client.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/client.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b0ef6566ceee9a4864d90e21b751fe7c0e6088a0 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/client.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/compat.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/compat.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50a528302c0829e4b14b1df1260f752eecfb6818 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/compat.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/compress.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/compress.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ceac4e91a2852f88a3e88a73f5497d1f5bd586a0 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/compress.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/config.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/config.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..71a915bfad0a72cb11267375ad72bdfeceb7289c Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/config.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/configloader.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/configloader.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..77d6f83b0128c0cd24166af62b7dadfa819dcdff Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/configloader.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/context.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/context.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6532784be26237ce6f410e33a957489d2fb63fc8 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/context.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/discovery.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/discovery.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1cb5574326ef9467306c032bbd0308bff9032f5c Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/discovery.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/endpoint.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/endpoint.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae86cf0ae529ac6f47de79382adc0a1179346bb2 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/endpoint.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/endpoint_provider.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/endpoint_provider.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..044c7faec3183290adef2e6145dccbf63998851c Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/endpoint_provider.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/eventstream.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/eventstream.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5110d0ebfa68e4e5776f9455700167f3dd8df637 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/eventstream.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/exceptions.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/exceptions.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4fe3bd198f248f474f4de70be53754b5b44499be Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/exceptions.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/history.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/history.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f11b004cb9026065536ebb972694181738120411 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/history.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/hooks.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/hooks.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..961a9d68815b8d4231d777ed7c54d73b75c565d8 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/hooks.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/httpchecksum.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/httpchecksum.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a1d790dfcd3dd127569dc0b2634af0c9b5942232 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/httpchecksum.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/httpsession.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/httpsession.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa14f5d1312c652270e88931a709a83fff451a2b Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/httpsession.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/model.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/model.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..934cdfb8a84348e4dafc539eee56439cb253c3fb Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/model.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/paginate.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/paginate.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..711f036e5abdc1f5bf761057a3732849c87d62fd Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/paginate.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/parsers.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/parsers.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7869ababd30d425e656d7fd5e623b23067d631cf Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/parsers.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/plugin.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/plugin.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7f6ad39b54d38dc66a76addd07b2a7ce209f9104 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/plugin.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/regions.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/regions.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..40cd1c47aa77a366f1ebbb35350182ba54d8f005 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/regions.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/response.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/response.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ce1d30a04dc8321cb62fe7b085a07a2e81c99333 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/response.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/serialize.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/serialize.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..59a59d7198a411090d750046d1288b438e089f38 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/serialize.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/signers.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/signers.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c7573aa0e8742c610e8a2df563de0c09a1d0f5c3 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/signers.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/tokens.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/tokens.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be48f0cac5cd4a3d39d330ced70a8847f9938280 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/tokens.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/useragent.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/useragent.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..087c9f2c57f4786d7c63eeb62f571a3614ef9f3d Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/useragent.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/validate.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/validate.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..85dc568fbf52803ddd694b99518aba91ad20ff5c Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/validate.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/__pycache__/waiter.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/__pycache__/waiter.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8afd07b37b84872078dee2fe59a625fcf930fff8 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/__pycache__/waiter.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/crt/__init__.py b/.venv/lib/python3.13/site-packages/botocore/crt/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..952ebf34cc37bde64e7fcd14a9b252a205429f47 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/crt/__init__.py @@ -0,0 +1,27 @@ +# Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. + +# A list of auth types supported by the signers in botocore/crt/auth.py. This +# should always match the keys of botocore.crt.auth.CRT_AUTH_TYPE_MAPS. The +# information is duplicated here so that it can be accessed in environments +# where `awscrt` is not present and any import from botocore.crt.auth would +# fail. +CRT_SUPPORTED_AUTH_TYPES = ( + 'v4', + 'v4-query', + 'v4a', + 's3v4', + 's3v4-query', + 's3v4a', + 's3v4a-query', +) diff --git a/.venv/lib/python3.13/site-packages/botocore/crt/auth.py b/.venv/lib/python3.13/site-packages/botocore/crt/auth.py new file mode 100644 index 0000000000000000000000000000000000000000..e36730e07ee60c578ac731e7dd0db856bb4f44a2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/crt/auth.py @@ -0,0 +1,629 @@ +# Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. + +from io import BytesIO + +from botocore.auth import ( + SIGNED_HEADERS_BLACKLIST, + STREAMING_UNSIGNED_PAYLOAD_TRAILER, + UNSIGNED_PAYLOAD, + BaseSigner, + _get_body_as_dict, + _host_from_url, +) +from botocore.compat import ( + HTTPHeaders, + awscrt, + get_current_datetime, + parse_qs, + urlsplit, + urlunsplit, +) +from botocore.exceptions import NoCredentialsError +from botocore.useragent import register_feature_id +from botocore.utils import percent_encode_sequence + + +class CrtSigV4Auth(BaseSigner): + REQUIRES_REGION = True + _PRESIGNED_HEADERS_BLOCKLIST = [ + 'Authorization', + 'X-Amz-Date', + 'X-Amz-Content-SHA256', + 'X-Amz-Security-Token', + ] + _SIGNATURE_TYPE = awscrt.auth.AwsSignatureType.HTTP_REQUEST_HEADERS + _USE_DOUBLE_URI_ENCODE = True + _SHOULD_NORMALIZE_URI_PATH = True + + def __init__(self, credentials, service_name, region_name): + self.credentials = credentials + self._service_name = service_name + self._region_name = region_name + self._expiration_in_seconds = None + + def _is_streaming_checksum_payload(self, request): + checksum_context = request.context.get('checksum', {}) + algorithm = checksum_context.get('request_algorithm') + return isinstance(algorithm, dict) and algorithm.get('in') == 'trailer' + + def add_auth(self, request): + if self.credentials is None: + raise NoCredentialsError() + + datetime_now = get_current_datetime(remove_tzinfo=False) + + # Use existing 'X-Amz-Content-SHA256' header if able + existing_sha256 = self._get_existing_sha256(request) + + self._modify_request_before_signing(request) + + credentials_provider = awscrt.auth.AwsCredentialsProvider.new_static( + access_key_id=self.credentials.access_key, + secret_access_key=self.credentials.secret_key, + session_token=self.credentials.token, + ) + + if self._is_streaming_checksum_payload(request): + explicit_payload = STREAMING_UNSIGNED_PAYLOAD_TRAILER + elif self._should_sha256_sign_payload(request): + if existing_sha256: + explicit_payload = existing_sha256 + else: + explicit_payload = None # to be calculated during signing + else: + explicit_payload = UNSIGNED_PAYLOAD + + if self._should_add_content_sha256_header(explicit_payload): + body_header = ( + awscrt.auth.AwsSignedBodyHeaderType.X_AMZ_CONTENT_SHA_256 + ) + else: + body_header = awscrt.auth.AwsSignedBodyHeaderType.NONE + + signing_config = awscrt.auth.AwsSigningConfig( + algorithm=awscrt.auth.AwsSigningAlgorithm.V4, + signature_type=self._SIGNATURE_TYPE, + credentials_provider=credentials_provider, + region=self._region_name, + service=self._service_name, + date=datetime_now, + should_sign_header=self._should_sign_header, + use_double_uri_encode=self._USE_DOUBLE_URI_ENCODE, + should_normalize_uri_path=self._SHOULD_NORMALIZE_URI_PATH, + signed_body_value=explicit_payload, + signed_body_header_type=body_header, + expiration_in_seconds=self._expiration_in_seconds, + ) + crt_request = self._crt_request_from_aws_request(request) + future = awscrt.auth.aws_sign_request(crt_request, signing_config) + future.result() + self._apply_signing_changes(request, crt_request) + + def _crt_request_from_aws_request(self, aws_request): + url_parts = urlsplit(aws_request.url) + crt_path = url_parts.path if url_parts.path else '/' + if aws_request.params: + array = [] + for param, value in aws_request.params.items(): + value = str(value) + array.append(f'{param}={value}') + crt_path = crt_path + '?' + '&'.join(array) + elif url_parts.query: + crt_path = f'{crt_path}?{url_parts.query}' + + crt_headers = awscrt.http.HttpHeaders(aws_request.headers.items()) + + # CRT requires body (if it exists) to be an I/O stream. + crt_body_stream = None + if aws_request.body: + if hasattr(aws_request.body, 'seek'): + crt_body_stream = aws_request.body + else: + crt_body_stream = BytesIO(aws_request.body) + + crt_request = awscrt.http.HttpRequest( + method=aws_request.method, + path=crt_path, + headers=crt_headers, + body_stream=crt_body_stream, + ) + return crt_request + + def _apply_signing_changes(self, aws_request, signed_crt_request): + # Apply changes from signed CRT request to the AWSRequest + aws_request.headers = HTTPHeaders.from_pairs( + list(signed_crt_request.headers) + ) + + def _should_sign_header(self, name, **kwargs): + return name.lower() not in SIGNED_HEADERS_BLACKLIST + + def _modify_request_before_signing(self, request): + # This could be a retry. Make sure the previous + # authorization headers are removed first. + for h in self._PRESIGNED_HEADERS_BLOCKLIST: + if h in request.headers: + del request.headers[h] + # If necessary, add the host header + if 'host' not in request.headers: + request.headers['host'] = _host_from_url(request.url) + + def _get_existing_sha256(self, request): + return request.headers.get('X-Amz-Content-SHA256') + + def _should_sha256_sign_payload(self, request): + # Payloads will always be signed over insecure connections. + if not request.url.startswith('https'): + return True + + # Certain operations may have payload signing disabled by default. + # Since we don't have access to the operation model, we pass in this + # bit of metadata through the request context. + return request.context.get('payload_signing_enabled', True) + + def _should_add_content_sha256_header(self, explicit_payload): + # only add X-Amz-Content-SHA256 header if payload is explicitly set + return explicit_payload is not None + + +class CrtS3SigV4Auth(CrtSigV4Auth): + # For S3, we do not normalize the path. + _USE_DOUBLE_URI_ENCODE = False + _SHOULD_NORMALIZE_URI_PATH = False + + def _get_existing_sha256(self, request): + # always recalculate + return None + + def _should_sha256_sign_payload(self, request): + # S3 allows optional body signing, so to minimize the performance + # impact, we opt to not SHA256 sign the body on streaming uploads, + # provided that we're on https. + client_config = request.context.get('client_config') + s3_config = getattr(client_config, 's3', None) + + # The config could be None if it isn't set, or if the customer sets it + # to None. + if s3_config is None: + s3_config = {} + + # The explicit configuration takes precedence over any implicit + # configuration. + sign_payload = s3_config.get('payload_signing_enabled', None) + if sign_payload is not None: + return sign_payload + + # We require that both a checksum be present and https be enabled + # to implicitly disable body signing. The combination of TLS and + # a checksum is sufficiently secure and durable for us to be + # confident in the request without body signing. + checksum_header = 'Content-MD5' + checksum_context = request.context.get('checksum', {}) + algorithm = checksum_context.get('request_algorithm') + if isinstance(algorithm, dict) and algorithm.get('in') == 'header': + checksum_header = algorithm['name'] + if ( + not request.url.startswith('https') + or checksum_header not in request.headers + ): + return True + + # If the input is streaming we disable body signing by default. + if request.context.get('has_streaming_input', False): + return False + + # If the S3-specific checks had no results, delegate to the generic + # checks. + return super()._should_sha256_sign_payload(request) + + def _should_add_content_sha256_header(self, explicit_payload): + # Always add X-Amz-Content-SHA256 header + return True + + +class CrtSigV4AsymAuth(BaseSigner): + REQUIRES_REGION = True + _PRESIGNED_HEADERS_BLOCKLIST = [ + 'Authorization', + 'X-Amz-Date', + 'X-Amz-Content-SHA256', + 'X-Amz-Security-Token', + ] + _SIGNATURE_TYPE = awscrt.auth.AwsSignatureType.HTTP_REQUEST_HEADERS + _USE_DOUBLE_URI_ENCODE = True + _SHOULD_NORMALIZE_URI_PATH = True + + def __init__(self, credentials, service_name, region_name): + self.credentials = credentials + self._service_name = service_name + self._region_name = region_name + self._expiration_in_seconds = None + + def add_auth(self, request): + register_feature_id("SIGV4A_SIGNING") + if self.credentials is None: + raise NoCredentialsError() + + datetime_now = get_current_datetime(remove_tzinfo=False) + + # Use existing 'X-Amz-Content-SHA256' header if able + existing_sha256 = self._get_existing_sha256(request) + + self._modify_request_before_signing(request) + + credentials_provider = awscrt.auth.AwsCredentialsProvider.new_static( + access_key_id=self.credentials.access_key, + secret_access_key=self.credentials.secret_key, + session_token=self.credentials.token, + ) + + if self._is_streaming_checksum_payload(request): + explicit_payload = STREAMING_UNSIGNED_PAYLOAD_TRAILER + elif self._should_sha256_sign_payload(request): + if existing_sha256: + explicit_payload = existing_sha256 + else: + explicit_payload = None # to be calculated during signing + else: + explicit_payload = UNSIGNED_PAYLOAD + + if self._should_add_content_sha256_header(explicit_payload): + body_header = ( + awscrt.auth.AwsSignedBodyHeaderType.X_AMZ_CONTENT_SHA_256 + ) + else: + body_header = awscrt.auth.AwsSignedBodyHeaderType.NONE + + signing_config = awscrt.auth.AwsSigningConfig( + algorithm=awscrt.auth.AwsSigningAlgorithm.V4_ASYMMETRIC, + signature_type=self._SIGNATURE_TYPE, + credentials_provider=credentials_provider, + region=self._region_name, + service=self._service_name, + date=datetime_now, + should_sign_header=self._should_sign_header, + use_double_uri_encode=self._USE_DOUBLE_URI_ENCODE, + should_normalize_uri_path=self._SHOULD_NORMALIZE_URI_PATH, + signed_body_value=explicit_payload, + signed_body_header_type=body_header, + expiration_in_seconds=self._expiration_in_seconds, + ) + crt_request = self._crt_request_from_aws_request(request) + future = awscrt.auth.aws_sign_request(crt_request, signing_config) + future.result() + self._apply_signing_changes(request, crt_request) + + def _crt_request_from_aws_request(self, aws_request): + url_parts = urlsplit(aws_request.url) + crt_path = url_parts.path if url_parts.path else '/' + if aws_request.params: + array = [] + for param, value in aws_request.params.items(): + value = str(value) + array.append(f'{param}={value}') + crt_path = crt_path + '?' + '&'.join(array) + elif url_parts.query: + crt_path = f'{crt_path}?{url_parts.query}' + + crt_headers = awscrt.http.HttpHeaders(aws_request.headers.items()) + + # CRT requires body (if it exists) to be an I/O stream. + crt_body_stream = None + if aws_request.body: + if hasattr(aws_request.body, 'seek'): + crt_body_stream = aws_request.body + else: + crt_body_stream = BytesIO(aws_request.body) + + crt_request = awscrt.http.HttpRequest( + method=aws_request.method, + path=crt_path, + headers=crt_headers, + body_stream=crt_body_stream, + ) + return crt_request + + def _apply_signing_changes(self, aws_request, signed_crt_request): + # Apply changes from signed CRT request to the AWSRequest + aws_request.headers = HTTPHeaders.from_pairs( + list(signed_crt_request.headers) + ) + + def _should_sign_header(self, name, **kwargs): + return name.lower() not in SIGNED_HEADERS_BLACKLIST + + def _modify_request_before_signing(self, request): + # This could be a retry. Make sure the previous + # authorization headers are removed first. + for h in self._PRESIGNED_HEADERS_BLOCKLIST: + if h in request.headers: + del request.headers[h] + # If necessary, add the host header + if 'host' not in request.headers: + request.headers['host'] = _host_from_url(request.url) + + def _get_existing_sha256(self, request): + return request.headers.get('X-Amz-Content-SHA256') + + def _is_streaming_checksum_payload(self, request): + checksum_context = request.context.get('checksum', {}) + algorithm = checksum_context.get('request_algorithm') + return isinstance(algorithm, dict) and algorithm.get('in') == 'trailer' + + def _should_sha256_sign_payload(self, request): + # Payloads will always be signed over insecure connections. + if not request.url.startswith('https'): + return True + + # Certain operations may have payload signing disabled by default. + # Since we don't have access to the operation model, we pass in this + # bit of metadata through the request context. + return request.context.get('payload_signing_enabled', True) + + def _should_add_content_sha256_header(self, explicit_payload): + # only add X-Amz-Content-SHA256 header if payload is explicitly set + return explicit_payload is not None + + +class CrtS3SigV4AsymAuth(CrtSigV4AsymAuth): + # For S3, we do not normalize the path. + _USE_DOUBLE_URI_ENCODE = False + _SHOULD_NORMALIZE_URI_PATH = False + + def _get_existing_sha256(self, request): + # always recalculate + return None + + def _should_sha256_sign_payload(self, request): + # S3 allows optional body signing, so to minimize the performance + # impact, we opt to not SHA256 sign the body on streaming uploads, + # provided that we're on https. + client_config = request.context.get('client_config') + s3_config = getattr(client_config, 's3', None) + + # The config could be None if it isn't set, or if the customer sets it + # to None. + if s3_config is None: + s3_config = {} + + # The explicit configuration takes precedence over any implicit + # configuration. + sign_payload = s3_config.get('payload_signing_enabled', None) + if sign_payload is not None: + return sign_payload + + # We require that both content-md5 be present and https be enabled + # to implicitly disable body signing. The combination of TLS and + # content-md5 is sufficiently secure and durable for us to be + # confident in the request without body signing. + if ( + not request.url.startswith('https') + or 'Content-MD5' not in request.headers + ): + return True + + # If the input is streaming we disable body signing by default. + if request.context.get('has_streaming_input', False): + return False + + # If the S3-specific checks had no results, delegate to the generic + # checks. + return super()._should_sha256_sign_payload(request) + + def _should_add_content_sha256_header(self, explicit_payload): + # Always add X-Amz-Content-SHA256 header + return True + + +class CrtSigV4AsymQueryAuth(CrtSigV4AsymAuth): + DEFAULT_EXPIRES = 3600 + _SIGNATURE_TYPE = awscrt.auth.AwsSignatureType.HTTP_REQUEST_QUERY_PARAMS + + def __init__( + self, credentials, service_name, region_name, expires=DEFAULT_EXPIRES + ): + super().__init__(credentials, service_name, region_name) + self._expiration_in_seconds = expires + + def _modify_request_before_signing(self, request): + super()._modify_request_before_signing(request) + + # We automatically set this header, so if it's the auto-set value we + # want to get rid of it since it doesn't make sense for presigned urls. + content_type = request.headers.get('content-type') + if content_type == 'application/x-www-form-urlencoded; charset=utf-8': + del request.headers['content-type'] + + # Now parse the original query string to a dict, inject our new query + # params, and serialize back to a query string. + url_parts = urlsplit(request.url) + # parse_qs makes each value a list, but in our case we know we won't + # have repeated keys so we know we have single element lists which we + # can convert back to scalar values. + query_string_parts = parse_qs(url_parts.query, keep_blank_values=True) + query_dict = {k: v[0] for k, v in query_string_parts.items()} + + # The spec is particular about this. It *has* to be: + # https://?& + # You can't mix the two types of params together, i.e just keep doing + # new_query_params.update(op_params) + # new_query_params.update(auth_params) + # percent_encode_sequence(new_query_params) + if request.data: + # We also need to move the body params into the query string. To + # do this, we first have to convert it to a dict. + query_dict.update(_get_body_as_dict(request)) + request.data = '' + new_query_string = percent_encode_sequence(query_dict) + # url_parts is a tuple (and therefore immutable) so we need to create + # a new url_parts with the new query string. + # - + # scheme - 0 + # netloc - 1 + # path - 2 + # query - 3 <-- we're replacing this. + # fragment - 4 + p = url_parts + new_url_parts = (p[0], p[1], p[2], new_query_string, p[4]) + request.url = urlunsplit(new_url_parts) + + def _apply_signing_changes(self, aws_request, signed_crt_request): + # Apply changes from signed CRT request to the AWSRequest + super()._apply_signing_changes(aws_request, signed_crt_request) + + signed_query = urlsplit(signed_crt_request.path).query + p = urlsplit(aws_request.url) + # urlsplit() returns a tuple (and therefore immutable) so we + # need to create new url with the new query string. + # - + # scheme - 0 + # netloc - 1 + # path - 2 + # query - 3 <-- we're replacing this. + # fragment - 4 + aws_request.url = urlunsplit((p[0], p[1], p[2], signed_query, p[4])) + + +class CrtS3SigV4AsymQueryAuth(CrtSigV4AsymQueryAuth): + """S3 SigV4A auth using query parameters. + This signer will sign a request using query parameters and signature + version 4A, i.e a "presigned url" signer. + """ + + # For S3, we do not normalize the path. + _USE_DOUBLE_URI_ENCODE = False + _SHOULD_NORMALIZE_URI_PATH = False + + def _should_sha256_sign_payload(self, request): + # From the doc link above: + # "You don't include a payload hash in the Canonical Request, because + # when you create a presigned URL, you don't know anything about the + # payload. Instead, you use a constant string "UNSIGNED-PAYLOAD". + return False + + def _should_add_content_sha256_header(self, explicit_payload): + # Never add X-Amz-Content-SHA256 header + return False + + +class CrtSigV4QueryAuth(CrtSigV4Auth): + DEFAULT_EXPIRES = 3600 + _SIGNATURE_TYPE = awscrt.auth.AwsSignatureType.HTTP_REQUEST_QUERY_PARAMS + + def __init__( + self, credentials, service_name, region_name, expires=DEFAULT_EXPIRES + ): + super().__init__(credentials, service_name, region_name) + self._expiration_in_seconds = expires + + def _modify_request_before_signing(self, request): + super()._modify_request_before_signing(request) + + # We automatically set this header, so if it's the auto-set value we + # want to get rid of it since it doesn't make sense for presigned urls. + content_type = request.headers.get('content-type') + if content_type == 'application/x-www-form-urlencoded; charset=utf-8': + del request.headers['content-type'] + + # Now parse the original query string to a dict, inject our new query + # params, and serialize back to a query string. + url_parts = urlsplit(request.url) + # parse_qs makes each value a list, but in our case we know we won't + # have repeated keys so we know we have single element lists which we + # can convert back to scalar values. + query_dict = { + k: v[0] + for k, v in parse_qs( + url_parts.query, keep_blank_values=True + ).items() + } + if request.params: + query_dict.update(request.params) + request.params = {} + # The spec is particular about this. It *has* to be: + # https://?& + # You can't mix the two types of params together, i.e just keep doing + # new_query_params.update(op_params) + # new_query_params.update(auth_params) + # percent_encode_sequence(new_query_params) + if request.data: + # We also need to move the body params into the query string. To + # do this, we first have to convert it to a dict. + query_dict.update(_get_body_as_dict(request)) + request.data = '' + new_query_string = percent_encode_sequence(query_dict) + # url_parts is a tuple (and therefore immutable) so we need to create + # a new url_parts with the new query string. + # - + # scheme - 0 + # netloc - 1 + # path - 2 + # query - 3 <-- we're replacing this. + # fragment - 4 + p = url_parts + new_url_parts = (p[0], p[1], p[2], new_query_string, p[4]) + request.url = urlunsplit(new_url_parts) + + def _apply_signing_changes(self, aws_request, signed_crt_request): + # Apply changes from signed CRT request to the AWSRequest + super()._apply_signing_changes(aws_request, signed_crt_request) + + signed_query = urlsplit(signed_crt_request.path).query + p = urlsplit(aws_request.url) + # urlsplit() returns a tuple (and therefore immutable) so we + # need to create new url with the new query string. + # - + # scheme - 0 + # netloc - 1 + # path - 2 + # query - 3 <-- we're replacing this. + # fragment - 4 + aws_request.url = urlunsplit((p[0], p[1], p[2], signed_query, p[4])) + + +class CrtS3SigV4QueryAuth(CrtSigV4QueryAuth): + """S3 SigV4 auth using query parameters. + This signer will sign a request using query parameters and signature + version 4, i.e a "presigned url" signer. + Based off of: + http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html + """ + + # For S3, we do not normalize the path. + _USE_DOUBLE_URI_ENCODE = False + _SHOULD_NORMALIZE_URI_PATH = False + + def _should_sha256_sign_payload(self, request): + # From the doc link above: + # "You don't include a payload hash in the Canonical Request, because + # when you create a presigned URL, you don't know anything about the + # payload. Instead, you use a constant string "UNSIGNED-PAYLOAD". + return False + + def _should_add_content_sha256_header(self, explicit_payload): + # Never add X-Amz-Content-SHA256 header + return False + + +# Defined at the bottom of module to ensure all Auth +# classes are defined. +CRT_AUTH_TYPE_MAPS = { + 'v4': CrtSigV4Auth, + 'v4-query': CrtSigV4QueryAuth, + 'v4a': CrtSigV4AsymAuth, + 's3v4': CrtS3SigV4Auth, + 's3v4-query': CrtS3SigV4QueryAuth, + 's3v4a': CrtS3SigV4AsymAuth, + 's3v4a-query': CrtS3SigV4AsymQueryAuth, +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/_retry.json b/.venv/lib/python3.13/site-packages/botocore/data/_retry.json new file mode 100644 index 0000000000000000000000000000000000000000..31e486e526de670b14126b95476d010e9b7b83a9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/_retry.json @@ -0,0 +1,300 @@ +{ + "definitions": { + "throttling": { + "applies_when": { + "response": { + "service_error_code": "Throttling", + "http_status_code": 400 + } + } + }, + "throttling_exception": { + "applies_when": { + "response": { + "service_error_code": "ThrottlingException", + "http_status_code": 400 + } + } + }, + "throttled_exception": { + "applies_when": { + "response": { + "service_error_code": "ThrottledException", + "http_status_code": 400 + } + } + }, + "request_throttled_exception": { + "applies_when": { + "response": { + "service_error_code": "RequestThrottledException", + "http_status_code": 400 + } + } + }, + "too_many_requests": { + "applies_when": { + "response": { + "http_status_code": 429 + } + } + }, + "general_socket_errors": { + "applies_when": { + "socket_errors": ["GENERAL_CONNECTION_ERROR"] + } + }, + "general_server_error": { + "applies_when": { + "response": { + "http_status_code": 500 + } + } + }, + "bad_gateway": { + "applies_when": { + "response": { + "http_status_code": 502 + } + } + }, + "service_unavailable": { + "applies_when": { + "response": { + "http_status_code": 503 + } + } + }, + "gateway_timeout": { + "applies_when": { + "response": { + "http_status_code": 504 + } + } + }, + "limit_exceeded": { + "applies_when": { + "response": { + "http_status_code": 509 + } + } + }, + "throughput_exceeded": { + "applies_when": { + "response": { + "service_error_code": "ProvisionedThroughputExceededException", + "http_status_code": 400 + } + } + } + }, + "retry": { + "__default__": { + "max_attempts": 5, + "delay": { + "type": "exponential", + "base": "rand", + "growth_factor": 2 + }, + "policies": { + "general_socket_errors": {"$ref": "general_socket_errors"}, + "general_server_error": {"$ref": "general_server_error"}, + "bad_gateway": {"$ref": "bad_gateway"}, + "service_unavailable": {"$ref": "service_unavailable"}, + "gateway_timeout": {"$ref": "gateway_timeout"}, + "limit_exceeded": {"$ref": "limit_exceeded"}, + "throttling_exception": {"$ref": "throttling_exception"}, + "throttled_exception": {"$ref": "throttled_exception"}, + "request_throttled_exception": {"$ref": "request_throttled_exception"}, + "throttling": {"$ref": "throttling"}, + "too_many_requests": {"$ref": "too_many_requests"}, + "throughput_exceeded": {"$ref": "throughput_exceeded"} + } + }, + "organizations": { + "__default__": { + "policies": { + "too_many_requests": { + "applies_when": { + "response": { + "service_error_code": "TooManyRequestsException", + "http_status_code": 400 + } + } + } + } + } + }, + "dynamodb": { + "__default__": { + "max_attempts": 10, + "delay": { + "type": "exponential", + "base": 0.05, + "growth_factor": 2 + }, + "policies": { + "write_conflict": { + "applies_when": { + "response": { + "service_error_code": "ReplicatedWriteConflictException", + "http_status_code": 409 + } + } + }, + "still_processing": { + "applies_when": { + "response": { + "service_error_code": "TransactionInProgressException", + "http_status_code": 400 + } + } + }, + "crc32": { + "applies_when": { + "response": { + "crc32body": "x-amz-crc32" + } + } + } + } + } + }, + "ec2": { + "__default__": { + "policies": { + "request_limit_exceeded": { + "applies_when": { + "response": { + "service_error_code": "RequestLimitExceeded", + "http_status_code": 503 + } + } + }, + "ec2_throttled_exception": { + "applies_when": { + "response": { + "service_error_code": "EC2ThrottledException", + "http_status_code": 503 + } + } + } + } + } + }, + "cloudsearch": { + "__default__": { + "policies": { + "request_limit_exceeded": { + "applies_when": { + "response": { + "service_error_code": "BandwidthLimitExceeded", + "http_status_code": 509 + } + } + } + } + } + }, + "kinesis": { + "__default__": { + "policies": { + "request_limit_exceeded": { + "applies_when": { + "response": { + "service_error_code": "LimitExceededException", + "http_status_code": 400 + } + } + } + } + } + }, + "sqs": { + "__default__": { + "policies": { + "request_limit_exceeded": { + "applies_when": { + "response": { + "service_error_code": "RequestThrottled", + "http_status_code": 403 + } + } + } + } + } + }, + "s3": { + "__default__": { + "policies": { + "timeouts": { + "applies_when": { + "response": { + "http_status_code": 400, + "service_error_code": "RequestTimeout" + } + } + }, + "contentmd5": { + "applies_when": { + "response": { + "http_status_code": 400, + "service_error_code": "BadDigest" + } + } + } + } + } + }, + "glacier": { + "__default__": { + "policies": { + "timeouts": { + "applies_when": { + "response": { + "http_status_code": 408, + "service_error_code": "RequestTimeoutException" + } + } + } + } + } + }, + "route53": { + "__default__": { + "policies": { + "request_limit_exceeded": { + "applies_when": { + "response": { + "service_error_code": "Throttling", + "http_status_code": 400 + } + } + }, + "still_processing": { + "applies_when": { + "response": { + "service_error_code": "PriorRequestNotComplete", + "http_status_code": 400 + } + } + } + } + } + }, + "sts": { + "__default__": { + "policies": { + "idp_unreachable_error": { + "applies_when": { + "response": { + "service_error_code": "IDPCommunicationError", + "http_status_code": 400 + } + } + } + } + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/accessanalyzer/2019-11-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/accessanalyzer/2019-11-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/accessanalyzer/2019-11-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/accessanalyzer/2019-11-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/accessanalyzer/2019-11-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..de88b6d49e7e18be0e405070bf4ae9807244f270 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/accessanalyzer/2019-11-01/paginators-1.json @@ -0,0 +1,70 @@ +{ + "pagination": { + "ListAnalyzedResources": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "analyzedResources" + }, + "ListAnalyzers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "analyzers" + }, + "ListArchiveRules": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "archiveRules" + }, + "ListFindings": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "findings" + }, + "ListAccessPreviewFindings": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "findings" + }, + "ListAccessPreviews": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "accessPreviews" + }, + "ValidatePolicy": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "findings" + }, + "ListPolicyGenerations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "policyGenerations" + }, + "GetFindingV2": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "findingDetails" + }, + "ListFindingsV2": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "findings" + }, + "GetFindingRecommendation": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "recommendedSteps" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/accessanalyzer/2019-11-01/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/accessanalyzer/2019-11-01/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..2fe19c01f73b1529b30060cc39ae96dcde5157c6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/accessanalyzer/2019-11-01/paginators-1.sdk-extras.json @@ -0,0 +1,31 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "GetFindingV2": { + "non_aggregate_keys": [ + "resource", + "status", + "error", + "createdAt", + "resourceType", + "findingType", + "resourceOwnerAccount", + "analyzedAt", + "id", + "updatedAt" + ] + }, + "GetFindingRecommendation": { + "non_aggregate_keys": [ + "status", + "error", + "completedAt", + "recommendationType", + "resourceArn", + "startedAt" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/acm-pca/2017-08-22/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/acm-pca/2017-08-22/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/acm-pca/2017-08-22/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/acm-pca/2017-08-22/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/acm-pca/2017-08-22/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..c1f4e234392577cbb9144a8d3b4ed7c000ba1345 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/acm-pca/2017-08-22/paginators-1.json @@ -0,0 +1,22 @@ +{ + "pagination": { + "ListCertificateAuthorities": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "CertificateAuthorities" + }, + "ListTags": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Tags" + }, + "ListPermissions": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Permissions" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/acm-pca/2017-08-22/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/acm-pca/2017-08-22/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..1d48140dbe45775034ff850c1ab52a69a1052627 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/acm-pca/2017-08-22/waiters-2.json @@ -0,0 +1,64 @@ +{ + "version" : 2, + "waiters" : { + "AuditReportCreated" : { + "description" : "Wait until a Audit Report is created", + "delay" : 3, + "maxAttempts" : 60, + "operation" : "DescribeCertificateAuthorityAuditReport", + "acceptors" : [ { + "matcher" : "path", + "argument" : "AuditReportStatus", + "state" : "success", + "expected" : "SUCCESS" + }, { + "matcher" : "path", + "argument" : "AuditReportStatus", + "state" : "failure", + "expected" : "FAILED" + }, { + "matcher" : "error", + "state" : "failure", + "expected" : "AccessDeniedException" + } ] + }, + "CertificateAuthorityCSRCreated" : { + "description" : "Wait until a Certificate Authority CSR is created", + "delay" : 3, + "maxAttempts" : 60, + "operation" : "GetCertificateAuthorityCsr", + "acceptors" : [ { + "matcher" : "error", + "state" : "success", + "expected" : false + }, { + "matcher" : "error", + "state" : "retry", + "expected" : "RequestInProgressException" + }, { + "matcher" : "error", + "state" : "failure", + "expected" : "AccessDeniedException" + } ] + }, + "CertificateIssued" : { + "description" : "Wait until a certificate is issued", + "delay" : 1, + "maxAttempts" : 60, + "operation" : "GetCertificate", + "acceptors" : [ { + "matcher" : "error", + "state" : "success", + "expected" : false + }, { + "matcher" : "error", + "state" : "retry", + "expected" : "RequestInProgressException" + }, { + "matcher" : "error", + "state" : "failure", + "expected" : "AccessDeniedException" + } ] + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/amp/2020-08-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/amp/2020-08-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/amp/2020-08-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/amp/2020-08-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/amp/2020-08-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..656dd3a23679552792d42fa186d76f74e128167d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/amp/2020-08-01/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "ListWorkspaces": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "workspaces" + }, + "ListRuleGroupsNamespaces": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "ruleGroupsNamespaces" + }, + "ListScrapers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "scrapers" + }, + "ListAnomalyDetectors": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "anomalyDetectors" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/amp/2020-08-01/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/amp/2020-08-01/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..0222806aadc877d482779942729e8498b9857c20 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/amp/2020-08-01/waiters-2.json @@ -0,0 +1,114 @@ +{ + "version" : 2, + "waiters" : { + "AnomalyDetectorActive" : { + "description" : "Wait until the anomaly detector reaches ACTIVE status", + "delay" : 2, + "maxAttempts" : 60, + "operation" : "DescribeAnomalyDetector", + "acceptors" : [ { + "matcher" : "path", + "argument" : "anomalyDetector.status.statusCode", + "state" : "success", + "expected" : "ACTIVE" + }, { + "matcher" : "path", + "argument" : "anomalyDetector.status.statusCode", + "state" : "retry", + "expected" : "CREATING" + }, { + "matcher" : "path", + "argument" : "anomalyDetector.status.statusCode", + "state" : "retry", + "expected" : "UPDATING" + } ] + }, + "AnomalyDetectorDeleted" : { + "description" : "Wait until the anomaly detector reaches DELETED status", + "delay" : 2, + "maxAttempts" : 60, + "operation" : "DescribeAnomalyDetector", + "acceptors" : [ { + "matcher" : "error", + "state" : "success", + "expected" : "ResourceNotFoundException" + }, { + "matcher" : "path", + "argument" : "anomalyDetector.status.statusCode", + "state" : "retry", + "expected" : "DELETING" + } ] + }, + "ScraperActive" : { + "description" : "Wait until a scraper reaches ACTIVE status", + "delay" : 2, + "maxAttempts" : 60, + "operation" : "DescribeScraper", + "acceptors" : [ { + "matcher" : "path", + "argument" : "scraper.status.statusCode", + "state" : "success", + "expected" : "ACTIVE" + }, { + "matcher" : "path", + "argument" : "scraper.status.statusCode", + "state" : "failure", + "expected" : "CREATION_FAILED" + } ] + }, + "ScraperDeleted" : { + "description" : "Wait until a scraper reaches DELETED status", + "delay" : 2, + "maxAttempts" : 60, + "operation" : "DescribeScraper", + "acceptors" : [ { + "matcher" : "error", + "state" : "success", + "expected" : "ResourceNotFoundException" + }, { + "matcher" : "path", + "argument" : "scraper.status.statusCode", + "state" : "failure", + "expected" : "DELETION_FAILED" + } ] + }, + "WorkspaceActive" : { + "description" : "Wait until a workspace reaches ACTIVE status", + "delay" : 2, + "maxAttempts" : 60, + "operation" : "DescribeWorkspace", + "acceptors" : [ { + "matcher" : "path", + "argument" : "workspace.status.statusCode", + "state" : "success", + "expected" : "ACTIVE" + }, { + "matcher" : "path", + "argument" : "workspace.status.statusCode", + "state" : "retry", + "expected" : "UPDATING" + }, { + "matcher" : "path", + "argument" : "workspace.status.statusCode", + "state" : "retry", + "expected" : "CREATING" + } ] + }, + "WorkspaceDeleted" : { + "description" : "Wait until a workspace reaches DELETED status", + "delay" : 2, + "maxAttempts" : 60, + "operation" : "DescribeWorkspace", + "acceptors" : [ { + "matcher" : "error", + "state" : "success", + "expected" : "ResourceNotFoundException" + }, { + "matcher" : "path", + "argument" : "workspace.status.statusCode", + "state" : "retry", + "expected" : "DELETING" + } ] + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/amplify/2017-07-25/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/amplify/2017-07-25/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/amplify/2017-07-25/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/amplify/2017-07-25/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/amplify/2017-07-25/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..f84208e94728c81c745ece3c87c87bffffffc371 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/amplify/2017-07-25/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "ListApps": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "apps" + }, + "ListBranches": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "branches" + }, + "ListDomainAssociations": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "domainAssociations" + }, + "ListJobs": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "jobSummaries" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/amplifybackend/2020-08-11/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/amplifybackend/2020-08-11/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..40304c7d438fddadc6e6ae26f20d803d8cd29757 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/amplifybackend/2020-08-11/paginators-1.json @@ -0,0 +1,10 @@ +{ + "pagination": { + "ListBackendJobs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Jobs" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/apigateway/2015-07-09/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/apigateway/2015-07-09/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/apigateway/2015-07-09/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/apigateway/2015-07-09/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/apigateway/2015-07-09/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..2a875c551e8792022e65bcf9b7835422d9db3946 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/apigateway/2015-07-09/paginators-1.json @@ -0,0 +1,117 @@ +{ + "pagination": { + "GetApiKeys": { + "input_token": "position", + "output_token": "position", + "limit_key": "limit", + "result_key": "items" + }, + "GetBasePathMappings": { + "input_token": "position", + "output_token": "position", + "limit_key": "limit", + "result_key": "items" + }, + "GetClientCertificates": { + "input_token": "position", + "output_token": "position", + "limit_key": "limit", + "result_key": "items" + }, + "GetDeployments": { + "input_token": "position", + "output_token": "position", + "limit_key": "limit", + "result_key": "items" + }, + "GetDomainNames": { + "input_token": "position", + "output_token": "position", + "limit_key": "limit", + "result_key": "items" + }, + "GetModels": { + "input_token": "position", + "output_token": "position", + "limit_key": "limit", + "result_key": "items" + }, + "GetResources": { + "input_token": "position", + "output_token": "position", + "limit_key": "limit", + "result_key": "items" + }, + "GetRestApis": { + "input_token": "position", + "output_token": "position", + "limit_key": "limit", + "result_key": "items" + }, + "GetUsage": { + "input_token": "position", + "output_token": "position", + "limit_key": "limit", + "result_key": "items", + "non_aggregate_keys": [ + "usagePlanId", + "startDate", + "endDate" + ] + }, + "GetUsagePlans": { + "input_token": "position", + "output_token": "position", + "limit_key": "limit", + "result_key": "items" + }, + "GetUsagePlanKeys": { + "input_token": "position", + "output_token": "position", + "limit_key": "limit", + "result_key": "items" + }, + "GetVpcLinks": { + "input_token": "position", + "limit_key": "limit", + "output_token": "position", + "result_key": "items" + }, + "GetAuthorizers": { + "input_token": "position", + "limit_key": "limit", + "output_token": "position", + "result_key": "items" + }, + "GetDocumentationParts": { + "input_token": "position", + "limit_key": "limit", + "output_token": "position", + "result_key": "items" + }, + "GetDocumentationVersions": { + "input_token": "position", + "limit_key": "limit", + "output_token": "position", + "result_key": "items" + }, + "GetGatewayResponses": { + "input_token": "position", + "limit_key": "limit", + "output_token": "position", + "result_key": "items" + }, + "GetRequestValidators": { + "input_token": "position", + "limit_key": "limit", + "output_token": "position", + "result_key": "items" + }, + "GetSdkTypes": { + "input_token": "position", + "limit_key": "limit", + "output_token": "position", + "result_key": "items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/appfabric/2023-05-19/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/appfabric/2023-05-19/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..8138e8a26496fa70a54219c5500729b0df249327 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/appfabric/2023-05-19/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "ListAppAuthorizations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "appAuthorizationSummaryList" + }, + "ListAppBundles": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "appBundleSummaryList" + }, + "ListIngestionDestinations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "ingestionDestinations" + }, + "ListIngestions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "ingestions" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/appfabric/2023-05-19/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/appfabric/2023-05-19/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/appfabric/2023-05-19/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/appintegrations/2020-07-29/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/appintegrations/2020-07-29/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/appintegrations/2020-07-29/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/appintegrations/2020-07-29/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/appintegrations/2020-07-29/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..64b4b5cb6cdee3a11742f755ba8b2734fefb7c1b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/appintegrations/2020-07-29/paginators-1.json @@ -0,0 +1,40 @@ +{ + "pagination": { + "ListApplications": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Applications" + }, + "ListDataIntegrationAssociations": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "DataIntegrationAssociations" + }, + "ListDataIntegrations": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "DataIntegrations" + }, + "ListEventIntegrationAssociations": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "EventIntegrationAssociations" + }, + "ListEventIntegrations": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "EventIntegrations" + }, + "ListApplicationAssociations": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ApplicationAssociations" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/application-autoscaling/2016-02-06/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/application-autoscaling/2016-02-06/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..5abcd5544a003f63bab2d3094caa1123d444e82f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/application-autoscaling/2016-02-06/examples-1.json @@ -0,0 +1,221 @@ +{ + "version": "1.0", + "examples": { + "DeleteScalingPolicy": [ + { + "input": { + "PolicyName": "web-app-cpu-lt-25", + "ResourceId": "service/default/web-app", + "ScalableDimension": "ecs:service:DesiredCount", + "ServiceNamespace": "ecs" + }, + "output": { + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deletes a scaling policy for the Amazon ECS service called web-app, which is running in the default cluster.", + "id": "to-delete-a-scaling-policy-1470863892689", + "title": "To delete a scaling policy" + } + ], + "DeregisterScalableTarget": [ + { + "input": { + "ResourceId": "service/default/web-app", + "ScalableDimension": "ecs:service:DesiredCount", + "ServiceNamespace": "ecs" + }, + "output": { + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deregisters a scalable target for an Amazon ECS service called web-app that is running in the default cluster.", + "id": "to-deregister-a-scalable-target-1470864164895", + "title": "To deregister a scalable target" + } + ], + "DescribeScalableTargets": [ + { + "input": { + "ServiceNamespace": "ecs" + }, + "output": { + "ScalableTargets": [ + { + "CreationTime": "2019-05-06T11:21:46.199Z", + "MaxCapacity": 10, + "MinCapacity": 1, + "ResourceId": "service/default/web-app", + "RoleARN": "arn:aws:iam::012345678910:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService", + "ScalableDimension": "ecs:service:DesiredCount", + "ServiceNamespace": "ecs", + "SuspendedState": { + "DynamicScalingInSuspended": false, + "DynamicScalingOutSuspended": false, + "ScheduledScalingSuspended": false + } + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the scalable targets for the ECS service namespace.", + "id": "to-describe-scalable-targets-1470864286961", + "title": "To describe scalable targets" + } + ], + "DescribeScalingActivities": [ + { + "input": { + "ResourceId": "service/default/web-app", + "ScalableDimension": "ecs:service:DesiredCount", + "ServiceNamespace": "ecs" + }, + "output": { + "ScalingActivities": [ + { + "ActivityId": "e6c5f7d1-dbbb-4a3f-89b2-51f33e766399", + "Cause": "monitor alarm web-app-cpu-lt-25 in state ALARM triggered policy web-app-cpu-lt-25", + "Description": "Setting desired count to 1.", + "EndTime": "2019-05-06T16:04:32.111Z", + "ResourceId": "service/default/web-app", + "ScalableDimension": "ecs:service:DesiredCount", + "ServiceNamespace": "ecs", + "StartTime": "2019-05-06T16:03:58.171Z", + "StatusCode": "Successful", + "StatusMessage": "Successfully set desired count to 1. Change successfully fulfilled by ecs." + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the scaling activities for an Amazon ECS service called web-app that is running in the default cluster.", + "id": "to-describe-scaling-activities-for-a-scalable-target-1470864398629", + "title": "To describe scaling activities for a scalable target" + } + ], + "DescribeScalingPolicies": [ + { + "input": { + "ServiceNamespace": "ecs" + }, + "output": { + "NextToken": "", + "ScalingPolicies": [ + { + "Alarms": [ + { + "AlarmARN": "arn:aws:cloudwatch:us-west-2:012345678910:alarm:web-app-cpu-gt-75", + "AlarmName": "web-app-cpu-gt-75" + } + ], + "CreationTime": "2019-05-06T12:11:39.230Z", + "PolicyARN": "arn:aws:autoscaling:us-west-2:012345678910:scalingPolicy:6d8972f3-efc8-437c-92d1-6270f29a66e7:resource/ecs/service/default/web-app:policyName/web-app-cpu-gt-75", + "PolicyName": "web-app-cpu-gt-75", + "PolicyType": "StepScaling", + "ResourceId": "service/default/web-app", + "ScalableDimension": "ecs:service:DesiredCount", + "ServiceNamespace": "ecs", + "StepScalingPolicyConfiguration": { + "AdjustmentType": "PercentChangeInCapacity", + "Cooldown": 60, + "StepAdjustments": [ + { + "MetricIntervalLowerBound": 0, + "ScalingAdjustment": 200 + } + ] + } + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the scaling policies for the ECS service namespace.", + "id": "to-describe-scaling-policies-1470864609734", + "title": "To describe scaling policies" + } + ], + "PutScalingPolicy": [ + { + "input": { + "PolicyName": "cpu75-target-tracking-scaling-policy", + "PolicyType": "TargetTrackingScaling", + "ResourceId": "service/default/web-app", + "ScalableDimension": "ecs:service:DesiredCount", + "ServiceNamespace": "ecs", + "TargetTrackingScalingPolicyConfiguration": { + "PredefinedMetricSpecification": { + "PredefinedMetricType": "ECSServiceAverageCPUUtilization" + }, + "ScaleInCooldown": 60, + "ScaleOutCooldown": 60, + "TargetValue": 75 + } + }, + "output": { + "Alarms": [ + { + "AlarmARN": "arn:aws:cloudwatch:us-west-2:012345678910:alarm:TargetTracking-service/default/web-app-AlarmHigh-d4f0770c-b46e-434a-a60f-3b36d653feca", + "AlarmName": "TargetTracking-service/default/web-app-AlarmHigh-d4f0770c-b46e-434a-a60f-3b36d653feca" + }, + { + "AlarmARN": "arn:aws:cloudwatch:us-west-2:012345678910:alarm:TargetTracking-service/default/web-app-AlarmLow-1b437334-d19b-4a63-a812-6c67aaf2910d", + "AlarmName": "TargetTracking-service/default/web-app-AlarmLow-1b437334-d19b-4a63-a812-6c67aaf2910d" + } + ], + "PolicyARN": "arn:aws:autoscaling:us-west-2:012345678910:scalingPolicy:6d8972f3-efc8-437c-92d1-6270f29a66e7:resource/ecs/service/default/web-app:policyName/cpu75-target-tracking-scaling-policy" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example applies a target tracking scaling policy with a predefined metric specification to an Amazon ECS service called web-app in the default cluster. The policy keeps the average CPU utilization of the service at 75 percent, with scale-out and scale-in cooldown periods of 60 seconds.", + "id": "to-apply-a-target-tracking-scaling-policy-with-a-predefined-metric-specification-1569364247984", + "title": "To apply a target tracking scaling policy with a predefined metric specification" + } + ], + "RegisterScalableTarget": [ + { + "input": { + "MaxCapacity": 10, + "MinCapacity": 1, + "ResourceId": "service/default/web-app", + "ScalableDimension": "ecs:service:DesiredCount", + "ServiceNamespace": "ecs" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example registers a scalable target from an Amazon ECS service called web-app that is running on the default cluster, with a minimum desired count of 1 task and a maximum desired count of 10 tasks.", + "id": "to-register-a-new-scalable-target-1470864910380", + "title": "To register an ECS service as a scalable target" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/application-autoscaling/2016-02-06/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/application-autoscaling/2016-02-06/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..7ec8f3afdc32ba1f18b57b4abd97d6b7cd39f835 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/application-autoscaling/2016-02-06/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "DescribeScalableTargets": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ScalableTargets" + }, + "DescribeScalingActivities": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ScalingActivities" + }, + "DescribeScalingPolicies": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ScalingPolicies" + }, + "DescribeScheduledActions": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ScheduledActions" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/applicationcostprofiler/2020-09-10/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/applicationcostprofiler/2020-09-10/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/applicationcostprofiler/2020-09-10/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/applicationcostprofiler/2020-09-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/applicationcostprofiler/2020-09-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..adffd06f188037f2a6843ae5bc467e977bfc5510 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/applicationcostprofiler/2020-09-10/paginators-1.json @@ -0,0 +1,10 @@ +{ + "pagination": { + "ListReportDefinitions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "reportDefinitions" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/appmesh/2018-10-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/appmesh/2018-10-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..752e89e032ee0f8e1efd4e7098313703bf934dbe --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/appmesh/2018-10-01/examples-1.json @@ -0,0 +1,4 @@ +{ + "version": "1.0", + "examples": { } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/appmesh/2018-10-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/appmesh/2018-10-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..162b8b96ddf663f1cc5e4d501e4661f55a8c9f17 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/appmesh/2018-10-01/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "ListMeshes": { + "input_token": "nextToken", + "limit_key": "limit", + "output_token": "nextToken", + "result_key": "meshes" + }, + "ListRoutes": { + "input_token": "nextToken", + "limit_key": "limit", + "output_token": "nextToken", + "result_key": "routes" + }, + "ListVirtualNodes": { + "input_token": "nextToken", + "limit_key": "limit", + "output_token": "nextToken", + "result_key": "virtualNodes" + }, + "ListVirtualRouters": { + "input_token": "nextToken", + "limit_key": "limit", + "output_token": "nextToken", + "result_key": "virtualRouters" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/appmesh/2019-01-25/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/appmesh/2019-01-25/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/appmesh/2019-01-25/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/appmesh/2019-01-25/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/appmesh/2019-01-25/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..5a79b5b5a3a700a1dcc2bf029ed557fd2590a737 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/appmesh/2019-01-25/paginators-1.json @@ -0,0 +1,52 @@ +{ + "pagination": { + "ListMeshes": { + "input_token": "nextToken", + "limit_key": "limit", + "output_token": "nextToken", + "result_key": "meshes" + }, + "ListRoutes": { + "input_token": "nextToken", + "limit_key": "limit", + "output_token": "nextToken", + "result_key": "routes" + }, + "ListVirtualNodes": { + "input_token": "nextToken", + "limit_key": "limit", + "output_token": "nextToken", + "result_key": "virtualNodes" + }, + "ListVirtualRouters": { + "input_token": "nextToken", + "limit_key": "limit", + "output_token": "nextToken", + "result_key": "virtualRouters" + }, + "ListVirtualServices": { + "input_token": "nextToken", + "limit_key": "limit", + "output_token": "nextToken", + "result_key": "virtualServices" + }, + "ListTagsForResource": { + "input_token": "nextToken", + "limit_key": "limit", + "output_token": "nextToken", + "result_key": "tags" + }, + "ListGatewayRoutes": { + "input_token": "nextToken", + "limit_key": "limit", + "output_token": "nextToken", + "result_key": "gatewayRoutes" + }, + "ListVirtualGateways": { + "input_token": "nextToken", + "limit_key": "limit", + "output_token": "nextToken", + "result_key": "virtualGateways" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/appstream/2016-12-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/appstream/2016-12-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/appstream/2016-12-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/appstream/2016-12-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/appstream/2016-12-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..40cbf4ba97e7a85792f57504a6e91c4a680ab991 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/appstream/2016-12-01/paginators-1.json @@ -0,0 +1,60 @@ +{ + "pagination": { + "DescribeDirectoryConfigs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "DirectoryConfigs" + }, + "DescribeFleets": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Fleets" + }, + "DescribeImageBuilders": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ImageBuilders" + }, + "DescribeImages": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Images" + }, + "DescribeSessions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "Limit", + "result_key": "Sessions" + }, + "DescribeStacks": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Stacks" + }, + "DescribeUserStackAssociations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "UserStackAssociations" + }, + "DescribeUsers": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Users" + }, + "ListAssociatedFleets": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Names" + }, + "ListAssociatedStacks": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Names" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/appstream/2016-12-01/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/appstream/2016-12-01/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..1c8dea0ded53105cb2069019548c8fc776f598a9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/appstream/2016-12-01/waiters-2.json @@ -0,0 +1,55 @@ +{ + "version": 2, + "waiters": { + "FleetStarted": { + "delay": 30, + "maxAttempts": 40, + "operation": "DescribeFleets", + "acceptors": [ + { + "state": "success", + "matcher": "pathAll", + "argument": "Fleets[].State", + "expected": "RUNNING" + }, + { + "state": "failure", + "matcher": "pathAny", + "argument": "Fleets[].State", + "expected": "STOPPING" + }, + { + "state": "failure", + "matcher": "pathAny", + "argument": "Fleets[].State", + "expected": "STOPPED" + } + ] + }, + "FleetStopped": { + "delay": 30, + "maxAttempts": 40, + "operation": "DescribeFleets", + "acceptors": [ + { + "state": "success", + "matcher": "pathAll", + "argument": "Fleets[].State", + "expected": "STOPPED" + }, + { + "state": "failure", + "matcher": "pathAny", + "argument": "Fleets[].State", + "expected": "STARTING" + }, + { + "state": "failure", + "matcher": "pathAny", + "argument": "Fleets[].State", + "expected": "RUNNING" + } + ] + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/artifact/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/artifact/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ae2de6dee1d818691e2e823ff52b2bfca253270e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/artifact/2018-05-10/paginators-1.json @@ -0,0 +1,22 @@ +{ + "pagination": { + "ListReports": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "reports" + }, + "ListCustomerAgreements": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "customerAgreements" + }, + "ListReportVersions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "reports" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/artifact/2018-05-10/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/artifact/2018-05-10/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/artifact/2018-05-10/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/autoscaling/2011-01-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/autoscaling/2011-01-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..af6929b4232176213db8cd80882b8954d185f62d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/autoscaling/2011-01-01/examples-1.json @@ -0,0 +1,1696 @@ +{ + "version": "1.0", + "examples": { + "AttachInstances": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "InstanceIds": [ + "i-93633f9b" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example attaches the specified instance to the specified Auto Scaling group.", + "id": "autoscaling-attach-instances-1", + "title": "To attach an instance to an Auto Scaling group" + } + ], + "AttachLoadBalancerTargetGroups": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "TargetGroupARNs": [ + "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example attaches the specified target group to the specified Auto Scaling group.", + "id": "autoscaling-attach-load-balancer-target-groups-1", + "title": "To attach a target group to an Auto Scaling group" + } + ], + "AttachLoadBalancers": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "LoadBalancerNames": [ + "my-load-balancer" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example attaches the specified load balancer to the specified Auto Scaling group.", + "id": "autoscaling-attach-load-balancers-1", + "title": "To attach a load balancer to an Auto Scaling group" + } + ], + "AttachTrafficSources": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "TrafficSources": [ + { + "Identifier": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067" + } + ] + }, + "output": { + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example attaches the specified target group to the specified Auto Scaling group.", + "id": "to-attach-a-target-group-to-an-auto-scaling-group-1680036570089", + "title": "To attach a target group to an Auto Scaling group" + } + ], + "CancelInstanceRefresh": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group" + }, + "output": { + "InstanceRefreshId": "08b91cf7-8fa6-48af-b6a6-d227f40f1b9b" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example cancels an instance refresh operation in progress.", + "id": "to-cancel-an-instance-refresh-1592960979817", + "title": "To cancel an instance refresh" + } + ], + "CompleteLifecycleAction": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "LifecycleActionResult": "CONTINUE", + "LifecycleActionToken": "bcd2f1b8-9a78-44d3-8a7a-4dd07d7cf635", + "LifecycleHookName": "my-lifecycle-hook" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example notifies Auto Scaling that the specified lifecycle action is complete so that it can finish launching or terminating the instance.", + "id": "autoscaling-complete-lifecycle-action-1", + "title": "To complete the lifecycle action" + } + ], + "CreateAutoScalingGroup": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "DefaultInstanceWarmup": 120, + "LaunchTemplate": { + "LaunchTemplateName": "my-template-for-auto-scaling", + "Version": "$Default" + }, + "MaxInstanceLifetime": 2592000, + "MaxSize": 3, + "MinSize": 1, + "VPCZoneIdentifier": "subnet-057fa0918fEXAMPLE" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example creates an Auto Scaling group.", + "id": "autoscaling-create-auto-scaling-group-1", + "title": "To create an Auto Scaling group" + }, + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "HealthCheckGracePeriod": 300, + "HealthCheckType": "ELB", + "LaunchTemplate": { + "LaunchTemplateName": "my-template-for-auto-scaling", + "Version": "$Default" + }, + "MaxSize": 3, + "MinSize": 1, + "TargetGroupARNs": [ + "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067" + ], + "VPCZoneIdentifier": "subnet-057fa0918fEXAMPLE, subnet-610acd08EXAMPLE" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example creates an Auto Scaling group and attaches the specified target group.", + "id": "autoscaling-create-auto-scaling-group-2", + "title": "To create an Auto Scaling group with an attached target group" + }, + { + "input": { + "AutoScalingGroupName": "my-asg", + "DesiredCapacity": 3, + "MaxSize": 5, + "MinSize": 1, + "MixedInstancesPolicy": { + "InstancesDistribution": { + "OnDemandBaseCapacity": 1, + "OnDemandPercentageAboveBaseCapacity": 50, + "SpotAllocationStrategy": "price-capacity-optimized" + }, + "LaunchTemplate": { + "LaunchTemplateSpecification": { + "LaunchTemplateName": "my-launch-template-for-x86", + "Version": "$Default" + }, + "Overrides": [ + { + "InstanceType": "c6g.large", + "LaunchTemplateSpecification": { + "LaunchTemplateName": "my-launch-template-for-arm", + "Version": "$Default" + } + }, + { + "InstanceType": "c5.large" + }, + { + "InstanceType": "c5a.large" + } + ] + } + }, + "VPCZoneIdentifier": "subnet-057fa0918fEXAMPLE, subnet-610acd08EXAMPLE" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example creates an Auto Scaling group with a mixed instances policy. It specifies the c5.large, c5a.large, and c6g.large instance types and defines a different launch template for the c6g.large instance type.", + "id": "autoscaling-create-auto-scaling-group-3", + "title": "To create an Auto Scaling group with a mixed instances policy" + }, + { + "input": { + "AutoScalingGroupName": "my-asg", + "DesiredCapacity": 4, + "DesiredCapacityType": "units", + "MaxSize": 100, + "MinSize": 0, + "MixedInstancesPolicy": { + "InstancesDistribution": { + "OnDemandPercentageAboveBaseCapacity": 50, + "SpotAllocationStrategy": "price-capacity-optimized" + }, + "LaunchTemplate": { + "LaunchTemplateSpecification": { + "LaunchTemplateName": "my-template-for-auto-scaling", + "Version": "$Default" + }, + "Overrides": [ + { + "InstanceRequirements": { + "CpuManufacturers": [ + "intel" + ], + "MemoryMiB": { + "Min": 16384 + }, + "VCpuCount": { + "Max": 8, + "Min": 4 + } + } + } + ] + } + }, + "VPCZoneIdentifier": "subnet-057fa0918fEXAMPLE, subnet-610acd08EXAMPLE" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example creates an Auto Scaling group using attribute-based instance type selection. It requires the instance types to have a minimum of four vCPUs and a maximum of eight vCPUs, a minimum of 16,384 MiB of memory, and an Intel manufactured CPU.", + "id": "autoscaling-create-auto-scaling-group-4", + "title": "To create an Auto Scaling group using attribute-based instance type selection" + } + ], + "CreateLaunchConfiguration": [ + { + "input": { + "IamInstanceProfile": "my-iam-role", + "ImageId": "ami-12345678", + "InstanceType": "m3.medium", + "LaunchConfigurationName": "my-launch-config", + "SecurityGroups": [ + "sg-eb2af88e" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example creates a launch configuration.", + "id": "autoscaling-create-launch-configuration-1", + "title": "To create a launch configuration" + } + ], + "CreateOrUpdateTags": [ + { + "input": { + "Tags": [ + { + "Key": "Role", + "PropagateAtLaunch": true, + "ResourceId": "my-auto-scaling-group", + "ResourceType": "auto-scaling-group", + "Value": "WebServer" + }, + { + "Key": "Dept", + "PropagateAtLaunch": true, + "ResourceId": "my-auto-scaling-group", + "ResourceType": "auto-scaling-group", + "Value": "Research" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example adds two tags to the specified Auto Scaling group.", + "id": "autoscaling-create-or-update-tags-1", + "title": "To create or update tags for an Auto Scaling group" + } + ], + "DeleteAutoScalingGroup": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deletes the specified Auto Scaling group.", + "id": "autoscaling-delete-auto-scaling-group-1", + "title": "To delete an Auto Scaling group" + }, + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "ForceDelete": true + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deletes the specified Auto Scaling group and all its instances.", + "id": "autoscaling-delete-auto-scaling-group-2", + "title": "To delete an Auto Scaling group and all its instances" + } + ], + "DeleteLaunchConfiguration": [ + { + "input": { + "LaunchConfigurationName": "my-launch-config" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deletes the specified launch configuration.", + "id": "autoscaling-delete-launch-configuration-1", + "title": "To delete a launch configuration" + } + ], + "DeleteLifecycleHook": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "LifecycleHookName": "my-lifecycle-hook" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deletes the specified lifecycle hook.", + "id": "autoscaling-delete-lifecycle-hook-1", + "title": "To delete a lifecycle hook" + } + ], + "DeleteNotificationConfiguration": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "TopicARN": "arn:aws:sns:us-west-2:123456789012:my-sns-topic" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deletes the specified notification from the specified Auto Scaling group.", + "id": "autoscaling-delete-notification-configuration-1", + "title": "To delete an Auto Scaling notification" + } + ], + "DeletePolicy": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "PolicyName": "my-step-scale-out-policy" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deletes the specified Auto Scaling policy.", + "id": "autoscaling-delete-policy-1", + "title": "To delete an Auto Scaling policy" + } + ], + "DeleteScheduledAction": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "ScheduledActionName": "my-scheduled-action" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deletes the specified scheduled action from the specified Auto Scaling group.", + "id": "autoscaling-delete-scheduled-action-1", + "title": "To delete a scheduled action from an Auto Scaling group" + } + ], + "DeleteTags": [ + { + "input": { + "Tags": [ + { + "Key": "Dept", + "ResourceId": "my-auto-scaling-group", + "ResourceType": "auto-scaling-group", + "Value": "Research" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deletes the specified tag from the specified Auto Scaling group.", + "id": "autoscaling-delete-tags-1", + "title": "To delete a tag from an Auto Scaling group" + } + ], + "DescribeAccountLimits": [ + { + "output": { + "MaxNumberOfAutoScalingGroups": 20, + "MaxNumberOfLaunchConfigurations": 100, + "NumberOfAutoScalingGroups": 3, + "NumberOfLaunchConfigurations": 5 + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the Amazon EC2 Auto Scaling service quotas for your account.", + "id": "autoscaling-describe-account-limits-1", + "title": "To describe your Auto Scaling account limits" + } + ], + "DescribeAdjustmentTypes": [ + { + "output": { + "AdjustmentTypes": [ + { + "AdjustmentType": "ChangeInCapacity" + }, + { + "AdjustmentType": "ExactCapcity" + }, + { + "AdjustmentType": "PercentChangeInCapacity" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the available adjustment types.", + "id": "autoscaling-describe-adjustment-types-1", + "title": "To describe the Amazon EC2 Auto Scaling adjustment types" + } + ], + "DescribeAutoScalingGroups": [ + { + "input": { + "AutoScalingGroupNames": [ + "my-auto-scaling-group" + ] + }, + "output": { + "AutoScalingGroups": [ + { + "AutoScalingGroupARN": "arn:aws:autoscaling:us-west-1:123456789012:autoScalingGroup:12345678-1234-1234-1234-123456789012:autoScalingGroupName/my-auto-scaling-group", + "AutoScalingGroupName": "my-auto-scaling-group", + "AvailabilityZones": [ + "us-west-2a", + "us-west-2b", + "us-west-2c" + ], + "CreatedTime": "2023-03-09T22:15:11.611Z", + "DefaultCooldown": 300, + "DesiredCapacity": 2, + "EnabledMetrics": [ + + ], + "HealthCheckGracePeriod": 300, + "HealthCheckType": "EC2", + "Instances": [ + { + "AvailabilityZone": "us-west-2c", + "HealthStatus": "Healthy", + "InstanceId": "i-05b4f7d5be44822a6", + "InstanceType": "t3.micro", + "LaunchConfigurationName": "my-launch-config", + "LifecycleState": "InService", + "ProtectedFromScaleIn": false + }, + { + "AvailabilityZone": "us-west-2b", + "HealthStatus": "Healthy", + "InstanceId": "i-0c20ac468fa3049e8", + "InstanceType": "t3.micro", + "LaunchConfigurationName": "my-launch-config", + "LifecycleState": "InService", + "ProtectedFromScaleIn": false + } + ], + "LaunchConfigurationName": "my-launch-config", + "LoadBalancerNames": [ + + ], + "MaxSize": 5, + "MinSize": 1, + "NewInstancesProtectedFromScaleIn": false, + "ServiceLinkedRoleARN": "arn:aws:iam::123456789012:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling", + "SuspendedProcesses": [ + + ], + "Tags": [ + + ], + "TargetGroupARNs": [ + + ], + "TerminationPolicies": [ + "Default" + ], + "TrafficSources": [ + + ], + "VPCZoneIdentifier": "subnet-5ea0c127,subnet-6194ea3b,subnet-c934b782" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the specified Auto Scaling group.", + "id": "autoscaling-describe-auto-scaling-groups-1", + "title": "To describe an Auto Scaling group" + } + ], + "DescribeAutoScalingInstances": [ + { + "input": { + "InstanceIds": [ + "i-05b4f7d5be44822a6" + ] + }, + "output": { + "AutoScalingInstances": [ + { + "AutoScalingGroupName": "my-auto-scaling-group", + "AvailabilityZone": "us-west-2c", + "HealthStatus": "HEALTHY", + "InstanceId": "i-05b4f7d5be44822a6", + "InstanceType": "t3.micro", + "LaunchConfigurationName": "my-launch-config", + "LifecycleState": "InService", + "ProtectedFromScaleIn": false + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the specified Auto Scaling instance.", + "id": "autoscaling-describe-auto-scaling-instances-1", + "title": "To describe one or more Auto Scaling instances" + } + ], + "DescribeAutoScalingNotificationTypes": [ + { + "output": { + "AutoScalingNotificationTypes": [ + "autoscaling:EC2_INSTANCE_LAUNCH", + "autoscaling:EC2_INSTANCE_LAUNCH_ERROR", + "autoscaling:EC2_INSTANCE_TERMINATE", + "autoscaling:EC2_INSTANCE_TERMINATE_ERROR", + "autoscaling:TEST_NOTIFICATION" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the available notification types.", + "id": "autoscaling-describe-auto-scaling-notification-types-1", + "title": "To describe the Auto Scaling notification types" + } + ], + "DescribeInstanceRefreshes": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group" + }, + "output": { + "InstanceRefreshes": [ + { + "AutoScalingGroupName": "my-auto-scaling-group", + "InstanceRefreshId": "08b91cf7-8fa6-48af-b6a6-d227f40f1b9b", + "InstancesToUpdate": 0, + "PercentageComplete": 50, + "Preferences": { + "AlarmSpecification": { + "Alarms": [ + "my-alarm" + ] + }, + "AutoRollback": true, + "InstanceWarmup": 200, + "MinHealthyPercentage": 90, + "ScaleInProtectedInstances": "Ignore", + "SkipMatching": false, + "StandbyInstances": "Ignore" + }, + "StartTime": "2023-06-13T16:46:52+00:00", + "Status": "InProgress", + "StatusReason": "Waiting for instances to warm up before continuing. For example: i-0645704820a8e83ff is warming up." + }, + { + "AutoScalingGroupName": "my-auto-scaling-group", + "EndTime": "2023-06-02T13:59:45+00:00", + "InstanceRefreshId": "0e151305-1e57-4a32-a256-1fd14157c5ec", + "InstancesToUpdate": 0, + "PercentageComplete": 100, + "Preferences": { + "AlarmSpecification": { + "Alarms": [ + "my-alarm" + ] + }, + "AutoRollback": true, + "InstanceWarmup": 200, + "MinHealthyPercentage": 90, + "ScaleInProtectedInstances": "Ignore", + "SkipMatching": false, + "StandbyInstances": "Ignore" + }, + "StartTime": "2023-06-02T13:53:37+00:00", + "Status": "Successful" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the instance refreshes for the specified Auto Scaling group.", + "id": "to-list-instance-refreshes-1592959593746", + "title": "To list instance refreshes" + } + ], + "DescribeLaunchConfigurations": [ + { + "input": { + "LaunchConfigurationNames": [ + "my-launch-config" + ] + }, + "output": { + "LaunchConfigurations": [ + { + "AssociatePublicIpAddress": true, + "BlockDeviceMappings": [ + + ], + "CreatedTime": "2014-05-07T17:39:28.599Z", + "EbsOptimized": false, + "ImageId": "ami-043a5034", + "InstanceMonitoring": { + "Enabled": true + }, + "InstanceType": "t1.micro", + "LaunchConfigurationARN": "arn:aws:autoscaling:us-west-2:123456789012:launchConfiguration:98d3b196-4cf9-4e88-8ca1-8547c24ced8b:launchConfigurationName/my-launch-config", + "LaunchConfigurationName": "my-launch-config", + "SecurityGroups": [ + "sg-67ef0308" + ] + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the specified launch configuration.", + "id": "autoscaling-describe-launch-configurations-1", + "title": "To describe Auto Scaling launch configurations" + } + ], + "DescribeLifecycleHookTypes": [ + { + "output": { + "LifecycleHookTypes": [ + "autoscaling:EC2_INSTANCE_LAUNCHING", + "autoscaling:EC2_INSTANCE_TERMINATING" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the available lifecycle hook types.", + "id": "autoscaling-describe-lifecycle-hook-types-1", + "title": "To describe the available types of lifecycle hooks" + } + ], + "DescribeLifecycleHooks": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group" + }, + "output": { + "LifecycleHooks": [ + { + "AutoScalingGroupName": "my-auto-scaling-group", + "DefaultResult": "ABANDON", + "GlobalTimeout": 172800, + "HeartbeatTimeout": 3600, + "LifecycleHookName": "my-lifecycle-hook", + "LifecycleTransition": "autoscaling:EC2_INSTANCE_LAUNCHING", + "NotificationTargetARN": "arn:aws:sns:us-west-2:123456789012:my-sns-topic", + "RoleARN": "arn:aws:iam::123456789012:role/my-auto-scaling-role" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the lifecycle hooks for the specified Auto Scaling group.", + "id": "autoscaling-describe-lifecycle-hooks-1", + "title": "To describe your lifecycle hooks" + } + ], + "DescribeLoadBalancerTargetGroups": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group" + }, + "output": { + "LoadBalancerTargetGroups": [ + { + "LoadBalancerTargetGroupARN": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "State": "Added" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the target groups attached to the specified Auto Scaling group.", + "id": "autoscaling-describe-load-balancer-target-groups-1", + "title": "To describe the target groups for an Auto Scaling group" + } + ], + "DescribeLoadBalancers": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group" + }, + "output": { + "LoadBalancers": [ + { + "LoadBalancerName": "my-load-balancer", + "State": "Added" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the load balancers attached to the specified Auto Scaling group.", + "id": "autoscaling-describe-load-balancers-1", + "title": "To describe the load balancers for an Auto Scaling group" + } + ], + "DescribeMetricCollectionTypes": [ + { + "output": { + "Granularities": [ + { + "Granularity": "1Minute" + } + ], + "Metrics": [ + { + "Metric": "GroupMinSize" + }, + { + "Metric": "GroupMaxSize" + }, + { + "Metric": "GroupDesiredCapacity" + }, + { + "Metric": "GroupInServiceInstances" + }, + { + "Metric": "GroupPendingInstances" + }, + { + "Metric": "GroupTerminatingInstances" + }, + { + "Metric": "GroupStandbyInstances" + }, + { + "Metric": "GroupTotalInstances" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the available metric collection types.", + "id": "autoscaling-describe-metric-collection-types-1", + "title": "To describe the Auto Scaling metric collection types" + } + ], + "DescribeNotificationConfigurations": [ + { + "input": { + "AutoScalingGroupNames": [ + "my-auto-scaling-group" + ] + }, + "output": { + "NotificationConfigurations": [ + { + "AutoScalingGroupName": "my-auto-scaling-group", + "NotificationType": "autoscaling:TEST_NOTIFICATION", + "TopicARN": "arn:aws:sns:us-west-2:123456789012:my-sns-topic-2" + }, + { + "AutoScalingGroupName": "my-auto-scaling-group", + "NotificationType": "autoscaling:TEST_NOTIFICATION", + "TopicARN": "arn:aws:sns:us-west-2:123456789012:my-sns-topic" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the notification configurations for the specified Auto Scaling group.", + "id": "autoscaling-describe-notification-configurations-1", + "title": "To describe Auto Scaling notification configurations" + } + ], + "DescribePolicies": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group" + }, + "output": { + "ScalingPolicies": [ + { + "AdjustmentType": "ChangeInCapacity", + "Alarms": [ + + ], + "AutoScalingGroupName": "my-auto-scaling-group", + "PolicyARN": "arn:aws:autoscaling:us-west-2:123456789012:scalingPolicy:2233f3d7-6290-403b-b632-93c553560106:autoScalingGroupName/my-auto-scaling-group:policyName/ScaleIn", + "PolicyName": "ScaleIn", + "ScalingAdjustment": -1 + }, + { + "AdjustmentType": "PercentChangeInCapacity", + "Alarms": [ + + ], + "AutoScalingGroupName": "my-auto-scaling-group", + "Cooldown": 60, + "MinAdjustmentStep": 2, + "PolicyARN": "arn:aws:autoscaling:us-west-2:123456789012:scalingPolicy:2b435159-cf77-4e89-8c0e-d63b497baad7:autoScalingGroupName/my-auto-scaling-group:policyName/ScalePercentChange", + "PolicyName": "ScalePercentChange", + "ScalingAdjustment": 25 + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the policies for the specified Auto Scaling group.", + "id": "autoscaling-describe-policies-1", + "title": "To describe scaling policies" + } + ], + "DescribeScalingActivities": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group" + }, + "output": { + "Activities": [ + { + "ActivityId": "f9f2d65b-f1f2-43e7-b46d-d86756459699", + "AutoScalingGroupARN": "arn:aws:autoscaling:us-east-1:123456789012:autoScalingGroup:12345678-1234-1234-1234-123456789012:autoScalingGroupName/my-auto-scaling-group", + "AutoScalingGroupName": "my-auto-scaling-group", + "Cause": "At 2013-08-19T20:53:25Z a user request created an AutoScalingGroup changing the desired capacity from 0 to 1. At 2013-08-19T20:53:29Z an instance was started in response to a difference between desired and actual capacity, increasing the capacity from 0 to 1.", + "Description": "Launching a new EC2 instance: i-4ba0837f", + "Details": "details", + "EndTime": "2013-08-19T20:54:02Z", + "Progress": 100, + "StartTime": "2013-08-19T20:53:29.930Z", + "StatusCode": "Successful" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the scaling activities for the specified Auto Scaling group.", + "id": "autoscaling-describe-scaling-activities-1", + "title": "To describe the scaling activities for an Auto Scaling group" + } + ], + "DescribeScalingProcessTypes": [ + { + "output": { + "Processes": [ + { + "ProcessName": "AZRebalance" + }, + { + "ProcessName": "AddToLoadBalancer" + }, + { + "ProcessName": "AlarmNotification" + }, + { + "ProcessName": "HealthCheck" + }, + { + "ProcessName": "Launch" + }, + { + "ProcessName": "ReplaceUnhealthy" + }, + { + "ProcessName": "ScheduledActions" + }, + { + "ProcessName": "Terminate" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the Auto Scaling process types.", + "id": "autoscaling-describe-scaling-process-types-1", + "title": "To describe the Auto Scaling process types" + } + ], + "DescribeScheduledActions": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group" + }, + "output": { + "ScheduledUpdateGroupActions": [ + { + "AutoScalingGroupName": "my-auto-scaling-group", + "DesiredCapacity": 4, + "MaxSize": 6, + "MinSize": 2, + "Recurrence": "30 0 1 12 0", + "ScheduledActionARN": "arn:aws:autoscaling:us-west-2:123456789012:scheduledUpdateGroupAction:8e86b655-b2e6-4410-8f29-b4f094d6871c:autoScalingGroupName/my-auto-scaling-group:scheduledActionName/my-scheduled-action", + "ScheduledActionName": "my-scheduled-action", + "StartTime": "2016-12-01T00:30:00Z", + "Time": "2016-12-01T00:30:00Z" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the scheduled actions for the specified Auto Scaling group.", + "id": "autoscaling-describe-scheduled-actions-1", + "title": "To describe scheduled actions" + } + ], + "DescribeTags": [ + { + "input": { + "Filters": [ + { + "Name": "auto-scaling-group", + "Values": [ + "my-auto-scaling-group" + ] + } + ] + }, + "output": { + "Tags": [ + { + "Key": "Dept", + "PropagateAtLaunch": true, + "ResourceId": "my-auto-scaling-group", + "ResourceType": "auto-scaling-group", + "Value": "Research" + }, + { + "Key": "Role", + "PropagateAtLaunch": true, + "ResourceId": "my-auto-scaling-group", + "ResourceType": "auto-scaling-group", + "Value": "WebServer" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the tags for the specified Auto Scaling group.", + "id": "autoscaling-describe-tags-1", + "title": "To describe tags" + } + ], + "DescribeTerminationPolicyTypes": [ + { + "output": { + "TerminationPolicyTypes": [ + "ClosestToNextInstanceHour", + "Default", + "NewestInstance", + "OldestInstance", + "OldestLaunchConfiguration" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the available termination policy types.", + "id": "autoscaling-describe-termination-policy-types-1", + "title": "To describe termination policy types" + } + ], + "DescribeTrafficSources": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group" + }, + "output": { + "NextToken": "", + "TrafficSources": [ + { + "Identifier": "arn:aws:vpc-lattice:us-west-2:123456789012:targetgroup/tg-0e2f2665eEXAMPLE", + "State": "InService", + "Type": "vpc-lattice" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the target groups attached to the specified Auto Scaling group.", + "id": "to-describe-the-target-groups-for-an-auto-scaling-group-1680040714521", + "title": "To describe the target groups for an Auto Scaling group" + } + ], + "DetachInstances": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "InstanceIds": [ + "i-93633f9b" + ], + "ShouldDecrementDesiredCapacity": true + }, + "output": { + "Activities": [ + { + "ActivityId": "5091cb52-547a-47ce-a236-c9ccbc2cb2c9", + "AutoScalingGroupName": "my-auto-scaling-group", + "Cause": "At 2015-04-12T15:02:16Z instance i-93633f9b was detached in response to a user request, shrinking the capacity from 2 to 1.", + "Description": "Detaching EC2 instance: i-93633f9b", + "Details": "details", + "Progress": 50, + "StartTime": "2015-04-12T15:02:16.179Z", + "StatusCode": "InProgress" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example detaches the specified instance from the specified Auto Scaling group.", + "id": "autoscaling-detach-instances-1", + "title": "To detach an instance from an Auto Scaling group" + } + ], + "DetachLoadBalancerTargetGroups": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "TargetGroupARNs": [ + "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example detaches the specified target group from the specified Auto Scaling group", + "id": "autoscaling-detach-load-balancer-target-groups-1", + "title": "To detach a target group from an Auto Scaling group" + } + ], + "DetachLoadBalancers": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "LoadBalancerNames": [ + "my-load-balancer" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example detaches the specified load balancer from the specified Auto Scaling group.", + "id": "autoscaling-detach-load-balancers-1", + "title": "To detach a load balancer from an Auto Scaling group" + } + ], + "DetachTrafficSources": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "TrafficSources": [ + { + "Identifier": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067" + } + ] + }, + "output": { + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example detaches the specified target group from the specified Auto Scaling group.", + "id": "to-detach-a-target-group-from-an-auto-scaling-group-1680040404169", + "title": "To detach a target group from an Auto Scaling group" + } + ], + "DisableMetricsCollection": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "Metrics": [ + "GroupDesiredCapacity" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example disables collecting data for the GroupDesiredCapacity metric for the specified Auto Scaling group.", + "id": "autoscaling-disable-metrics-collection-1", + "title": "To disable metrics collection for an Auto Scaling group" + } + ], + "EnableMetricsCollection": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "Granularity": "1Minute" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example enables data collection for the specified Auto Scaling group.", + "id": "autoscaling-enable-metrics-collection-1", + "title": "To enable metrics collection for an Auto Scaling group" + } + ], + "EnterStandby": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "InstanceIds": [ + "i-93633f9b" + ], + "ShouldDecrementDesiredCapacity": true + }, + "output": { + "Activities": [ + { + "ActivityId": "ffa056b4-6ed3-41ba-ae7c-249dfae6eba1", + "AutoScalingGroupName": "my-auto-scaling-group", + "Cause": "At 2015-04-12T15:10:23Z instance i-93633f9b was moved to standby in response to a user request, shrinking the capacity from 2 to 1.", + "Description": "Moving EC2 instance to Standby: i-93633f9b", + "Details": "details", + "Progress": 50, + "StartTime": "2015-04-12T15:10:23.640Z", + "StatusCode": "InProgress" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example puts the specified instance into standby mode.", + "id": "autoscaling-enter-standby-1", + "title": "To move instances into standby mode" + } + ], + "ExecutePolicy": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "BreachThreshold": 50.0, + "MetricValue": 59.0, + "PolicyName": "my-step-scale-out-policy" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example executes the specified policy.", + "id": "autoscaling-execute-policy-1", + "title": "To execute a scaling policy" + } + ], + "ExitStandby": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "InstanceIds": [ + "i-93633f9b" + ] + }, + "output": { + "Activities": [ + { + "ActivityId": "142928e1-a2dc-453a-9b24-b85ad6735928", + "AutoScalingGroupName": "my-auto-scaling-group", + "Cause": "At 2015-04-12T15:14:29Z instance i-93633f9b was moved out of standby in response to a user request, increasing the capacity from 1 to 2.", + "Description": "Moving EC2 instance out of Standby: i-93633f9b", + "Details": "details", + "Progress": 30, + "StartTime": "2015-04-12T15:14:29.886Z", + "StatusCode": "PreInService" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example moves the specified instance out of standby mode.", + "id": "autoscaling-exit-standby-1", + "title": "To move instances out of standby mode" + } + ], + "PutLifecycleHook": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "DefaultResult": "CONTINUE", + "HeartbeatTimeout": 300, + "LifecycleHookName": "my-launch-lifecycle-hook", + "LifecycleTransition": "autoscaling:EC2_INSTANCE_LAUNCHING" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example creates a lifecycle hook for instance launch.", + "id": "autoscaling-put-lifecycle-hook-1", + "title": "To create a launch lifecycle hook" + } + ], + "PutNotificationConfiguration": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "NotificationTypes": [ + "autoscaling:TEST_NOTIFICATION" + ], + "TopicARN": "arn:aws:sns:us-west-2:123456789012:my-sns-topic" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example adds the specified notification to the specified Auto Scaling group.", + "id": "autoscaling-put-notification-configuration-1", + "title": "To add an Auto Scaling notification" + } + ], + "PutScalingPolicy": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "PolicyName": "alb1000-target-tracking-scaling-policy", + "PolicyType": "TargetTrackingScaling", + "TargetTrackingConfiguration": { + "PredefinedMetricSpecification": { + "PredefinedMetricType": "ALBRequestCountPerTarget", + "ResourceLabel": "app/my-alb/778d41231b141a0f/targetgroup/my-alb-target-group/943f017f100becff" + }, + "TargetValue": 1000.0 + } + }, + "output": { + "Alarms": [ + { + "AlarmARN": "arn:aws:cloudwatch:us-west-2:123456789012:alarm:TargetTracking-my-asg-AlarmHigh-fc0e4183-23ac-497e-9992-691c9980c38e", + "AlarmName": "TargetTracking-my-asg-AlarmHigh-fc0e4183-23ac-497e-9992-691c9980c38e" + }, + { + "AlarmARN": "arn:aws:cloudwatch:us-west-2:123456789012:alarm:TargetTracking-my-asg-AlarmLow-61a39305-ed0c-47af-bd9e-471a352ee1a2", + "AlarmName": "TargetTracking-my-asg-AlarmLow-61a39305-ed0c-47af-bd9e-471a352ee1a2" + } + ], + "PolicyARN": "arn:aws:autoscaling:us-west-2:123456789012:scalingPolicy:228f02c2-c665-4bfd-aaac-8b04080bea3c:autoScalingGroupName/my-auto-scaling-group:policyName/alb1000-target-tracking-scaling-policy" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example adds the specified policy to the specified Auto Scaling group.", + "id": "autoscaling-put-scaling-policy-1", + "title": "To add a scaling policy to an Auto Scaling group" + } + ], + "PutScheduledUpdateGroupAction": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "DesiredCapacity": 4, + "EndTime": "2014-05-12T08:00:00Z", + "MaxSize": 6, + "MinSize": 2, + "ScheduledActionName": "my-scheduled-action", + "StartTime": "2014-05-12T08:00:00Z" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example adds the specified scheduled action to the specified Auto Scaling group.", + "id": "autoscaling-put-scheduled-update-group-action-1", + "title": "To add a scheduled action to an Auto Scaling group" + } + ], + "PutWarmPool": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "InstanceReusePolicy": { + "ReuseOnScaleIn": true + }, + "MinSize": 30, + "PoolState": "Hibernated" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example creates a warm pool for the specified Auto Scaling group.", + "id": "to-add-a-warm-pool-to-an-auto-scaling-group-1617818810383", + "title": "To create a warm pool for an Auto Scaling group" + } + ], + "RecordLifecycleActionHeartbeat": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "LifecycleActionToken": "bcd2f1b8-9a78-44d3-8a7a-4dd07d7cf635", + "LifecycleHookName": "my-lifecycle-hook" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example records a lifecycle action heartbeat to keep the instance in a pending state.", + "id": "autoscaling-record-lifecycle-action-heartbeat-1", + "title": "To record a lifecycle action heartbeat" + } + ], + "ResumeProcesses": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "ScalingProcesses": [ + "AlarmNotification" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example resumes the specified suspended scaling process for the specified Auto Scaling group.", + "id": "autoscaling-resume-processes-1", + "title": "To resume Auto Scaling processes" + } + ], + "SetDesiredCapacity": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "DesiredCapacity": 2, + "HonorCooldown": true + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example sets the desired capacity for the specified Auto Scaling group.", + "id": "autoscaling-set-desired-capacity-1", + "title": "To set the desired capacity for an Auto Scaling group" + } + ], + "SetInstanceHealth": [ + { + "input": { + "HealthStatus": "Unhealthy", + "InstanceId": "i-93633f9b" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example sets the health status of the specified instance to Unhealthy.", + "id": "autoscaling-set-instance-health-1", + "title": "To set the health status of an instance" + } + ], + "SetInstanceProtection": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "InstanceIds": [ + "i-93633f9b" + ], + "ProtectedFromScaleIn": true + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example enables instance protection for the specified instance.", + "id": "autoscaling-set-instance-protection-1", + "title": "To enable instance protection for an instance" + }, + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "InstanceIds": [ + "i-93633f9b" + ], + "ProtectedFromScaleIn": false + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example disables instance protection for the specified instance.", + "id": "autoscaling-set-instance-protection-2", + "title": "To disable instance protection for an instance" + } + ], + "StartInstanceRefresh": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "DesiredConfiguration": { + "LaunchTemplate": { + "LaunchTemplateName": "my-template-for-auto-scaling", + "Version": "$Latest" + } + }, + "Preferences": { + "AlarmSpecification": { + "Alarms": [ + "my-alarm" + ] + }, + "AutoRollback": true, + "InstanceWarmup": 200, + "MinHealthyPercentage": 90 + } + }, + "output": { + "InstanceRefreshId": "08b91cf7-8fa6-48af-b6a6-d227f40f1b9b" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example starts an instance refresh for the specified Auto Scaling group.", + "id": "to-start-an-instance-refresh-1592957271522", + "title": "To start an instance refresh" + } + ], + "SuspendProcesses": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "ScalingProcesses": [ + "AlarmNotification" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example suspends the specified scaling process for the specified Auto Scaling group.", + "id": "autoscaling-suspend-processes-1", + "title": "To suspend Auto Scaling processes" + } + ], + "TerminateInstanceInAutoScalingGroup": [ + { + "input": { + "InstanceId": "i-93633f9b", + "ShouldDecrementDesiredCapacity": false + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example terminates the specified instance from the specified Auto Scaling group without updating the size of the group. Auto Scaling launches a replacement instance after the specified instance terminates.", + "id": "autoscaling-terminate-instance-in-auto-scaling-group-1", + "title": "To terminate an instance in an Auto Scaling group" + } + ], + "UpdateAutoScalingGroup": [ + { + "input": { + "AutoScalingGroupName": "my-auto-scaling-group", + "LaunchTemplate": { + "LaunchTemplateName": "my-template-for-auto-scaling", + "Version": "2" + }, + "MaxSize": 5, + "MinSize": 1, + "NewInstancesProtectedFromScaleIn": true + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example updates multiple properties at the same time.", + "id": "autoscaling-update-auto-scaling-group-1", + "title": "To update an Auto Scaling group" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/autoscaling/2011-01-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/autoscaling/2011-01-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ac5939dfe545f889052afd10d93200aea559264e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/autoscaling/2011-01-01/paginators-1.json @@ -0,0 +1,70 @@ +{ + "pagination": { + "DescribeAutoScalingGroups": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxRecords", + "result_key": "AutoScalingGroups" + }, + "DescribeAutoScalingInstances": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxRecords", + "result_key": "AutoScalingInstances" + }, + "DescribeLaunchConfigurations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxRecords", + "result_key": "LaunchConfigurations" + }, + "DescribeNotificationConfigurations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxRecords", + "result_key": "NotificationConfigurations" + }, + "DescribePolicies": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxRecords", + "result_key": "ScalingPolicies" + }, + "DescribeScalingActivities": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxRecords", + "result_key": "Activities" + }, + "DescribeScheduledActions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxRecords", + "result_key": "ScheduledUpdateGroupActions" + }, + "DescribeTags": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxRecords", + "result_key": "Tags" + }, + "DescribeLoadBalancerTargetGroups": { + "input_token": "NextToken", + "limit_key": "MaxRecords", + "output_token": "NextToken", + "result_key": "LoadBalancerTargetGroups" + }, + "DescribeLoadBalancers": { + "input_token": "NextToken", + "limit_key": "MaxRecords", + "output_token": "NextToken", + "result_key": "LoadBalancers" + }, + "DescribeWarmPool": { + "input_token": "NextToken", + "limit_key": "MaxRecords", + "output_token": "NextToken", + "result_key": "Instances" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/autoscaling/2011-01-01/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/autoscaling/2011-01-01/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..1c63499294318cbbceca74373d91a13403dd4535 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/autoscaling/2011-01-01/paginators-1.sdk-extras.json @@ -0,0 +1,12 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "DescribeWarmPool": { + "non_aggregate_keys": [ + "WarmPoolConfiguration" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/b2bi/2022-06-23/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/b2bi/2022-06-23/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..5f3b0d242ce73407c92ab9e21d74d5586f7a0b1c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/b2bi/2022-06-23/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "ListCapabilities": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "capabilities" + }, + "ListPartnerships": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "partnerships" + }, + "ListProfiles": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "profiles" + }, + "ListTransformers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "transformers" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/b2bi/2022-06-23/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/b2bi/2022-06-23/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..35d86981d1c08848a752310bcaca3bc7ff225fc7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/b2bi/2022-06-23/waiters-2.json @@ -0,0 +1,21 @@ +{ + "version" : 2, + "waiters" : { + "TransformerJobSucceeded" : { + "delay" : 10, + "maxAttempts" : 12, + "operation" : "GetTransformerJob", + "acceptors" : [ { + "matcher" : "path", + "argument" : "status", + "state" : "success", + "expected" : "succeeded" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "failed" + } ] + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/backupsearch/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/backupsearch/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..bc482fde26ba8b28289c82ff794d83210e153875 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/backupsearch/2018-05-10/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "ListSearchJobBackups": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Results" + }, + "ListSearchJobResults": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Results" + }, + "ListSearchJobs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "SearchJobs" + }, + "ListSearchResultExportJobs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ExportJobs" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/backupsearch/2018-05-10/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/backupsearch/2018-05-10/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/backupsearch/2018-05-10/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/bcm-data-exports/2023-11-26/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/bcm-data-exports/2023-11-26/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..3d03805cd9c901bdadd930fc5ce7f45aee9c5eda --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/bcm-data-exports/2023-11-26/paginators-1.json @@ -0,0 +1,22 @@ +{ + "pagination": { + "ListExecutions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Executions" + }, + "ListExports": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Exports" + }, + "ListTables": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Tables" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/bcm-pricing-calculator/2024-06-19/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/bcm-pricing-calculator/2024-06-19/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..678b04a93dc21651f2f016c76071609aaa9a5507 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/bcm-pricing-calculator/2024-06-19/paginators-1.json @@ -0,0 +1,64 @@ +{ + "pagination": { + "ListBillEstimateCommitments": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListBillEstimateInputCommitmentModifications": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListBillEstimateInputUsageModifications": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListBillEstimateLineItems": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListBillEstimates": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListBillScenarioCommitmentModifications": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListBillScenarioUsageModifications": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListBillScenarios": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListWorkloadEstimateUsage": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListWorkloadEstimates": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/bcm-pricing-calculator/2024-06-19/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/bcm-pricing-calculator/2024-06-19/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/bcm-pricing-calculator/2024-06-19/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agent-runtime/2023-07-26/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agent-runtime/2023-07-26/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..d3b72464a00b7d98283018da92178bf933f821c8 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agent-runtime/2023-07-26/paginators-1.json @@ -0,0 +1,50 @@ +{ + "pagination": { + "Retrieve": { + "input_token": "nextToken", + "output_token": "nextToken", + "result_key": "retrievalResults" + }, + "GetAgentMemory": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxItems", + "result_key": "memoryContents" + }, + "Rerank": { + "input_token": "nextToken", + "output_token": "nextToken", + "result_key": "results" + }, + "ListInvocationSteps": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "invocationStepSummaries" + }, + "ListInvocations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "invocationSummaries" + }, + "ListSessions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "sessionSummaries" + }, + "ListFlowExecutionEvents": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "flowExecutionEvents" + }, + "ListFlowExecutions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "flowExecutionSummaries" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agent/2023-06-05/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agent/2023-06-05/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0daea1de84cec21422f551fe117f4633f30e7609 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agent/2023-06-05/paginators-1.json @@ -0,0 +1,88 @@ +{ + "pagination": { + "ListAgentActionGroups": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "actionGroupSummaries" + }, + "ListAgentAliases": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "agentAliasSummaries" + }, + "ListAgentKnowledgeBases": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "agentKnowledgeBaseSummaries" + }, + "ListAgentVersions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "agentVersionSummaries" + }, + "ListAgents": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "agentSummaries" + }, + "ListDataSources": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "dataSourceSummaries" + }, + "ListIngestionJobs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "ingestionJobSummaries" + }, + "ListKnowledgeBases": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "knowledgeBaseSummaries" + }, + "ListFlowAliases": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "flowAliasSummaries" + }, + "ListFlowVersions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "flowVersionSummaries" + }, + "ListFlows": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "flowSummaries" + }, + "ListPrompts": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "promptSummaries" + }, + "ListKnowledgeBaseDocuments": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "documentDetails" + }, + "ListAgentCollaborators": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "agentCollaboratorSummaries" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agentcore-control/2023-06-05/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agentcore-control/2023-06-05/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..745be8273355ba4b1f9366bdd7e2ea580632f880 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agentcore-control/2023-06-05/paginators-1.json @@ -0,0 +1,106 @@ +{ + "pagination": { + "ListAgentRuntimeEndpoints": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "runtimeEndpoints" + }, + "ListAgentRuntimeVersions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "agentRuntimes" + }, + "ListAgentRuntimes": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "agentRuntimes" + }, + "ListApiKeyCredentialProviders": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "credentialProviders" + }, + "ListBrowsers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "browserSummaries" + }, + "ListCodeInterpreters": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "codeInterpreterSummaries" + }, + "ListGatewayTargets": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListGateways": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListMemories": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "memories" + }, + "ListOauth2CredentialProviders": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "credentialProviders" + }, + "ListWorkloadIdentities": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "workloadIdentities" + }, + "ListEvaluators": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "evaluators" + }, + "ListOnlineEvaluationConfigs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "onlineEvaluationConfigs" + }, + "ListPolicies": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "policies" + }, + "ListPolicyEngines": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "policyEngines" + }, + "ListPolicyGenerationAssets": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "policyGenerationAssets" + }, + "ListPolicyGenerations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "policyGenerations" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agentcore-control/2023-06-05/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agentcore-control/2023-06-05/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..f6b282129c395f06afba830a030ccce33f1739ee --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agentcore-control/2023-06-05/waiters-2.json @@ -0,0 +1,149 @@ +{ + "version" : 2, + "waiters" : { + "MemoryCreated" : { + "delay" : 2, + "maxAttempts" : 60, + "operation" : "GetMemory", + "acceptors" : [ { + "matcher" : "path", + "argument" : "memory.status", + "state" : "retry", + "expected" : "CREATING" + }, { + "matcher" : "path", + "argument" : "memory.status", + "state" : "success", + "expected" : "ACTIVE" + }, { + "matcher" : "path", + "argument" : "memory.status", + "state" : "failure", + "expected" : "FAILED" + } ] + }, + "PolicyActive" : { + "description" : "Wait until a Policy is active", + "delay" : 2, + "maxAttempts" : 60, + "operation" : "GetPolicy", + "acceptors" : [ { + "matcher" : "path", + "argument" : "status", + "state" : "success", + "expected" : "ACTIVE" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "CREATE_FAILED" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "UPDATE_FAILED" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "DELETE_FAILED" + } ] + }, + "PolicyDeleted" : { + "description" : "Wait until a Policy is deleted", + "delay" : 2, + "maxAttempts" : 60, + "operation" : "GetPolicy", + "acceptors" : [ { + "matcher" : "error", + "state" : "success", + "expected" : "ResourceNotFoundException" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "retry", + "expected" : "DELETING" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "DELETE_FAILED" + } ] + }, + "PolicyEngineActive" : { + "description" : "Wait until a PolicyEngine is active", + "delay" : 2, + "maxAttempts" : 60, + "operation" : "GetPolicyEngine", + "acceptors" : [ { + "matcher" : "path", + "argument" : "status", + "state" : "success", + "expected" : "ACTIVE" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "CREATE_FAILED" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "UPDATE_FAILED" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "DELETE_FAILED" + } ] + }, + "PolicyEngineDeleted" : { + "description" : "Wait until a PolicyEngine is deleted", + "delay" : 2, + "maxAttempts" : 60, + "operation" : "GetPolicyEngine", + "acceptors" : [ { + "matcher" : "error", + "state" : "success", + "expected" : "ResourceNotFoundException" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "retry", + "expected" : "DELETING" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "DELETE_FAILED" + } ] + }, + "PolicyGenerationCompleted" : { + "description" : "Wait until policy generation is completed", + "delay" : 2, + "maxAttempts" : 60, + "operation" : "GetPolicyGeneration", + "acceptors" : [ { + "matcher" : "path", + "argument" : "status", + "state" : "success", + "expected" : "GENERATED" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "retry", + "expected" : "GENERATING" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "GENERATE_FAILED" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "DELETE_FAILED" + } ] + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agentcore/2024-02-28/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agentcore/2024-02-28/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..129086aa545fb76e91c7fabdf6e03c6b5334acc5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agentcore/2024-02-28/paginators-1.json @@ -0,0 +1,40 @@ +{ + "pagination": { + "ListActors": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "actorSummaries" + }, + "ListEvents": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "events" + }, + "ListMemoryRecords": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "memoryRecordSummaries" + }, + "ListSessions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "sessionSummaries" + }, + "RetrieveMemoryRecords": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "memoryRecordSummaries" + }, + "ListMemoryExtractionJobs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "jobs" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agentcore/2024-02-28/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agentcore/2024-02-28/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/bedrock-agentcore/2024-02-28/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/bedrock-data-automation/2023-07-26/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/bedrock-data-automation/2023-07-26/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..741799cc0ddb11e90c14f077d6ac75e0f483fa4f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/bedrock-data-automation/2023-07-26/paginators-1.json @@ -0,0 +1,16 @@ +{ + "pagination": { + "ListBlueprints": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "blueprints" + }, + "ListDataAutomationProjects": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "projects" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/braket/2019-09-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/braket/2019-09-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/braket/2019-09-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/braket/2019-09-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/braket/2019-09-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..2f0f69eb75a1439e171abca7c1b27c7c28a473a2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/braket/2019-09-01/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "SearchDevices": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "devices" + }, + "SearchQuantumTasks": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "quantumTasks" + }, + "SearchJobs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "jobs" + }, + "SearchSpendingLimits": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "spendingLimits" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/budgets/2016-10-20/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/budgets/2016-10-20/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/budgets/2016-10-20/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/budgets/2016-10-20/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/budgets/2016-10-20/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..15f7a63e05c9dbc1b31cc66f75bb3836263142d0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/budgets/2016-10-20/paginators-1.json @@ -0,0 +1,52 @@ +{ + "pagination": { + "DescribeBudgets": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Budgets" + }, + "DescribeNotificationsForBudget": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Notifications" + }, + "DescribeSubscribersForNotification": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Subscribers" + }, + "DescribeBudgetPerformanceHistory": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "BudgetPerformanceHistory" + }, + "DescribeBudgetActionHistories": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ActionHistories" + }, + "DescribeBudgetActionsForAccount": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Actions" + }, + "DescribeBudgetActionsForBudget": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Actions" + }, + "DescribeBudgetNotificationsForAccount": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "BudgetNotificationsForAccount" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/chime-sdk-identity/2021-04-20/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/chime-sdk-identity/2021-04-20/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/chime-sdk-identity/2021-04-20/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/chime-sdk-identity/2021-04-20/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/chime-sdk-identity/2021-04-20/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/chime-sdk-identity/2021-04-20/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/chime-sdk-meetings/2021-07-15/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/chime-sdk-meetings/2021-07-15/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/chime-sdk-meetings/2021-07-15/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/chime-sdk-meetings/2021-07-15/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/chime-sdk-meetings/2021-07-15/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/chime-sdk-meetings/2021-07-15/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cleanroomsml/2023-09-06/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cleanroomsml/2023-09-06/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..570b41c8f284d94eb7a0a1c6263cff8f3bee2eae --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cleanroomsml/2023-09-06/paginators-1.json @@ -0,0 +1,100 @@ +{ + "pagination": { + "ListAudienceExportJobs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "audienceExportJobs" + }, + "ListAudienceGenerationJobs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "audienceGenerationJobs" + }, + "ListAudienceModels": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "audienceModels" + }, + "ListConfiguredAudienceModels": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "configuredAudienceModels" + }, + "ListTrainingDatasets": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "trainingDatasets" + }, + "ListCollaborationConfiguredModelAlgorithmAssociations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "collaborationConfiguredModelAlgorithmAssociations" + }, + "ListCollaborationMLInputChannels": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "collaborationMLInputChannelsList" + }, + "ListCollaborationTrainedModelExportJobs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "collaborationTrainedModelExportJobs" + }, + "ListCollaborationTrainedModelInferenceJobs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "collaborationTrainedModelInferenceJobs" + }, + "ListCollaborationTrainedModels": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "collaborationTrainedModels" + }, + "ListConfiguredModelAlgorithmAssociations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "configuredModelAlgorithmAssociations" + }, + "ListConfiguredModelAlgorithms": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "configuredModelAlgorithms" + }, + "ListMLInputChannels": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "mlInputChannelsList" + }, + "ListTrainedModelInferenceJobs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "trainedModelInferenceJobs" + }, + "ListTrainedModels": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "trainedModels" + }, + "ListTrainedModelVersions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "trainedModels" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cleanroomsml/2023-09-06/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/cleanroomsml/2023-09-06/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cleanroomsml/2023-09-06/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudcontrol/2021-09-30/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudcontrol/2021-09-30/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudcontrol/2021-09-30/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudcontrol/2021-09-30/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudcontrol/2021-09-30/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..14380b07447f80f178786eded893e6eb2d726afa --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudcontrol/2021-09-30/paginators-1.json @@ -0,0 +1,16 @@ +{ + "pagination": { + "ListResourceRequests": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ResourceRequestStatusSummaries" + }, + "ListResources": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ResourceDescriptions" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudcontrol/2021-09-30/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudcontrol/2021-09-30/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..d0d47fb7972ee2ebb4fe4c659b928baa1de7decf --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudcontrol/2021-09-30/paginators-1.sdk-extras.json @@ -0,0 +1,12 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "ListResources": { + "non_aggregate_keys": [ + "TypeName" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudcontrol/2021-09-30/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudcontrol/2021-09-30/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..e5f82acb29941a16a86198c5699d2aaa0faf36cd --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudcontrol/2021-09-30/waiters-2.json @@ -0,0 +1,27 @@ +{ + "version" : 2, + "waiters" : { + "ResourceRequestSuccess" : { + "description" : "Wait until resource operation request is successful", + "delay" : 5, + "maxAttempts" : 24, + "operation" : "GetResourceRequestStatus", + "acceptors" : [ { + "matcher" : "path", + "argument" : "ProgressEvent.OperationStatus", + "state" : "success", + "expected" : "SUCCESS" + }, { + "matcher" : "path", + "argument" : "ProgressEvent.OperationStatus", + "state" : "failure", + "expected" : "FAILED" + }, { + "matcher" : "path", + "argument" : "ProgressEvent.OperationStatus", + "state" : "failure", + "expected" : "CANCEL_COMPLETE" + } ] + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudformation/2010-05-15/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudformation/2010-05-15/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudformation/2010-05-15/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudformation/2010-05-15/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudformation/2010-05-15/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..55e601fe35ad52fa035bd8597e989e520c658769 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudformation/2010-05-15/paginators-1.json @@ -0,0 +1,143 @@ +{ + "pagination": { + "DescribeAccountLimits": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "AccountLimits" + }, + "DescribeChangeSet": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Changes", + "non_aggregate_keys": [ + "ChangeSetName", + "ChangeSetId", + "StackId", + "StackName", + "Description", + "Parameters", + "CreationTime", + "ExecutionStatus", + "Status", + "StatusReason", + "NotificationARNs", + "RollbackConfiguration", + "Capabilities", + "Tags", + "ParentChangeSetId", + "IncludeNestedStacks", + "RootChangeSetId", + "OnStackFailure", + "ImportExistingResources", + "StackDriftStatus", + "DeploymentMode" + ] + }, + "DescribeStackEvents": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "StackEvents" + }, + "DescribeStacks": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Stacks" + }, + "ListChangeSets": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Summaries" + }, + "ListStackInstances": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Summaries" + }, + "ListStackResources": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "StackResourceSummaries" + }, + "ListStacks": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "StackSummaries" + }, + "ListStackSetOperationResults": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Summaries" + }, + "ListStackSetOperations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Summaries" + }, + "ListStackSets": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Summaries" + }, + "ListExports": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Exports" + }, + "ListImports": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Imports" + }, + "ListTypes": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "TypeSummaries" + }, + "ListGeneratedTemplates": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Summaries" + }, + "ListResourceScanRelatedResources": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "RelatedResources" + }, + "ListResourceScanResources": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Resources" + }, + "ListResourceScans": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ResourceScanSummaries" + }, + "ListStackRefactorActions": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "StackRefactorActions" + }, + "ListStackRefactors": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "StackRefactorSummaries" + }, + "DescribeEvents": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "OperationEvents" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudformation/2010-05-15/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudformation/2010-05-15/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..0bfa9b00a134b314a72e7231422c71062433176b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudformation/2010-05-15/waiters-2.json @@ -0,0 +1,404 @@ +{ + "version": 2, + "waiters": { + "StackExists": { + "delay": 5, + "operation": "DescribeStacks", + "maxAttempts": 20, + "acceptors": [ + { + "matcher": "status", + "expected": 200, + "state": "success" + }, + { + "matcher": "error", + "expected": "ValidationError", + "state": "retry" + } + ] + }, + "StackCreateComplete": { + "delay": 30, + "operation": "DescribeStacks", + "maxAttempts": 120, + "description": "Wait until stack status is CREATE_COMPLETE.", + "acceptors": [ + { + "argument": "Stacks[].StackStatus", + "expected": "CREATE_COMPLETE", + "matcher": "pathAll", + "state": "success" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_COMPLETE", + "matcher": "pathAll", + "state": "success" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_IN_PROGRESS", + "matcher": "pathAll", + "state": "success" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS", + "matcher": "pathAll", + "state": "success" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_FAILED", + "matcher": "pathAll", + "state": "success" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_ROLLBACK_IN_PROGRESS", + "matcher": "pathAll", + "state": "success" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_ROLLBACK_FAILED", + "matcher": "pathAll", + "state": "success" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS", + "matcher": "pathAll", + "state": "success" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_ROLLBACK_COMPLETE", + "matcher": "pathAll", + "state": "success" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "CREATE_FAILED", + "matcher": "pathAny", + "state": "failure" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "DELETE_COMPLETE", + "matcher": "pathAny", + "state": "failure" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "DELETE_FAILED", + "matcher": "pathAny", + "state": "failure" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "ROLLBACK_FAILED", + "matcher": "pathAny", + "state": "failure" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "ROLLBACK_COMPLETE", + "matcher": "pathAny", + "state": "failure" + }, + { + "expected": "ValidationError", + "matcher": "error", + "state": "failure" + } + ] + }, + "StackDeleteComplete": { + "delay": 30, + "operation": "DescribeStacks", + "maxAttempts": 120, + "description": "Wait until stack status is DELETE_COMPLETE.", + "acceptors": [ + { + "argument": "Stacks[].StackStatus", + "expected": "DELETE_COMPLETE", + "matcher": "pathAll", + "state": "success" + }, + { + "expected": "ValidationError", + "matcher": "error", + "state": "success" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "DELETE_FAILED", + "matcher": "pathAny", + "state": "failure" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "CREATE_FAILED", + "matcher": "pathAny", + "state": "failure" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "ROLLBACK_FAILED", + "matcher": "pathAny", + "state": "failure" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_ROLLBACK_IN_PROGRESS", + "matcher": "pathAny", + "state": "failure" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_ROLLBACK_FAILED", + "matcher": "pathAny", + "state": "failure" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_ROLLBACK_COMPLETE", + "matcher": "pathAny", + "state": "failure" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_COMPLETE", + "matcher": "pathAny", + "state": "failure" + } + ] + }, + "StackUpdateComplete": { + "delay": 30, + "maxAttempts": 120, + "operation": "DescribeStacks", + "description": "Wait until stack status is UPDATE_COMPLETE.", + "acceptors": [ + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_COMPLETE", + "matcher": "pathAll", + "state": "success" + }, + { + "expected": "UPDATE_FAILED", + "matcher": "pathAny", + "state": "failure", + "argument": "Stacks[].StackStatus" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_ROLLBACK_FAILED", + "matcher": "pathAny", + "state": "failure" + }, + { + "expected": "UPDATE_ROLLBACK_COMPLETE", + "matcher": "pathAny", + "state": "failure", + "argument": "Stacks[].StackStatus" + }, + { + "expected": "ValidationError", + "matcher": "error", + "state": "failure" + } + ] + }, + "StackImportComplete": { + "delay": 30, + "maxAttempts": 120, + "operation": "DescribeStacks", + "description": "Wait until stack status is IMPORT_COMPLETE.", + "acceptors": [ + { + "argument": "Stacks[].StackStatus", + "expected": "IMPORT_COMPLETE", + "matcher": "pathAll", + "state": "success" + }, + { + "expected": "ROLLBACK_COMPLETE", + "matcher": "pathAny", + "state": "failure", + "argument": "Stacks[].StackStatus" + }, + { + "expected": "ROLLBACK_FAILED", + "matcher": "pathAny", + "state": "failure", + "argument": "Stacks[].StackStatus" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "IMPORT_ROLLBACK_IN_PROGRESS", + "matcher": "pathAny", + "state": "failure" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "IMPORT_ROLLBACK_FAILED", + "matcher": "pathAny", + "state": "failure" + }, + { + "expected": "IMPORT_ROLLBACK_COMPLETE", + "matcher": "pathAny", + "state": "failure", + "argument": "Stacks[].StackStatus" + }, + { + "expected": "ValidationError", + "matcher": "error", + "state": "failure" + } + ] + }, + "StackRollbackComplete": { + "delay": 30, + "operation": "DescribeStacks", + "maxAttempts": 120, + "description": "Wait until stack status is UPDATE_ROLLBACK_COMPLETE.", + "acceptors": [ + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_ROLLBACK_COMPLETE", + "matcher": "pathAll", + "state": "success" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_FAILED", + "matcher": "pathAny", + "state": "failure" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "UPDATE_ROLLBACK_FAILED", + "matcher": "pathAny", + "state": "failure" + }, + { + "argument": "Stacks[].StackStatus", + "expected": "DELETE_FAILED", + "matcher": "pathAny", + "state": "failure" + }, + { + "expected": "ValidationError", + "matcher": "error", + "state": "failure" + } + ] + }, + "ChangeSetCreateComplete": { + "delay": 30, + "operation": "DescribeChangeSet", + "maxAttempts": 120, + "description": "Wait until change set status is CREATE_COMPLETE.", + "acceptors": [ + { + "argument": "Status", + "expected": "CREATE_COMPLETE", + "matcher": "path", + "state": "success" + }, + { + "argument": "Status", + "expected": "FAILED", + "matcher": "path", + "state": "failure" + }, + { + "expected": "ValidationError", + "matcher": "error", + "state": "failure" + } + ] + }, + "StackRefactorCreateComplete": { + "delay": 5, + "operation": "DescribeStackRefactor", + "maxAttempts": 120, + "description": "Wait until the stack refactor status is CREATE_COMPLETE.", + "acceptors": [ + { + "argument": "Status", + "expected": "CREATE_COMPLETE", + "matcher": "path", + "state": "success" + }, + { + "argument": "Status", + "expected": "CREATE_FAILED", + "matcher": "path", + "state": "failure" + }, + { + "expected": "ValidationError", + "matcher": "error", + "state": "failure" + } + ] + }, + "StackRefactorExecuteComplete": { + "delay": 15, + "operation": "DescribeStackRefactor", + "maxAttempts": 120, + "description": "Wait until the stack refactor status is EXECUTE_COMPLETE.", + "acceptors": [ + { + "argument": "ExecutionStatus", + "expected": "EXECUTE_COMPLETE", + "matcher": "path", + "state": "success" + }, + { + "argument": "ExecutionStatus", + "expected": "EXECUTE_FAILED", + "matcher": "path", + "state": "failure" + }, + { + "argument": "ExecutionStatus", + "expected": "ROLLBACK_COMPLETE", + "matcher": "path", + "state": "failure" + }, + { + "expected": "ValidationError", + "matcher": "error", + "state": "failure" + } + ] + }, + "TypeRegistrationComplete": { + "delay": 30, + "operation": "DescribeTypeRegistration", + "maxAttempts": 120, + "description": "Wait until type registration is COMPLETE.", + "acceptors": [ + { + "argument": "ProgressStatus", + "expected": "COMPLETE", + "matcher": "path", + "state": "success" + }, + { + "argument": "ProgressStatus", + "expected": "FAILED", + "matcher": "path", + "state": "failure" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-05-31/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-05-31/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..51fbb907fa38d6d868c935bc108f30bff305bc4a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-05-31/paginators-1.json @@ -0,0 +1,32 @@ +{ + "pagination": { + "ListCloudFrontOriginAccessIdentities": { + "input_token": "Marker", + "output_token": "CloudFrontOriginAccessIdentityList.NextMarker", + "limit_key": "MaxItems", + "more_results": "CloudFrontOriginAccessIdentityList.IsTruncated", + "result_key": "CloudFrontOriginAccessIdentityList.Items" + }, + "ListDistributions": { + "input_token": "Marker", + "output_token": "DistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "DistributionList.IsTruncated", + "result_key": "DistributionList.Items" + }, + "ListInvalidations": { + "input_token": "Marker", + "output_token": "InvalidationList.NextMarker", + "limit_key": "MaxItems", + "more_results": "InvalidationList.IsTruncated", + "result_key": "InvalidationList.Items" + }, + "ListStreamingDistributions": { + "input_token": "Marker", + "output_token": "StreamingDistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "StreamingDistributionList.IsTruncated", + "result_key": "StreamingDistributionList.Items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-05-31/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-05-31/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..6e044bc51be95cbb262f7f3c37108499877e5775 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-05-31/waiters-2.json @@ -0,0 +1,47 @@ +{ + "version": 2, + "waiters": { + "DistributionDeployed": { + "delay": 60, + "operation": "GetDistribution", + "maxAttempts": 25, + "description": "Wait until a distribution is deployed.", + "acceptors": [ + { + "expected": "Deployed", + "matcher": "path", + "state": "success", + "argument": "Distribution.Status" + } + ] + }, + "InvalidationCompleted": { + "delay": 20, + "operation": "GetInvalidation", + "maxAttempts": 60, + "description": "Wait until an invalidation has completed.", + "acceptors": [ + { + "expected": "Completed", + "matcher": "path", + "state": "success", + "argument": "Invalidation.Status" + } + ] + }, + "StreamingDistributionDeployed": { + "delay": 60, + "operation": "GetStreamingDistribution", + "maxAttempts": 25, + "description": "Wait until a streaming distribution is deployed.", + "acceptors": [ + { + "expected": "Deployed", + "matcher": "path", + "state": "success", + "argument": "StreamingDistribution.Status" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-10-21/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-10-21/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..51fbb907fa38d6d868c935bc108f30bff305bc4a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-10-21/paginators-1.json @@ -0,0 +1,32 @@ +{ + "pagination": { + "ListCloudFrontOriginAccessIdentities": { + "input_token": "Marker", + "output_token": "CloudFrontOriginAccessIdentityList.NextMarker", + "limit_key": "MaxItems", + "more_results": "CloudFrontOriginAccessIdentityList.IsTruncated", + "result_key": "CloudFrontOriginAccessIdentityList.Items" + }, + "ListDistributions": { + "input_token": "Marker", + "output_token": "DistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "DistributionList.IsTruncated", + "result_key": "DistributionList.Items" + }, + "ListInvalidations": { + "input_token": "Marker", + "output_token": "InvalidationList.NextMarker", + "limit_key": "MaxItems", + "more_results": "InvalidationList.IsTruncated", + "result_key": "InvalidationList.Items" + }, + "ListStreamingDistributions": { + "input_token": "Marker", + "output_token": "StreamingDistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "StreamingDistributionList.IsTruncated", + "result_key": "StreamingDistributionList.Items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-10-21/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-10-21/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..6e044bc51be95cbb262f7f3c37108499877e5775 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-10-21/waiters-2.json @@ -0,0 +1,47 @@ +{ + "version": 2, + "waiters": { + "DistributionDeployed": { + "delay": 60, + "operation": "GetDistribution", + "maxAttempts": 25, + "description": "Wait until a distribution is deployed.", + "acceptors": [ + { + "expected": "Deployed", + "matcher": "path", + "state": "success", + "argument": "Distribution.Status" + } + ] + }, + "InvalidationCompleted": { + "delay": 20, + "operation": "GetInvalidation", + "maxAttempts": 60, + "description": "Wait until an invalidation has completed.", + "acceptors": [ + { + "expected": "Completed", + "matcher": "path", + "state": "success", + "argument": "Invalidation.Status" + } + ] + }, + "StreamingDistributionDeployed": { + "delay": 60, + "operation": "GetStreamingDistribution", + "maxAttempts": 25, + "description": "Wait until a streaming distribution is deployed.", + "acceptors": [ + { + "expected": "Deployed", + "matcher": "path", + "state": "success", + "argument": "StreamingDistribution.Status" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-11-06/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-11-06/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..51fbb907fa38d6d868c935bc108f30bff305bc4a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-11-06/paginators-1.json @@ -0,0 +1,32 @@ +{ + "pagination": { + "ListCloudFrontOriginAccessIdentities": { + "input_token": "Marker", + "output_token": "CloudFrontOriginAccessIdentityList.NextMarker", + "limit_key": "MaxItems", + "more_results": "CloudFrontOriginAccessIdentityList.IsTruncated", + "result_key": "CloudFrontOriginAccessIdentityList.Items" + }, + "ListDistributions": { + "input_token": "Marker", + "output_token": "DistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "DistributionList.IsTruncated", + "result_key": "DistributionList.Items" + }, + "ListInvalidations": { + "input_token": "Marker", + "output_token": "InvalidationList.NextMarker", + "limit_key": "MaxItems", + "more_results": "InvalidationList.IsTruncated", + "result_key": "InvalidationList.Items" + }, + "ListStreamingDistributions": { + "input_token": "Marker", + "output_token": "StreamingDistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "StreamingDistributionList.IsTruncated", + "result_key": "StreamingDistributionList.Items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-11-06/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-11-06/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..6e044bc51be95cbb262f7f3c37108499877e5775 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2014-11-06/waiters-2.json @@ -0,0 +1,47 @@ +{ + "version": 2, + "waiters": { + "DistributionDeployed": { + "delay": 60, + "operation": "GetDistribution", + "maxAttempts": 25, + "description": "Wait until a distribution is deployed.", + "acceptors": [ + { + "expected": "Deployed", + "matcher": "path", + "state": "success", + "argument": "Distribution.Status" + } + ] + }, + "InvalidationCompleted": { + "delay": 20, + "operation": "GetInvalidation", + "maxAttempts": 60, + "description": "Wait until an invalidation has completed.", + "acceptors": [ + { + "expected": "Completed", + "matcher": "path", + "state": "success", + "argument": "Invalidation.Status" + } + ] + }, + "StreamingDistributionDeployed": { + "delay": 60, + "operation": "GetStreamingDistribution", + "maxAttempts": 25, + "description": "Wait until a streaming distribution is deployed.", + "acceptors": [ + { + "expected": "Deployed", + "matcher": "path", + "state": "success", + "argument": "StreamingDistribution.Status" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2016-01-13/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2016-01-13/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..6e044bc51be95cbb262f7f3c37108499877e5775 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2016-01-13/waiters-2.json @@ -0,0 +1,47 @@ +{ + "version": 2, + "waiters": { + "DistributionDeployed": { + "delay": 60, + "operation": "GetDistribution", + "maxAttempts": 25, + "description": "Wait until a distribution is deployed.", + "acceptors": [ + { + "expected": "Deployed", + "matcher": "path", + "state": "success", + "argument": "Distribution.Status" + } + ] + }, + "InvalidationCompleted": { + "delay": 20, + "operation": "GetInvalidation", + "maxAttempts": 60, + "description": "Wait until an invalidation has completed.", + "acceptors": [ + { + "expected": "Completed", + "matcher": "path", + "state": "success", + "argument": "Invalidation.Status" + } + ] + }, + "StreamingDistributionDeployed": { + "delay": 60, + "operation": "GetStreamingDistribution", + "maxAttempts": 25, + "description": "Wait until a streaming distribution is deployed.", + "acceptors": [ + { + "expected": "Deployed", + "matcher": "path", + "state": "success", + "argument": "StreamingDistribution.Status" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2016-09-29/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2016-09-29/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2016-09-29/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2016-09-29/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2016-09-29/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..51fbb907fa38d6d868c935bc108f30bff305bc4a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2016-09-29/paginators-1.json @@ -0,0 +1,32 @@ +{ + "pagination": { + "ListCloudFrontOriginAccessIdentities": { + "input_token": "Marker", + "output_token": "CloudFrontOriginAccessIdentityList.NextMarker", + "limit_key": "MaxItems", + "more_results": "CloudFrontOriginAccessIdentityList.IsTruncated", + "result_key": "CloudFrontOriginAccessIdentityList.Items" + }, + "ListDistributions": { + "input_token": "Marker", + "output_token": "DistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "DistributionList.IsTruncated", + "result_key": "DistributionList.Items" + }, + "ListInvalidations": { + "input_token": "Marker", + "output_token": "InvalidationList.NextMarker", + "limit_key": "MaxItems", + "more_results": "InvalidationList.IsTruncated", + "result_key": "InvalidationList.Items" + }, + "ListStreamingDistributions": { + "input_token": "Marker", + "output_token": "StreamingDistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "StreamingDistributionList.IsTruncated", + "result_key": "StreamingDistributionList.Items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2016-09-29/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2016-09-29/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..6e044bc51be95cbb262f7f3c37108499877e5775 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2016-09-29/waiters-2.json @@ -0,0 +1,47 @@ +{ + "version": 2, + "waiters": { + "DistributionDeployed": { + "delay": 60, + "operation": "GetDistribution", + "maxAttempts": 25, + "description": "Wait until a distribution is deployed.", + "acceptors": [ + { + "expected": "Deployed", + "matcher": "path", + "state": "success", + "argument": "Distribution.Status" + } + ] + }, + "InvalidationCompleted": { + "delay": 20, + "operation": "GetInvalidation", + "maxAttempts": 60, + "description": "Wait until an invalidation has completed.", + "acceptors": [ + { + "expected": "Completed", + "matcher": "path", + "state": "success", + "argument": "Invalidation.Status" + } + ] + }, + "StreamingDistributionDeployed": { + "delay": 60, + "operation": "GetStreamingDistribution", + "maxAttempts": 25, + "description": "Wait until a streaming distribution is deployed.", + "acceptors": [ + { + "expected": "Deployed", + "matcher": "path", + "state": "success", + "argument": "StreamingDistribution.Status" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2017-10-30/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2017-10-30/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2017-10-30/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2017-10-30/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2017-10-30/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..51fbb907fa38d6d868c935bc108f30bff305bc4a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2017-10-30/paginators-1.json @@ -0,0 +1,32 @@ +{ + "pagination": { + "ListCloudFrontOriginAccessIdentities": { + "input_token": "Marker", + "output_token": "CloudFrontOriginAccessIdentityList.NextMarker", + "limit_key": "MaxItems", + "more_results": "CloudFrontOriginAccessIdentityList.IsTruncated", + "result_key": "CloudFrontOriginAccessIdentityList.Items" + }, + "ListDistributions": { + "input_token": "Marker", + "output_token": "DistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "DistributionList.IsTruncated", + "result_key": "DistributionList.Items" + }, + "ListInvalidations": { + "input_token": "Marker", + "output_token": "InvalidationList.NextMarker", + "limit_key": "MaxItems", + "more_results": "InvalidationList.IsTruncated", + "result_key": "InvalidationList.Items" + }, + "ListStreamingDistributions": { + "input_token": "Marker", + "output_token": "StreamingDistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "StreamingDistributionList.IsTruncated", + "result_key": "StreamingDistributionList.Items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2017-10-30/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2017-10-30/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..edd74b2a3b4ac1a57179d068f0a33255c60e72d4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2017-10-30/waiters-2.json @@ -0,0 +1,47 @@ +{ + "version": 2, + "waiters": { + "DistributionDeployed": { + "delay": 60, + "operation": "GetDistribution", + "maxAttempts": 25, + "description": "Wait until a distribution is deployed.", + "acceptors": [ + { + "expected": "Deployed", + "matcher": "path", + "state": "success", + "argument": "Distribution.Status" + } + ] + }, + "InvalidationCompleted": { + "delay": 20, + "operation": "GetInvalidation", + "maxAttempts": 30, + "description": "Wait until an invalidation has completed.", + "acceptors": [ + { + "expected": "Completed", + "matcher": "path", + "state": "success", + "argument": "Invalidation.Status" + } + ] + }, + "StreamingDistributionDeployed": { + "delay": 60, + "operation": "GetStreamingDistribution", + "maxAttempts": 25, + "description": "Wait until a streaming distribution is deployed.", + "acceptors": [ + { + "expected": "Deployed", + "matcher": "path", + "state": "success", + "argument": "StreamingDistribution.Status" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2018-06-18/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2018-06-18/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2018-06-18/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2018-06-18/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2018-06-18/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..51fbb907fa38d6d868c935bc108f30bff305bc4a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2018-06-18/paginators-1.json @@ -0,0 +1,32 @@ +{ + "pagination": { + "ListCloudFrontOriginAccessIdentities": { + "input_token": "Marker", + "output_token": "CloudFrontOriginAccessIdentityList.NextMarker", + "limit_key": "MaxItems", + "more_results": "CloudFrontOriginAccessIdentityList.IsTruncated", + "result_key": "CloudFrontOriginAccessIdentityList.Items" + }, + "ListDistributions": { + "input_token": "Marker", + "output_token": "DistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "DistributionList.IsTruncated", + "result_key": "DistributionList.Items" + }, + "ListInvalidations": { + "input_token": "Marker", + "output_token": "InvalidationList.NextMarker", + "limit_key": "MaxItems", + "more_results": "InvalidationList.IsTruncated", + "result_key": "InvalidationList.Items" + }, + "ListStreamingDistributions": { + "input_token": "Marker", + "output_token": "StreamingDistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "StreamingDistributionList.IsTruncated", + "result_key": "StreamingDistributionList.Items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2018-06-18/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2018-06-18/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..edd74b2a3b4ac1a57179d068f0a33255c60e72d4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2018-06-18/waiters-2.json @@ -0,0 +1,47 @@ +{ + "version": 2, + "waiters": { + "DistributionDeployed": { + "delay": 60, + "operation": "GetDistribution", + "maxAttempts": 25, + "description": "Wait until a distribution is deployed.", + "acceptors": [ + { + "expected": "Deployed", + "matcher": "path", + "state": "success", + "argument": "Distribution.Status" + } + ] + }, + "InvalidationCompleted": { + "delay": 20, + "operation": "GetInvalidation", + "maxAttempts": 30, + "description": "Wait until an invalidation has completed.", + "acceptors": [ + { + "expected": "Completed", + "matcher": "path", + "state": "success", + "argument": "Invalidation.Status" + } + ] + }, + "StreamingDistributionDeployed": { + "delay": 60, + "operation": "GetStreamingDistribution", + "maxAttempts": 25, + "description": "Wait until a streaming distribution is deployed.", + "acceptors": [ + { + "expected": "Deployed", + "matcher": "path", + "state": "success", + "argument": "StreamingDistribution.Status" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2018-11-05/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2018-11-05/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2018-11-05/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2018-11-05/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2018-11-05/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..51fbb907fa38d6d868c935bc108f30bff305bc4a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2018-11-05/paginators-1.json @@ -0,0 +1,32 @@ +{ + "pagination": { + "ListCloudFrontOriginAccessIdentities": { + "input_token": "Marker", + "output_token": "CloudFrontOriginAccessIdentityList.NextMarker", + "limit_key": "MaxItems", + "more_results": "CloudFrontOriginAccessIdentityList.IsTruncated", + "result_key": "CloudFrontOriginAccessIdentityList.Items" + }, + "ListDistributions": { + "input_token": "Marker", + "output_token": "DistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "DistributionList.IsTruncated", + "result_key": "DistributionList.Items" + }, + "ListInvalidations": { + "input_token": "Marker", + "output_token": "InvalidationList.NextMarker", + "limit_key": "MaxItems", + "more_results": "InvalidationList.IsTruncated", + "result_key": "InvalidationList.Items" + }, + "ListStreamingDistributions": { + "input_token": "Marker", + "output_token": "StreamingDistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "StreamingDistributionList.IsTruncated", + "result_key": "StreamingDistributionList.Items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2019-03-26/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2019-03-26/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2019-03-26/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2019-03-26/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2019-03-26/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..51fbb907fa38d6d868c935bc108f30bff305bc4a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2019-03-26/paginators-1.json @@ -0,0 +1,32 @@ +{ + "pagination": { + "ListCloudFrontOriginAccessIdentities": { + "input_token": "Marker", + "output_token": "CloudFrontOriginAccessIdentityList.NextMarker", + "limit_key": "MaxItems", + "more_results": "CloudFrontOriginAccessIdentityList.IsTruncated", + "result_key": "CloudFrontOriginAccessIdentityList.Items" + }, + "ListDistributions": { + "input_token": "Marker", + "output_token": "DistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "DistributionList.IsTruncated", + "result_key": "DistributionList.Items" + }, + "ListInvalidations": { + "input_token": "Marker", + "output_token": "InvalidationList.NextMarker", + "limit_key": "MaxItems", + "more_results": "InvalidationList.IsTruncated", + "result_key": "InvalidationList.Items" + }, + "ListStreamingDistributions": { + "input_token": "Marker", + "output_token": "StreamingDistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "StreamingDistributionList.IsTruncated", + "result_key": "StreamingDistributionList.Items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2019-03-26/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2019-03-26/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..95f0a2dd4dc86c0a2452fce2ace365003abfdb27 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2019-03-26/waiters-2.json @@ -0,0 +1,47 @@ +{ + "version": 2, + "waiters": { + "DistributionDeployed": { + "delay": 60, + "operation": "GetDistribution", + "maxAttempts": 35, + "description": "Wait until a distribution is deployed.", + "acceptors": [ + { + "expected": "Deployed", + "matcher": "path", + "state": "success", + "argument": "Distribution.Status" + } + ] + }, + "InvalidationCompleted": { + "delay": 20, + "operation": "GetInvalidation", + "maxAttempts": 30, + "description": "Wait until an invalidation has completed.", + "acceptors": [ + { + "expected": "Completed", + "matcher": "path", + "state": "success", + "argument": "Invalidation.Status" + } + ] + }, + "StreamingDistributionDeployed": { + "delay": 60, + "operation": "GetStreamingDistribution", + "maxAttempts": 25, + "description": "Wait until a streaming distribution is deployed.", + "acceptors": [ + { + "expected": "Deployed", + "matcher": "path", + "state": "success", + "argument": "StreamingDistribution.Status" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2020-05-31/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2020-05-31/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2020-05-31/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2020-05-31/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2020-05-31/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..f956149a49752bb98800a22d5cdcb520e69c220b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2020-05-31/paginators-1.json @@ -0,0 +1,110 @@ +{ + "pagination": { + "ListCloudFrontOriginAccessIdentities": { + "input_token": "Marker", + "output_token": "CloudFrontOriginAccessIdentityList.NextMarker", + "limit_key": "MaxItems", + "more_results": "CloudFrontOriginAccessIdentityList.IsTruncated", + "result_key": "CloudFrontOriginAccessIdentityList.Items" + }, + "ListDistributions": { + "input_token": "Marker", + "output_token": "DistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "DistributionList.IsTruncated", + "result_key": "DistributionList.Items" + }, + "ListInvalidations": { + "input_token": "Marker", + "output_token": "InvalidationList.NextMarker", + "limit_key": "MaxItems", + "more_results": "InvalidationList.IsTruncated", + "result_key": "InvalidationList.Items" + }, + "ListStreamingDistributions": { + "input_token": "Marker", + "output_token": "StreamingDistributionList.NextMarker", + "limit_key": "MaxItems", + "more_results": "StreamingDistributionList.IsTruncated", + "result_key": "StreamingDistributionList.Items" + }, + "ListKeyValueStores": { + "input_token": "Marker", + "limit_key": "MaxItems", + "output_token": "KeyValueStoreList.NextMarker", + "result_key": "KeyValueStoreList.Items" + }, + "ListPublicKeys": { + "input_token": "Marker", + "output_token": "PublicKeyList.NextMarker", + "limit_key": "MaxItems", + "result_key": "PublicKeyList.Items" + }, + "ListConnectionGroups": { + "input_token": "Marker", + "output_token": "NextMarker", + "limit_key": "MaxItems", + "result_key": "ConnectionGroups" + }, + "ListDistributionTenants": { + "input_token": "Marker", + "output_token": "NextMarker", + "limit_key": "MaxItems", + "result_key": "DistributionTenantList" + }, + "ListDistributionTenantsByCustomization": { + "input_token": "Marker", + "output_token": "NextMarker", + "limit_key": "MaxItems", + "result_key": "DistributionTenantList" + }, + "ListDistributionsByConnectionMode": { + "input_token": "Marker", + "output_token": "DistributionList.NextMarker", + "limit_key": "MaxItems", + "result_key": "DistributionList.Items" + }, + "ListDomainConflicts": { + "input_token": "Marker", + "output_token": "NextMarker", + "limit_key": "MaxItems", + "result_key": "DomainConflicts" + }, + "ListInvalidationsForDistributionTenant": { + "input_token": "Marker", + "output_token": "InvalidationList.NextMarker", + "limit_key": "MaxItems", + "result_key": "InvalidationList.Items" + }, + "ListOriginAccessControls": { + "input_token": "Marker", + "output_token": "OriginAccessControlList.NextMarker", + "limit_key": "MaxItems", + "result_key": "OriginAccessControlList.Items" + }, + "ListConnectionFunctions": { + "input_token": "Marker", + "output_token": "NextMarker", + "limit_key": "MaxItems", + "result_key": "ConnectionFunctions" + }, + "ListDistributionsByConnectionFunction": { + "input_token": "Marker", + "output_token": "DistributionList.NextMarker", + "limit_key": "MaxItems", + "result_key": "DistributionList.Items" + }, + "ListDistributionsByTrustStore": { + "input_token": "Marker", + "output_token": "DistributionList.NextMarker", + "limit_key": "MaxItems", + "result_key": "DistributionList.Items" + }, + "ListTrustStores": { + "input_token": "Marker", + "output_token": "NextMarker", + "limit_key": "MaxItems", + "result_key": "TrustStoreList" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2020-05-31/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2020-05-31/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..1e2c625d81e63812781e38da0fe9f5f88d7274f4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudfront/2020-05-31/waiters-2.json @@ -0,0 +1,53 @@ +{ + "version" : 2, + "waiters" : { + "DistributionDeployed" : { + "description" : "Wait until a distribution is deployed.", + "delay" : 60, + "maxAttempts" : 35, + "operation" : "GetDistribution", + "acceptors" : [ { + "matcher" : "path", + "argument" : "Distribution.Status", + "state" : "success", + "expected" : "Deployed" + } ] + }, + "InvalidationCompleted" : { + "description" : "Wait until an invalidation has completed.", + "delay" : 20, + "maxAttempts" : 30, + "operation" : "GetInvalidation", + "acceptors" : [ { + "matcher" : "path", + "argument" : "Invalidation.Status", + "state" : "success", + "expected" : "Completed" + } ] + }, + "InvalidationForDistributionTenantCompleted" : { + "description" : "Wait until an invalidation for distribution tenant has completed.", + "delay" : 20, + "maxAttempts" : 30, + "operation" : "GetInvalidationForDistributionTenant", + "acceptors" : [ { + "matcher" : "path", + "argument" : "Invalidation.Status", + "state" : "success", + "expected" : "Completed" + } ] + }, + "StreamingDistributionDeployed" : { + "description" : "Wait until a streaming distribution is deployed.", + "delay" : 60, + "maxAttempts" : 25, + "operation" : "GetStreamingDistribution", + "acceptors" : [ { + "matcher" : "path", + "argument" : "StreamingDistribution.Status", + "state" : "success", + "expected" : "Deployed" + } ] + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudhsm/2014-05-30/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudhsm/2014-05-30/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudhsm/2014-05-30/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudhsm/2014-05-30/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudhsm/2014-05-30/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..3dedddf1179570563dbd379f0315413495508166 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudhsm/2014-05-30/paginators-1.json @@ -0,0 +1,19 @@ +{ + "pagination": { + "ListHapgs": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "HapgList" + }, + "ListHsms": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "HsmList" + }, + "ListLunaClients": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "ClientList" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudhsmv2/2017-04-28/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudhsmv2/2017-04-28/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudhsmv2/2017-04-28/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudhsmv2/2017-04-28/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudhsmv2/2017-04-28/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..19c403f0cac89f9a72c4bd121f20487ea434963c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudhsmv2/2017-04-28/paginators-1.json @@ -0,0 +1,22 @@ +{ + "pagination": { + "DescribeBackups": { + "result_key": "Backups", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "DescribeClusters": { + "result_key": "Clusters", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "ListTags": { + "result_key": "TagList", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudsearchdomain/2013-01-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudsearchdomain/2013-01-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudsearchdomain/2013-01-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudsearchdomain/2013-01-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudsearchdomain/2013-01-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudsearchdomain/2013-01-01/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudwatch/2010-08-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudwatch/2010-08-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudwatch/2010-08-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudwatch/2010-08-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudwatch/2010-08-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..b386c2f60b43c21be3746fe132435027bca00c62 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudwatch/2010-08-01/paginators-1.json @@ -0,0 +1,47 @@ +{ + "pagination": { + "DescribeAlarmHistory": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxRecords", + "result_key": "AlarmHistoryItems" + }, + "DescribeAlarms": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxRecords", + "result_key": [ + "MetricAlarms", + "CompositeAlarms" + ] + }, + "ListDashboards": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "DashboardEntries" + }, + "ListMetrics": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": [ + "Metrics", + "OwningAccounts" + ] + }, + "GetMetricData": { + "input_token": "NextToken", + "limit_key": "MaxDatapoints", + "output_token": "NextToken", + "result_key": [ + "MetricDataResults", + "Messages" + ] + }, + "DescribeAnomalyDetectors": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "AnomalyDetectors" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cloudwatch/2010-08-01/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/cloudwatch/2010-08-01/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..32803bba55eedaeb1f8998962dc7f42bdd8ced33 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cloudwatch/2010-08-01/waiters-2.json @@ -0,0 +1,31 @@ +{ + "version": 2, + "waiters": { + "AlarmExists": { + "delay": 5, + "maxAttempts": 40, + "operation": "DescribeAlarms", + "acceptors": [ + { + "matcher": "path", + "expected": true, + "argument": "length(MetricAlarms[]) > `0`", + "state": "success" + } + ] + }, + "CompositeAlarmExists": { + "delay": 5, + "maxAttempts": 40, + "operation": "DescribeAlarms", + "acceptors": [ + { + "matcher": "path", + "expected": true, + "argument": "length(CompositeAlarms[]) > `0`", + "state": "success" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/codecommit/2015-04-13/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/codecommit/2015-04-13/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/codecommit/2015-04-13/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/codecommit/2015-04-13/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/codecommit/2015-04-13/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..b3310fca982d7f77190523be03a4e3e1380c47e5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/codecommit/2015-04-13/paginators-1.json @@ -0,0 +1,44 @@ +{ + "pagination": { + "ListBranches": { + "input_token": "nextToken", + "output_token": "nextToken", + "result_key": "branches" + }, + "ListRepositories": { + "input_token": "nextToken", + "output_token": "nextToken", + "result_key": "repositories" + }, + "GetCommentsForComparedCommit": { + "result_key": "commentsForComparedCommitData", + "output_token": "nextToken", + "input_token": "nextToken", + "limit_key": "maxResults" + }, + "DescribePullRequestEvents": { + "result_key": "pullRequestEvents", + "output_token": "nextToken", + "input_token": "nextToken", + "limit_key": "maxResults" + }, + "GetCommentsForPullRequest": { + "result_key": "commentsForPullRequestData", + "output_token": "nextToken", + "input_token": "nextToken", + "limit_key": "maxResults" + }, + "ListPullRequests": { + "result_key": "pullRequestIds", + "output_token": "nextToken", + "input_token": "nextToken", + "limit_key": "maxResults" + }, + "GetDifferences": { + "result_key": "differences", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/codeguru-reviewer/2019-09-19/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/codeguru-reviewer/2019-09-19/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/codeguru-reviewer/2019-09-19/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/codeguru-reviewer/2019-09-19/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/codeguru-reviewer/2019-09-19/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..bbc1f584fdd7cffc09118fbbfb4bb43d8d541e24 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/codeguru-reviewer/2019-09-19/paginators-1.json @@ -0,0 +1,10 @@ +{ + "pagination": { + "ListRepositoryAssociations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "RepositoryAssociationSummaries" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/codeguru-reviewer/2019-09-19/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/codeguru-reviewer/2019-09-19/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..cd1730fabf15c7e9162227777f6d5dcf5c4e5548 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/codeguru-reviewer/2019-09-19/waiters-2.json @@ -0,0 +1,58 @@ +{ + "version": 2, + "waiters": + { + "RepositoryAssociationSucceeded": + { + "description": "Wait until a repository association is complete.", + "operation": "DescribeRepositoryAssociation", + "delay": 10, + "maxAttempts": 30, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "RepositoryAssociation.State", + "expected": "Associated" + }, + { + "state": "failure", + "matcher": "path", + "argument": "RepositoryAssociation.State", + "expected": "Failed" + }, + { + "state": "retry", + "matcher": "path", + "argument": "RepositoryAssociation.State", + "expected": "Associating" + }] + }, + "CodeReviewCompleted": + { + "description": "Wait until a code review is complete.", + "operation": "DescribeCodeReview", + "delay": 10, + "maxAttempts": 180, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "CodeReview.State", + "expected": "Completed" + }, + { + "state": "failure", + "matcher": "path", + "argument": "CodeReview.State", + "expected": "Failed" + }, + { + "state": "retry", + "matcher": "path", + "argument": "CodeReview.State", + "expected": "Pending" + }] + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/codepipeline/2015-07-09/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/codepipeline/2015-07-09/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/codepipeline/2015-07-09/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/codepipeline/2015-07-09/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/codepipeline/2015-07-09/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..32217ac901f3bd5731f8dba5d74e8c98a07c1b5e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/codepipeline/2015-07-09/paginators-1.json @@ -0,0 +1,51 @@ +{ + "pagination": { + "ListActionTypes": { + "input_token": "nextToken", + "output_token": "nextToken", + "result_key": "actionTypes" + }, + "ListPipelineExecutions": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "pipelineExecutionSummaries" + }, + "ListPipelines": { + "input_token": "nextToken", + "output_token": "nextToken", + "result_key": "pipelines", + "limit_key": "maxResults" + }, + "ListWebhooks": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "webhooks" + }, + "ListActionExecutions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "actionExecutionDetails" + }, + "ListTagsForResource": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "tags" + }, + "ListRuleExecutions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "ruleExecutionDetails" + }, + "ListDeployActionExecutionTargets": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "targets" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cognito-idp/2016-04-18/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cognito-idp/2016-04-18/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cognito-idp/2016-04-18/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/cognito-idp/2016-04-18/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/cognito-idp/2016-04-18/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..51b7c94d27b12bf5340960e2a695e3856c49a6db --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/cognito-idp/2016-04-18/paginators-1.json @@ -0,0 +1,58 @@ +{ + "pagination": { + "AdminListGroupsForUser": { + "input_token": "NextToken", + "limit_key": "Limit", + "output_token": "NextToken", + "result_key": "Groups" + }, + "AdminListUserAuthEvents": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "AuthEvents" + }, + "ListGroups": { + "input_token": "NextToken", + "limit_key": "Limit", + "output_token": "NextToken", + "result_key": "Groups" + }, + "ListIdentityProviders": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Providers" + }, + "ListResourceServers": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ResourceServers" + }, + "ListUserPoolClients": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "UserPoolClients" + }, + "ListUserPools": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "UserPools" + }, + "ListUsersInGroup": { + "input_token": "NextToken", + "limit_key": "Limit", + "output_token": "NextToken", + "result_key": "Users" + }, + "ListUsers": { + "input_token": "PaginationToken", + "limit_key": "Limit", + "output_token": "PaginationToken", + "result_key": "Users" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/comprehend/2017-11-27/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/comprehend/2017-11-27/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/comprehend/2017-11-27/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/comprehend/2017-11-27/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/comprehend/2017-11-27/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..3a458182911848bc92d89af9dd8f2ded64782283 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/comprehend/2017-11-27/paginators-1.json @@ -0,0 +1,64 @@ +{ + "pagination": { + "ListTopicsDetectionJobs": { + "result_key": "TopicsDetectionJobPropertiesList", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "ListDocumentClassificationJobs": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "DocumentClassificationJobPropertiesList" + }, + "ListDocumentClassifiers": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "DocumentClassifierPropertiesList" + }, + "ListDominantLanguageDetectionJobs": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "DominantLanguageDetectionJobPropertiesList" + }, + "ListEntitiesDetectionJobs": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "EntitiesDetectionJobPropertiesList" + }, + "ListEntityRecognizers": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "EntityRecognizerPropertiesList" + }, + "ListKeyPhrasesDetectionJobs": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "KeyPhrasesDetectionJobPropertiesList" + }, + "ListSentimentDetectionJobs": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "SentimentDetectionJobPropertiesList" + }, + "ListEndpoints": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "EndpointPropertiesList" + }, + "ListPiiEntitiesDetectionJobs": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "PiiEntitiesDetectionJobPropertiesList" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/compute-optimizer-automation/2025-09-22/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/compute-optimizer-automation/2025-09-22/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..93d118848bf73983f22806cb42be77677f3e7a76 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/compute-optimizer-automation/2025-09-22/paginators-1.json @@ -0,0 +1,58 @@ +{ + "pagination": { + "ListAccounts": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "accounts" + }, + "ListAutomationEventSteps": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "automationEventSteps" + }, + "ListAutomationEventSummaries": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "automationEventSummaries" + }, + "ListAutomationEvents": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "automationEvents" + }, + "ListAutomationRulePreview": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "previewResults" + }, + "ListAutomationRulePreviewSummaries": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "previewResultSummaries" + }, + "ListAutomationRules": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "automationRules" + }, + "ListRecommendedActionSummaries": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "recommendedActionSummaries" + }, + "ListRecommendedActions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "recommendedActions" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/compute-optimizer-automation/2025-09-22/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/compute-optimizer-automation/2025-09-22/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/compute-optimizer-automation/2025-09-22/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/connect-contact-lens/2020-08-21/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/connect-contact-lens/2020-08-21/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/connect-contact-lens/2020-08-21/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/connect-contact-lens/2020-08-21/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/connect-contact-lens/2020-08-21/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/connect-contact-lens/2020-08-21/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/connectcampaignsv2/2024-04-23/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/connectcampaignsv2/2024-04-23/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..c8396078e4be885ef3f835e5a989db7d81ece46b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/connectcampaignsv2/2024-04-23/paginators-1.json @@ -0,0 +1,16 @@ +{ + "pagination": { + "ListCampaigns": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "campaignSummaryList" + }, + "ListConnectInstanceIntegrations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "integrationSummaryList" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/controlcatalog/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/controlcatalog/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..2e3358d33a64fd8332b8f44e2016d9d64c63e011 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/controlcatalog/2018-05-10/paginators-1.json @@ -0,0 +1,34 @@ +{ + "pagination": { + "ListCommonControls": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "CommonControls" + }, + "ListDomains": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Domains" + }, + "ListObjectives": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Objectives" + }, + "ListControls": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Controls" + }, + "ListControlMappings": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ControlMappings" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/controlcatalog/2018-05-10/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/controlcatalog/2018-05-10/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/controlcatalog/2018-05-10/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/controltower/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/controltower/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..e34843be35efa9e79de9c8baa2ce8dccd3c02304 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/controltower/2018-05-10/paginators-1.json @@ -0,0 +1,40 @@ +{ + "pagination": { + "ListEnabledControls": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "enabledControls" + }, + "ListLandingZones": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "landingZones" + }, + "ListBaselines": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "baselines" + }, + "ListEnabledBaselines": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "enabledBaselines" + }, + "ListControlOperations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "controlOperations" + }, + "ListLandingZoneOperations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "landingZoneOperations" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/controltower/2018-05-10/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/controltower/2018-05-10/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/controltower/2018-05-10/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/customer-profiles/2020-08-15/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/customer-profiles/2020-08-15/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/customer-profiles/2020-08-15/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/customer-profiles/2020-08-15/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/customer-profiles/2020-08-15/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..38a591c536cdeb86e8b7688e05613900131c7c39 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/customer-profiles/2020-08-15/paginators-1.json @@ -0,0 +1,70 @@ +{ + "pagination": { + "ListEventStreams": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "GetSimilarProfiles": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ProfileIds" + }, + "ListObjectTypeAttributes": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListRuleBasedMatches": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "MatchIds" + }, + "ListSegmentDefinitions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListEventTriggers": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListDomainLayouts": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListUploadJobs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListDomainObjectTypes": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListRecommenderRecipes": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "RecommenderRecipes" + }, + "ListRecommenders": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Recommenders" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/customer-profiles/2020-08-15/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/customer-profiles/2020-08-15/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..15e5e3182516bfa2b378698845b09f4293a06f13 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/customer-profiles/2020-08-15/paginators-1.sdk-extras.json @@ -0,0 +1,15 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "GetSimilarProfiles": { + "non_aggregate_keys": [ + "MatchType", + "MatchId", + "RuleLevel", + "ConfidenceScore" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/databrew/2017-07-25/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/databrew/2017-07-25/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/databrew/2017-07-25/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/databrew/2017-07-25/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/databrew/2017-07-25/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..d18a749efa7e66732ebf557618f45c3357053faf --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/databrew/2017-07-25/paginators-1.json @@ -0,0 +1,52 @@ +{ + "pagination": { + "ListDatasets": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Datasets" + }, + "ListJobRuns": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "JobRuns" + }, + "ListJobs": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Jobs" + }, + "ListProjects": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Projects" + }, + "ListRecipeVersions": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Recipes" + }, + "ListRecipes": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Recipes" + }, + "ListSchedules": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Schedules" + }, + "ListRulesets": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Rulesets" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/dataexchange/2017-07-25/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/dataexchange/2017-07-25/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..cf704b02cc40b65c3366958a9d014fb21b7a66d2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/dataexchange/2017-07-25/paginators-1.json @@ -0,0 +1,46 @@ +{ + "pagination": { + "ListDataSetRevisions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Revisions" + }, + "ListDataSets": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "DataSets" + }, + "ListJobs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Jobs" + }, + "ListRevisionAssets": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Assets" + }, + "ListEventActions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "EventActions" + }, + "ListDataGrants": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "DataGrantSummaries" + }, + "ListReceivedDataGrants": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "DataGrantSummaries" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/dataexchange/2017-07-25/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/dataexchange/2017-07-25/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/dataexchange/2017-07-25/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/dax/2017-04-19/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/dax/2017-04-19/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/dax/2017-04-19/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/dax/2017-04-19/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/dax/2017-04-19/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..c13b2df9cb3be9bf5579246745f5737db4fed57b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/dax/2017-04-19/paginators-1.json @@ -0,0 +1,45 @@ +{ + "pagination": { + "DescribeClusters": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Clusters" + }, + "DescribeDefaultParameters": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Parameters" + }, + "DescribeEvents": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Events" + }, + "DescribeParameterGroups": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ParameterGroups" + }, + "DescribeParameters": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Parameters" + }, + "DescribeSubnetGroups": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "SubnetGroups" + }, + "ListTags": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Tags" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/deadline/2023-10-12/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/deadline/2023-10-12/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0a87c6895d7e72136b134f0dfda84beb1c58c618 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/deadline/2023-10-12/paginators-1.json @@ -0,0 +1,178 @@ +{ + "pagination": { + "GetSessionsStatisticsAggregation": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "statistics" + }, + "ListAvailableMeteredProducts": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "meteredProducts" + }, + "ListBudgets": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "budgets" + }, + "ListFarmMembers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "members" + }, + "ListFarms": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "farms" + }, + "ListFleetMembers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "members" + }, + "ListFleets": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "fleets" + }, + "ListJobMembers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "members" + }, + "ListJobs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "jobs" + }, + "ListLicenseEndpoints": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "licenseEndpoints" + }, + "ListMeteredProducts": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "meteredProducts" + }, + "ListMonitors": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "monitors" + }, + "ListQueueEnvironments": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "environments" + }, + "ListQueueFleetAssociations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "queueFleetAssociations" + }, + "ListQueueMembers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "members" + }, + "ListQueues": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "queues" + }, + "ListSessionActions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "sessionActions" + }, + "ListSessions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "sessions" + }, + "ListSessionsForWorker": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "sessions" + }, + "ListStepConsumers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "consumers" + }, + "ListStepDependencies": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "dependencies" + }, + "ListSteps": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "steps" + }, + "ListStorageProfiles": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "storageProfiles" + }, + "ListStorageProfilesForQueue": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "storageProfiles" + }, + "ListTasks": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "tasks" + }, + "ListWorkers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "workers" + }, + "ListJobParameterDefinitions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "jobParameterDefinitions" + }, + "ListLimits": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "limits" + }, + "ListQueueLimitAssociations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "queueLimitAssociations" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/deadline/2023-10-12/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/deadline/2023-10-12/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..27c22e79bf0d3c072bfca7c57bec5313a6e5ab25 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/deadline/2023-10-12/paginators-1.sdk-extras.json @@ -0,0 +1,13 @@ + { + "version": 1.0, + "merge": { + "pagination": { + "GetSessionsStatisticsAggregation": { + "non_aggregate_keys": [ + "status", + "statusMessage" + ] + } + } + } + } diff --git a/.venv/lib/python3.13/site-packages/botocore/data/deadline/2023-10-12/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/deadline/2023-10-12/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..eb6bcc6dfc6cf5ee7d73f70c0b72226031b06d35 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/deadline/2023-10-12/waiters-2.json @@ -0,0 +1,143 @@ +{ + "version" : 2, + "waiters" : { + "FleetActive" : { + "description" : "Wait until a Fleet is activated. Use this after invoking CreateFleet or UpdateFleet.", + "delay" : 5, + "maxAttempts" : 180, + "operation" : "GetFleet", + "acceptors" : [ { + "matcher" : "path", + "argument" : "status", + "state" : "success", + "expected" : "ACTIVE" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "CREATE_FAILED" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "UPDATE_FAILED" + } ] + }, + "JobCreateComplete" : { + "description" : "Wait until a Job is created. Use this after invoking CreateJob.", + "delay" : 1, + "maxAttempts" : 120, + "operation" : "GetJob", + "acceptors" : [ { + "matcher" : "path", + "argument" : "lifecycleStatus", + "state" : "success", + "expected" : "CREATE_COMPLETE" + }, { + "matcher" : "path", + "argument" : "lifecycleStatus", + "state" : "success", + "expected" : "UPDATE_IN_PROGRESS" + }, { + "matcher" : "path", + "argument" : "lifecycleStatus", + "state" : "success", + "expected" : "UPDATE_FAILED" + }, { + "matcher" : "path", + "argument" : "lifecycleStatus", + "state" : "success", + "expected" : "UPDATE_SUCCEEDED" + }, { + "matcher" : "path", + "argument" : "lifecycleStatus", + "state" : "failure", + "expected" : "UPLOAD_FAILED" + }, { + "matcher" : "path", + "argument" : "lifecycleStatus", + "state" : "failure", + "expected" : "CREATE_FAILED" + } ] + }, + "LicenseEndpointDeleted" : { + "description" : "Wait until a LicenseEndpoint is Deleted. Use this after invoking DeleteLicenseEndpoint.", + "delay" : 10, + "maxAttempts" : 234, + "operation" : "GetLicenseEndpoint", + "acceptors" : [ { + "matcher" : "error", + "state" : "success", + "expected" : "ResourceNotFoundException" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "NOT_READY" + } ] + }, + "LicenseEndpointValid" : { + "description" : "Wait until a LicenseEndpoint is Ready. Use this after invoking CreateLicenseEndpoint.", + "delay" : 10, + "maxAttempts" : 114, + "operation" : "GetLicenseEndpoint", + "acceptors" : [ { + "matcher" : "path", + "argument" : "status", + "state" : "success", + "expected" : "READY" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "NOT_READY" + } ] + }, + "QueueFleetAssociationStopped" : { + "description" : "Wait until a QueueFleetAssociation is stopped. Use this after setting the status to STOP_SCHEDULING_AND_COMPLETE_TASKS or STOP_SCHEDULING_AND_CANCEL_TASKS to wait for a QueueFleetAssociation to reach STOPPED", + "delay" : 10, + "maxAttempts" : 60, + "operation" : "GetQueueFleetAssociation", + "acceptors" : [ { + "matcher" : "path", + "argument" : "status", + "state" : "success", + "expected" : "STOPPED" + } ] + }, + "QueueLimitAssociationStopped" : { + "description" : "Wait until a QueueLimitAssociation is stopped. Use this after setting the status to STOP_LIMIT_USAGE_AND_COMPLETE_TASKS or STOP_LIMIT_USAGE_AND_CANCEL_TASKS to wait for a QueueLimitAssociation to reach STOPPED", + "delay" : 10, + "maxAttempts" : 60, + "operation" : "GetQueueLimitAssociation", + "acceptors" : [ { + "matcher" : "path", + "argument" : "status", + "state" : "success", + "expected" : "STOPPED" + } ] + }, + "QueueScheduling" : { + "delay" : 10, + "maxAttempts" : 70, + "operation" : "GetQueue", + "acceptors" : [ { + "matcher" : "path", + "argument" : "status", + "state" : "success", + "expected" : "SCHEDULING" + } ] + }, + "QueueSchedulingBlocked" : { + "delay" : 10, + "maxAttempts" : 30, + "operation" : "GetQueue", + "acceptors" : [ { + "matcher" : "path", + "argument" : "status", + "state" : "success", + "expected" : "SCHEDULING_BLOCKED" + } ] + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/detective/2018-10-26/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/detective/2018-10-26/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/detective/2018-10-26/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/detective/2018-10-26/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/detective/2018-10-26/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/detective/2018-10-26/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/devops-guru/2020-12-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/devops-guru/2020-12-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/devops-guru/2020-12-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/devops-guru/2020-12-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/devops-guru/2020-12-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..d0d5871792838a271d466cbb9a7023ea6626c81c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/devops-guru/2020-12-01/paginators-1.json @@ -0,0 +1,125 @@ +{ + "pagination": { + "DescribeResourceCollectionHealth": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": [ + "CloudFormation", + "Service", + "Tags" + ] + }, + "GetResourceCollection": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": [ + "ResourceCollection.CloudFormation.StackNames", + "ResourceCollection.Tags" + ], + "non_aggregate_keys": [ + "ResourceCollection" + ] + }, + "ListAnomaliesForInsight": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": [ + "ReactiveAnomalies", + "ProactiveAnomalies" + ] + }, + "ListEvents": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Events" + }, + "ListInsights": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": [ + "ProactiveInsights", + "ReactiveInsights" + ] + }, + "ListNotificationChannels": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Channels" + }, + "ListRecommendations": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Recommendations" + }, + "SearchInsights": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": [ + "ProactiveInsights", + "ReactiveInsights" + ] + }, + "GetCostEstimation": { + "input_token": "NextToken", + "non_aggregate_keys": [ + "Status", + "TotalCost", + "TimeRange", + "ResourceCollection" + ], + "output_token": "NextToken", + "result_key": [ + "Costs" + ] + }, + "DescribeOrganizationResourceCollectionHealth": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": [ + "CloudFormation", + "Account", + "Service", + "Tags" + ] + }, + "ListOrganizationInsights": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": [ + "ProactiveInsights", + "ReactiveInsights" + ] + }, + "SearchOrganizationInsights": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": [ + "ProactiveInsights", + "ReactiveInsights" + ] + }, + "ListAnomalousLogGroups": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": [ + "InsightId", + "AnomalousLogGroups" + ] + }, + "ListMonitoredResources": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": [ + "MonitoredResourceIdentifiers" + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/directconnect/2012-10-25/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/directconnect/2012-10-25/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/directconnect/2012-10-25/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/directconnect/2012-10-25/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/directconnect/2012-10-25/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..dbca668f8b58885a18a431be621926aa943d0cd1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/directconnect/2012-10-25/paginators-1.json @@ -0,0 +1,22 @@ +{ + "pagination": { + "DescribeDirectConnectGatewayAssociations": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "directConnectGatewayAssociations" + }, + "DescribeDirectConnectGatewayAttachments": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "directConnectGatewayAttachments" + }, + "DescribeDirectConnectGateways": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "directConnectGateways" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/dlm/2018-01-12/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/dlm/2018-01-12/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/dlm/2018-01-12/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/dlm/2018-01-12/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/dlm/2018-01-12/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/dlm/2018-01-12/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/dms/2016-01-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/dms/2016-01-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..f9e8c4e5dcb68239e4305e0eac5762696bfede7d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/dms/2016-01-01/examples-1.json @@ -0,0 +1,1074 @@ +{ + "version": "1.0", + "examples": { + "AddTagsToResource": [ + { + "input": { + "ResourceArn": "arn:aws:dms:us-east-1:123456789012:endpoint:ASXWXJZLNWNT5HTWCGV2BUJQ7E", + "Tags": [ + { + "Key": "Acount", + "Value": "1633456" + } + ] + }, + "output": { + }, + "comments": { + "input": { + "ResourceArn": "Required. Use the ARN of the resource you want to tag.", + "Tags": "Required. Use the Key/Value pair format." + }, + "output": { + } + }, + "description": "Adds metadata tags to an AWS DMS resource, including replication instance, endpoint, security group, and migration task. These tags can also be used with cost allocation reporting to track cost associated with AWS DMS resources, or used in a Condition statement in an IAM policy for AWS DMS.", + "id": "add-tags-to-resource-1481744141435", + "title": "Add tags to resource" + } + ], + "CreateEndpoint": [ + { + "input": { + "CertificateArn": "", + "DatabaseName": "testdb", + "EndpointIdentifier": "test-endpoint-1", + "EndpointType": "source", + "EngineName": "mysql", + "ExtraConnectionAttributes": "", + "KmsKeyId": "arn:aws:kms:us-east-1:123456789012:key/4c1731d6-5435-ed4d-be13-d53411a7cfbd", + "Password": "pasword", + "Port": 3306, + "ServerName": "mydb.cx1llnox7iyx.us-west-2.rds.amazonaws.com", + "SslMode": "require", + "Tags": [ + { + "Key": "Acount", + "Value": "143327655" + } + ], + "Username": "username" + }, + "output": { + "Endpoint": { + "EndpointArn": "arn:aws:dms:us-east-1:123456789012:endpoint:RAAR3R22XSH46S3PWLC3NJAWKM", + "EndpointIdentifier": "test-endpoint-1", + "EndpointType": "source", + "EngineName": "mysql", + "KmsKeyId": "arn:aws:kms:us-east-1:123456789012:key/4c1731d6-5435-ed4d-be13-d53411a7cfbd", + "Port": 3306, + "ServerName": "mydb.cx1llnox7iyx.us-west-2.rds.amazonaws.com", + "Status": "active", + "Username": "username" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Creates an endpoint using the provided settings.", + "id": "create-endpoint-1481746254348", + "title": "Create endpoint" + } + ], + "CreateReplicationInstance": [ + { + "input": { + "AllocatedStorage": 123, + "AutoMinorVersionUpgrade": true, + "AvailabilityZone": "", + "EngineVersion": "", + "KmsKeyId": "", + "MultiAZ": true, + "PreferredMaintenanceWindow": "", + "PubliclyAccessible": true, + "ReplicationInstanceClass": "", + "ReplicationInstanceIdentifier": "", + "ReplicationSubnetGroupIdentifier": "", + "Tags": [ + { + "Key": "string", + "Value": "string" + } + ], + "VpcSecurityGroupIds": [ + + ] + }, + "output": { + "ReplicationInstance": { + "AllocatedStorage": 5, + "AutoMinorVersionUpgrade": true, + "EngineVersion": "1.5.0", + "KmsKeyId": "arn:aws:kms:us-east-1:123456789012:key/4c1731d6-5435-ed4d-be13-d53411a7cfbd", + "PendingModifiedValues": { + }, + "PreferredMaintenanceWindow": "sun:06:00-sun:14:00", + "PubliclyAccessible": true, + "ReplicationInstanceArn": "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", + "ReplicationInstanceClass": "dms.t2.micro", + "ReplicationInstanceIdentifier": "test-rep-1", + "ReplicationInstanceStatus": "creating", + "ReplicationSubnetGroup": { + "ReplicationSubnetGroupDescription": "default", + "ReplicationSubnetGroupIdentifier": "default", + "SubnetGroupStatus": "Complete", + "Subnets": [ + { + "SubnetAvailabilityZone": { + "Name": "us-east-1d" + }, + "SubnetIdentifier": "subnet-f6dd91af", + "SubnetStatus": "Active" + }, + { + "SubnetAvailabilityZone": { + "Name": "us-east-1b" + }, + "SubnetIdentifier": "subnet-3605751d", + "SubnetStatus": "Active" + }, + { + "SubnetAvailabilityZone": { + "Name": "us-east-1c" + }, + "SubnetIdentifier": "subnet-c2daefb5", + "SubnetStatus": "Active" + }, + { + "SubnetAvailabilityZone": { + "Name": "us-east-1e" + }, + "SubnetIdentifier": "subnet-85e90cb8", + "SubnetStatus": "Active" + } + ], + "VpcId": "vpc-6741a603" + } + } + }, + "comments": { + "output": { + } + }, + "description": "Creates the replication instance using the specified parameters.", + "id": "create-replication-instance-1481746705295", + "title": "Create replication instance" + } + ], + "CreateReplicationSubnetGroup": [ + { + "input": { + "ReplicationSubnetGroupDescription": "US West subnet group", + "ReplicationSubnetGroupIdentifier": "us-west-2ab-vpc-215ds366", + "SubnetIds": [ + "subnet-e145356n", + "subnet-58f79200" + ], + "Tags": [ + { + "Key": "Acount", + "Value": "145235" + } + ] + }, + "output": { + "ReplicationSubnetGroup": { + } + }, + "comments": { + "output": { + } + }, + "description": "Creates a replication subnet group given a list of the subnet IDs in a VPC.", + "id": "create-replication-subnet-group-1481747297930", + "title": "Create replication subnet group" + } + ], + "CreateReplicationTask": [ + { + "input": { + "CdcStartTime": "2016-12-14T18:25:43Z", + "MigrationType": "full-load", + "ReplicationInstanceArn": "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", + "ReplicationTaskIdentifier": "task1", + "ReplicationTaskSettings": "", + "SourceEndpointArn": "arn:aws:dms:us-east-1:123456789012:endpoint:ZW5UAN6P4E77EC7YWHK4RZZ3BE", + "TableMappings": "file://mappingfile.json", + "Tags": [ + { + "Key": "Acount", + "Value": "24352226" + } + ], + "TargetEndpointArn": "arn:aws:dms:us-east-1:123456789012:endpoint:ASXWXJZLNWNT5HTWCGV2BUJQ7E" + }, + "output": { + "ReplicationTask": { + "MigrationType": "full-load", + "ReplicationInstanceArn": "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", + "ReplicationTaskArn": "arn:aws:dms:us-east-1:123456789012:task:OEAMB3NXSTZ6LFYZFEPPBBXPYM", + "ReplicationTaskCreationDate": "2016-12-14T18:25:43Z", + "ReplicationTaskIdentifier": "task1", + "ReplicationTaskSettings": "{\"TargetMetadata\":{\"TargetSchema\":\"\",\"SupportLobs\":true,\"FullLobMode\":true,\"LobChunkSize\":64,\"LimitedSizeLobMode\":false,\"LobMaxSize\":0},\"FullLoadSettings\":{\"FullLoadEnabled\":true,\"ApplyChangesEnabled\":false,\"TargetTablePrepMode\":\"DROP_AND_CREATE\",\"CreatePkAfterFullLoad\":false,\"StopTaskCachedChangesApplied\":false,\"StopTaskCachedChangesNotApplied\":false,\"ResumeEnabled\":false,\"ResumeMinTableSize\":100000,\"ResumeOnlyClusteredPKTables\":true,\"MaxFullLoadSubTasks\":8,\"TransactionConsistencyTimeout\":600,\"CommitRate\":10000},\"Logging\":{\"EnableLogging\":false}}", + "SourceEndpointArn": "arn:aws:dms:us-east-1:123456789012:endpoint:ZW5UAN6P4E77EC7YWHK4RZZ3BE", + "Status": "creating", + "TableMappings": "file://mappingfile.json", + "TargetEndpointArn": "arn:aws:dms:us-east-1:123456789012:endpoint:ASXWXJZLNWNT5HTWCGV2BUJQ7E" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Creates a replication task using the specified parameters.", + "id": "create-replication-task-1481747646288", + "title": "Create replication task" + } + ], + "DeleteCertificate": [ + { + "input": { + "CertificateArn": "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUSM457DE6XFJCJQ" + }, + "output": { + "Certificate": { + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Deletes the specified certificate.", + "id": "delete-certificate-1481751957981", + "title": "Delete Certificate" + } + ], + "DeleteConnection": [ + { + "input": { + "EndpointArn": "arn:aws:dms:us-east-1:123456789012:endpoint:RAAR3R22XSH46S3PWLC3NJAWKM", + "ReplicationInstanceArn": "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ" + }, + "output": { + "Connection": { + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Deletes the connection between the replication instance and the endpoint.", + "id": "delete-connection-1481751957981", + "title": "Delete Connection" + } + ], + "DeleteEndpoint": [ + { + "input": { + "EndpointArn": "arn:aws:dms:us-east-1:123456789012:endpoint:RAAR3R22XSH46S3PWLC3NJAWKM" + }, + "output": { + "Endpoint": { + "EndpointArn": "arn:aws:dms:us-east-1:123456789012:endpoint:RAAR3R22XSH46S3PWLC3NJAWKM", + "EndpointIdentifier": "test-endpoint-1", + "EndpointType": "source", + "EngineName": "mysql", + "KmsKeyId": "arn:aws:kms:us-east-1:123456789012:key/4c1731d6-5435-ed4d-be13-d53411a7cfbd", + "Port": 3306, + "ServerName": "mydb.cx1llnox7iyx.us-west-2.rds.amazonaws.com", + "Status": "active", + "Username": "username" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Deletes the specified endpoint. All tasks associated with the endpoint must be deleted before you can delete the endpoint.\n", + "id": "delete-endpoint-1481752425530", + "title": "Delete Endpoint" + } + ], + "DeleteReplicationInstance": [ + { + "input": { + "ReplicationInstanceArn": "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ" + }, + "output": { + "ReplicationInstance": { + "AllocatedStorage": 5, + "AutoMinorVersionUpgrade": true, + "EngineVersion": "1.5.0", + "KmsKeyId": "arn:aws:kms:us-east-1:123456789012:key/4c1731d6-5435-ed4d-be13-d53411a7cfbd", + "PendingModifiedValues": { + }, + "PreferredMaintenanceWindow": "sun:06:00-sun:14:00", + "PubliclyAccessible": true, + "ReplicationInstanceArn": "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", + "ReplicationInstanceClass": "dms.t2.micro", + "ReplicationInstanceIdentifier": "test-rep-1", + "ReplicationInstanceStatus": "creating", + "ReplicationSubnetGroup": { + "ReplicationSubnetGroupDescription": "default", + "ReplicationSubnetGroupIdentifier": "default", + "SubnetGroupStatus": "Complete", + "Subnets": [ + { + "SubnetAvailabilityZone": { + "Name": "us-east-1d" + }, + "SubnetIdentifier": "subnet-f6dd91af", + "SubnetStatus": "Active" + }, + { + "SubnetAvailabilityZone": { + "Name": "us-east-1b" + }, + "SubnetIdentifier": "subnet-3605751d", + "SubnetStatus": "Active" + }, + { + "SubnetAvailabilityZone": { + "Name": "us-east-1c" + }, + "SubnetIdentifier": "subnet-c2daefb5", + "SubnetStatus": "Active" + }, + { + "SubnetAvailabilityZone": { + "Name": "us-east-1e" + }, + "SubnetIdentifier": "subnet-85e90cb8", + "SubnetStatus": "Active" + } + ], + "VpcId": "vpc-6741a603" + } + } + }, + "comments": { + "output": { + } + }, + "description": "Deletes the specified replication instance. You must delete any migration tasks that are associated with the replication instance before you can delete it.\n\n", + "id": "delete-replication-instance-1481752552839", + "title": "Delete Replication Instance" + } + ], + "DeleteReplicationSubnetGroup": [ + { + "input": { + "ReplicationSubnetGroupIdentifier": "us-west-2ab-vpc-215ds366" + }, + "output": { + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Deletes a replication subnet group.", + "id": "delete-replication-subnet-group-1481752728597", + "title": "Delete Replication Subnet Group" + } + ], + "DeleteReplicationTask": [ + { + "input": { + "ReplicationTaskArn": "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ" + }, + "output": { + "ReplicationTask": { + "MigrationType": "full-load", + "ReplicationInstanceArn": "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", + "ReplicationTaskArn": "arn:aws:dms:us-east-1:123456789012:task:OEAMB3NXSTZ6LFYZFEPPBBXPYM", + "ReplicationTaskCreationDate": "2016-12-14T18:25:43Z", + "ReplicationTaskIdentifier": "task1", + "ReplicationTaskSettings": "{\"TargetMetadata\":{\"TargetSchema\":\"\",\"SupportLobs\":true,\"FullLobMode\":true,\"LobChunkSize\":64,\"LimitedSizeLobMode\":false,\"LobMaxSize\":0},\"FullLoadSettings\":{\"FullLoadEnabled\":true,\"ApplyChangesEnabled\":false,\"TargetTablePrepMode\":\"DROP_AND_CREATE\",\"CreatePkAfterFullLoad\":false,\"StopTaskCachedChangesApplied\":false,\"StopTaskCachedChangesNotApplied\":false,\"ResumeEnabled\":false,\"ResumeMinTableSize\":100000,\"ResumeOnlyClusteredPKTables\":true,\"MaxFullLoadSubTasks\":8,\"TransactionConsistencyTimeout\":600,\"CommitRate\":10000},\"Logging\":{\"EnableLogging\":false}}", + "SourceEndpointArn": "arn:aws:dms:us-east-1:123456789012:endpoint:ZW5UAN6P4E77EC7YWHK4RZZ3BE", + "Status": "creating", + "TableMappings": "file://mappingfile.json", + "TargetEndpointArn": "arn:aws:dms:us-east-1:123456789012:endpoint:ASXWXJZLNWNT5HTWCGV2BUJQ7E" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Deletes the specified replication task.", + "id": "delete-replication-task-1481752903506", + "title": "Delete Replication Task" + } + ], + "DescribeAccountAttributes": [ + { + "input": { + }, + "output": { + "AccountQuotas": [ + { + "AccountQuotaName": "ReplicationInstances", + "Max": 20, + "Used": 0 + }, + { + "AccountQuotaName": "AllocatedStorage", + "Max": 20, + "Used": 0 + }, + { + "AccountQuotaName": "Endpoints", + "Max": 20, + "Used": 0 + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Lists all of the AWS DMS attributes for a customer account. The attributes include AWS DMS quotas for the account, such as the number of replication instances allowed. The description for a quota includes the quota name, current usage toward that quota, and the quota's maximum value. This operation does not take any parameters.", + "id": "describe-acount-attributes-1481753085663", + "title": "Describe acount attributes" + } + ], + "DescribeCertificates": [ + { + "input": { + "Filters": [ + { + "Name": "string", + "Values": [ + "string", + "string" + ] + } + ], + "Marker": "", + "MaxRecords": 123 + }, + "output": { + "Certificates": [ + + ], + "Marker": "" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Provides a description of the certificate.", + "id": "describe-certificates-1481753186244", + "title": "Describe certificates" + } + ], + "DescribeConnections": [ + { + "input": { + "Filters": [ + { + "Name": "string", + "Values": [ + "string", + "string" + ] + } + ], + "Marker": "", + "MaxRecords": 123 + }, + "output": { + "Connections": [ + { + "EndpointArn": "arn:aws:dms:us-east-arn:aws:dms:us-east-1:123456789012:endpoint:ZW5UAN6P4E77EC7YWHK4RZZ3BE", + "EndpointIdentifier": "testsrc1", + "ReplicationInstanceArn": "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", + "ReplicationInstanceIdentifier": "test", + "Status": "successful" + } + ], + "Marker": "" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Describes the status of the connections that have been made between the replication instance and an endpoint. Connections are created when you test an endpoint.", + "id": "describe-connections-1481754477953", + "title": "Describe connections" + } + ], + "DescribeEndpointTypes": [ + { + "input": { + "Filters": [ + { + "Name": "string", + "Values": [ + "string", + "string" + ] + } + ], + "Marker": "", + "MaxRecords": 123 + }, + "output": { + "Marker": "", + "SupportedEndpointTypes": [ + + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns information about the type of endpoints available.", + "id": "describe-endpoint-types-1481754742591", + "title": "Describe endpoint types" + } + ], + "DescribeEndpoints": [ + { + "input": { + "Filters": [ + { + "Name": "string", + "Values": [ + "string", + "string" + ] + } + ], + "Marker": "", + "MaxRecords": 123 + }, + "output": { + "Endpoints": [ + + ], + "Marker": "" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns information about the endpoints for your account in the current region.", + "id": "describe-endpoints-1481754926060", + "title": "Describe endpoints" + } + ], + "DescribeOrderableReplicationInstances": [ + { + "input": { + "Marker": "", + "MaxRecords": 123 + }, + "output": { + "Marker": "", + "OrderableReplicationInstances": [ + + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns information about the replication instance types that can be created in the specified region.", + "id": "describe-orderable-replication-instances-1481755123669", + "title": "Describe orderable replication instances" + } + ], + "DescribeRefreshSchemasStatus": [ + { + "input": { + "EndpointArn": "" + }, + "output": { + "RefreshSchemasStatus": { + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns the status of the refresh-schemas operation.", + "id": "describe-refresh-schema-status-1481755303497", + "title": "Describe refresh schema status" + } + ], + "DescribeReplicationInstances": [ + { + "input": { + "Filters": [ + { + "Name": "string", + "Values": [ + "string", + "string" + ] + } + ], + "Marker": "", + "MaxRecords": 123 + }, + "output": { + "Marker": "", + "ReplicationInstances": [ + + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns the status of the refresh-schemas operation.", + "id": "describe-replication-instances-1481755443952", + "title": "Describe replication instances" + } + ], + "DescribeReplicationSubnetGroups": [ + { + "input": { + "Filters": [ + { + "Name": "string", + "Values": [ + "string", + "string" + ] + } + ], + "Marker": "", + "MaxRecords": 123 + }, + "output": { + "Marker": "", + "ReplicationSubnetGroups": [ + + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns information about the replication subnet groups.", + "id": "describe-replication-subnet-groups-1481755621284", + "title": "Describe replication subnet groups" + } + ], + "DescribeReplicationTasks": [ + { + "input": { + "Filters": [ + { + "Name": "string", + "Values": [ + "string", + "string" + ] + } + ], + "Marker": "", + "MaxRecords": 123 + }, + "output": { + "Marker": "", + "ReplicationTasks": [ + + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns information about replication tasks for your account in the current region.", + "id": "describe-replication-tasks-1481755777563", + "title": "Describe replication tasks" + } + ], + "DescribeSchemas": [ + { + "input": { + "EndpointArn": "", + "Marker": "", + "MaxRecords": 123 + }, + "output": { + "Marker": "", + "Schemas": [ + + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns information about the schema for the specified endpoint.", + "id": "describe-schemas-1481755933924", + "title": "Describe schemas" + } + ], + "DescribeTableStatistics": [ + { + "input": { + "Marker": "", + "MaxRecords": 123, + "ReplicationTaskArn": "" + }, + "output": { + "Marker": "", + "ReplicationTaskArn": "", + "TableStatistics": [ + + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns table statistics on the database migration task, including table name, rows inserted, rows updated, and rows deleted.", + "id": "describe-table-statistics-1481756071890", + "title": "Describe table statistics" + } + ], + "ImportCertificate": [ + { + "input": { + "CertificateIdentifier": "", + "CertificatePem": "" + }, + "output": { + "Certificate": { + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Uploads the specified certificate.", + "id": "import-certificate-1481756197206", + "title": "Import certificate" + } + ], + "ListTagsForResource": [ + { + "input": { + "ResourceArn": "" + }, + "output": { + "TagList": [ + + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Lists all tags for an AWS DMS resource.", + "id": "list-tags-for-resource-1481761095501", + "title": "List tags for resource" + } + ], + "ModifyEndpoint": [ + { + "input": { + "CertificateArn": "", + "DatabaseName": "", + "EndpointArn": "", + "EndpointIdentifier": "", + "EndpointType": "source", + "EngineName": "", + "ExtraConnectionAttributes": "", + "Password": "", + "Port": 123, + "ServerName": "", + "SslMode": "require", + "Username": "" + }, + "output": { + "Endpoint": { + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Modifies the specified endpoint.", + "id": "modify-endpoint-1481761649937", + "title": "Modify endpoint" + } + ], + "ModifyReplicationInstance": [ + { + "input": { + "AllocatedStorage": 123, + "AllowMajorVersionUpgrade": true, + "ApplyImmediately": true, + "AutoMinorVersionUpgrade": true, + "EngineVersion": "1.5.0", + "MultiAZ": true, + "PreferredMaintenanceWindow": "sun:06:00-sun:14:00", + "ReplicationInstanceArn": "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", + "ReplicationInstanceClass": "dms.t2.micro", + "ReplicationInstanceIdentifier": "test-rep-1", + "VpcSecurityGroupIds": [ + + ] + }, + "output": { + "ReplicationInstance": { + "AllocatedStorage": 5, + "AutoMinorVersionUpgrade": true, + "EngineVersion": "1.5.0", + "KmsKeyId": "arn:aws:kms:us-east-1:123456789012:key/4c1731d6-5435-ed4d-be13-d53411a7cfbd", + "PendingModifiedValues": { + }, + "PreferredMaintenanceWindow": "sun:06:00-sun:14:00", + "PubliclyAccessible": true, + "ReplicationInstanceArn": "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", + "ReplicationInstanceClass": "dms.t2.micro", + "ReplicationInstanceIdentifier": "test-rep-1", + "ReplicationInstanceStatus": "available", + "ReplicationSubnetGroup": { + "ReplicationSubnetGroupDescription": "default", + "ReplicationSubnetGroupIdentifier": "default", + "SubnetGroupStatus": "Complete", + "Subnets": [ + { + "SubnetAvailabilityZone": { + "Name": "us-east-1d" + }, + "SubnetIdentifier": "subnet-f6dd91af", + "SubnetStatus": "Active" + }, + { + "SubnetAvailabilityZone": { + "Name": "us-east-1b" + }, + "SubnetIdentifier": "subnet-3605751d", + "SubnetStatus": "Active" + }, + { + "SubnetAvailabilityZone": { + "Name": "us-east-1c" + }, + "SubnetIdentifier": "subnet-c2daefb5", + "SubnetStatus": "Active" + }, + { + "SubnetAvailabilityZone": { + "Name": "us-east-1e" + }, + "SubnetIdentifier": "subnet-85e90cb8", + "SubnetStatus": "Active" + } + ], + "VpcId": "vpc-6741a603" + } + } + }, + "comments": { + "output": { + } + }, + "description": "Modifies the replication instance to apply new settings. You can change one or more parameters by specifying these parameters and the new values in the request. Some settings are applied during the maintenance window.", + "id": "modify-replication-instance-1481761784746", + "title": "Modify replication instance" + } + ], + "ModifyReplicationSubnetGroup": [ + { + "input": { + "ReplicationSubnetGroupDescription": "", + "ReplicationSubnetGroupIdentifier": "", + "SubnetIds": [ + + ] + }, + "output": { + "ReplicationSubnetGroup": { + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Modifies the settings for the specified replication subnet group.", + "id": "modify-replication-subnet-group-1481762275392", + "title": "Modify replication subnet group" + } + ], + "RefreshSchemas": [ + { + "input": { + "EndpointArn": "", + "ReplicationInstanceArn": "" + }, + "output": { + "RefreshSchemasStatus": { + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Populates the schema for the specified endpoint. This is an asynchronous operation and can take several minutes. You can check the status of this operation by calling the describe-refresh-schemas-status operation.", + "id": "refresh-schema-1481762399111", + "title": "Refresh schema" + } + ], + "RemoveTagsFromResource": [ + { + "input": { + "ResourceArn": "arn:aws:dms:us-east-1:123456789012:endpoint:ASXWXJZLNWNT5HTWCGV2BUJQ7E", + "TagKeys": [ + + ] + }, + "output": { + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Removes metadata tags from an AWS DMS resource.", + "id": "remove-tags-from-resource-1481762571330", + "title": "Remove tags from resource" + } + ], + "StartReplicationTask": [ + { + "input": { + "CdcStartTime": "2016-12-14T13:33:20Z", + "ReplicationTaskArn": "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", + "StartReplicationTaskType": "start-replication" + }, + "output": { + "ReplicationTask": { + "MigrationType": "full-load", + "ReplicationInstanceArn": "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", + "ReplicationTaskArn": "arn:aws:dms:us-east-1:123456789012:task:OEAMB3NXSTZ6LFYZFEPPBBXPYM", + "ReplicationTaskCreationDate": "2016-12-14T18:25:43Z", + "ReplicationTaskIdentifier": "task1", + "ReplicationTaskSettings": "{\"TargetMetadata\":{\"TargetSchema\":\"\",\"SupportLobs\":true,\"FullLobMode\":true,\"LobChunkSize\":64,\"LimitedSizeLobMode\":false,\"LobMaxSize\":0},\"FullLoadSettings\":{\"FullLoadEnabled\":true,\"ApplyChangesEnabled\":false,\"TargetTablePrepMode\":\"DROP_AND_CREATE\",\"CreatePkAfterFullLoad\":false,\"StopTaskCachedChangesApplied\":false,\"StopTaskCachedChangesNotApplied\":false,\"ResumeEnabled\":false,\"ResumeMinTableSize\":100000,\"ResumeOnlyClusteredPKTables\":true,\"MaxFullLoadSubTasks\":8,\"TransactionConsistencyTimeout\":600,\"CommitRate\":10000},\"Logging\":{\"EnableLogging\":false}}", + "SourceEndpointArn": "arn:aws:dms:us-east-1:123456789012:endpoint:ZW5UAN6P4E77EC7YWHK4RZZ3BE", + "Status": "creating", + "TableMappings": "file://mappingfile.json", + "TargetEndpointArn": "arn:aws:dms:us-east-1:123456789012:endpoint:ASXWXJZLNWNT5HTWCGV2BUJQ7E" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Starts the replication task.", + "id": "start-replication-task-1481762706778", + "title": "Start replication task" + } + ], + "StopReplicationTask": [ + { + "input": { + "ReplicationTaskArn": "arn:aws:dms:us-east-1:123456789012:endpoint:ASXWXJZLNWNT5HTWCGV2BUJQ7E" + }, + "output": { + "ReplicationTask": { + "MigrationType": "full-load", + "ReplicationInstanceArn": "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ", + "ReplicationTaskArn": "arn:aws:dms:us-east-1:123456789012:task:OEAMB3NXSTZ6LFYZFEPPBBXPYM", + "ReplicationTaskCreationDate": "2016-12-14T18:25:43Z", + "ReplicationTaskIdentifier": "task1", + "ReplicationTaskSettings": "{\"TargetMetadata\":{\"TargetSchema\":\"\",\"SupportLobs\":true,\"FullLobMode\":true,\"LobChunkSize\":64,\"LimitedSizeLobMode\":false,\"LobMaxSize\":0},\"FullLoadSettings\":{\"FullLoadEnabled\":true,\"ApplyChangesEnabled\":false,\"TargetTablePrepMode\":\"DROP_AND_CREATE\",\"CreatePkAfterFullLoad\":false,\"StopTaskCachedChangesApplied\":false,\"StopTaskCachedChangesNotApplied\":false,\"ResumeEnabled\":false,\"ResumeMinTableSize\":100000,\"ResumeOnlyClusteredPKTables\":true,\"MaxFullLoadSubTasks\":8,\"TransactionConsistencyTimeout\":600,\"CommitRate\":10000},\"Logging\":{\"EnableLogging\":false}}", + "SourceEndpointArn": "arn:aws:dms:us-east-1:123456789012:endpoint:ZW5UAN6P4E77EC7YWHK4RZZ3BE", + "Status": "creating", + "TableMappings": "file://mappingfile.json", + "TargetEndpointArn": "arn:aws:dms:us-east-1:123456789012:endpoint:ASXWXJZLNWNT5HTWCGV2BUJQ7E" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Stops the replication task.", + "id": "stop-replication-task-1481762924947", + "title": "Stop replication task" + } + ], + "TestConnection": [ + { + "input": { + "EndpointArn": "arn:aws:dms:us-east-1:123456789012:endpoint:RAAR3R22XSH46S3PWLC3NJAWKM", + "ReplicationInstanceArn": "arn:aws:dms:us-east-1:123456789012:rep:6UTDJGBOUS3VI3SUWA66XFJCJQ" + }, + "output": { + "Connection": { + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Tests the connection between the replication instance and the endpoint.", + "id": "test-conection-1481763017636", + "title": "Test conection" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/dms/2016-01-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/dms/2016-01-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ae92c8252ca333f2b8c6c584caf5e469abc82e9c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/dms/2016-01-01/paginators-1.json @@ -0,0 +1,100 @@ +{ + "pagination": { + "DescribeSchemas": { + "result_key": "Schemas", + "output_token": "Marker", + "input_token": "Marker", + "limit_key": "MaxRecords" + }, + "DescribeCertificates": { + "result_key": "Certificates", + "output_token": "Marker", + "input_token": "Marker", + "limit_key": "MaxRecords" + }, + "DescribeEndpoints": { + "result_key": "Endpoints", + "output_token": "Marker", + "input_token": "Marker", + "limit_key": "MaxRecords" + }, + "DescribeEventSubscriptions": { + "result_key": "EventSubscriptionsList", + "output_token": "Marker", + "input_token": "Marker", + "limit_key": "MaxRecords" + }, + "DescribeEndpointTypes": { + "result_key": "SupportedEndpointTypes", + "output_token": "Marker", + "input_token": "Marker", + "limit_key": "MaxRecords" + }, + "DescribeReplicationInstances": { + "result_key": "ReplicationInstances", + "output_token": "Marker", + "input_token": "Marker", + "limit_key": "MaxRecords" + }, + "DescribeTableStatistics": { + "result_key": "TableStatistics", + "output_token": "Marker", + "input_token": "Marker", + "limit_key": "MaxRecords" + }, + "DescribeConnections": { + "result_key": "Connections", + "output_token": "Marker", + "input_token": "Marker", + "limit_key": "MaxRecords" + }, + "DescribeReplicationTaskAssessmentResults": { + "result_key": "ReplicationTaskAssessmentResults", + "output_token": "Marker", + "input_token": "Marker", + "limit_key": "MaxRecords" + }, + "DescribeEvents": { + "result_key": "Events", + "output_token": "Marker", + "input_token": "Marker", + "limit_key": "MaxRecords" + }, + "DescribeOrderableReplicationInstances": { + "result_key": "OrderableReplicationInstances", + "output_token": "Marker", + "input_token": "Marker", + "limit_key": "MaxRecords" + }, + "DescribeReplicationSubnetGroups": { + "result_key": "ReplicationSubnetGroups", + "output_token": "Marker", + "input_token": "Marker", + "limit_key": "MaxRecords" + }, + "DescribeReplicationTasks": { + "result_key": "ReplicationTasks", + "output_token": "Marker", + "input_token": "Marker", + "limit_key": "MaxRecords" + }, + "DescribeDataMigrations": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "DataMigrations" + }, + "DescribeMetadataModelChildren": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "MetadataModelChildren" + }, + "DescribeMetadataModelCreations": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "Requests" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/dms/2016-01-01/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/dms/2016-01-01/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..73fba51002da1678e59de4b6d672143138e59831 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/dms/2016-01-01/waiters-2.json @@ -0,0 +1,330 @@ +{ + "version":2, + "waiters":{ + "TestConnectionSucceeds":{ + "acceptors":[ + { + "argument":"Connections[].Status", + "expected":"successful", + "matcher":"pathAll", + "state":"success" + }, + { + "argument":"Connections[].Status", + "expected":"failed", + "matcher":"pathAny", + "state":"failure" + } + ], + "delay":5, + "description":"Wait until testing connection succeeds.", + "maxAttempts":60, + "operation":"DescribeConnections" + }, + "EndpointDeleted":{ + "acceptors":[ + { + "expected":"ResourceNotFoundFault", + "matcher":"error", + "state":"success" + }, + { + "argument":"Endpoints[].Status", + "expected":"active", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"Endpoints[].Status", + "expected":"creating", + "matcher":"pathAny", + "state":"failure" + } + ], + "delay":5, + "description":"Wait until testing endpoint is deleted.", + "maxAttempts":60, + "operation":"DescribeEndpoints" + }, + "ReplicationInstanceAvailable":{ + "acceptors":[ + { + "argument":"ReplicationInstances[].ReplicationInstanceStatus", + "expected":"available", + "matcher":"pathAll", + "state":"success" + }, + { + "argument":"ReplicationInstances[].ReplicationInstanceStatus", + "expected":"deleting", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationInstances[].ReplicationInstanceStatus", + "expected":"incompatible-credentials", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationInstances[].ReplicationInstanceStatus", + "expected":"incompatible-network", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationInstances[].ReplicationInstanceStatus", + "expected":"inaccessible-encryption-credentials", + "matcher":"pathAny", + "state":"failure" + } + ], + "delay":60, + "description":"Wait until DMS replication instance is available.", + "maxAttempts":60, + "operation":"DescribeReplicationInstances" + }, + "ReplicationInstanceDeleted":{ + "acceptors":[ + { + "argument":"ReplicationInstances[].ReplicationInstanceStatus", + "expected":"available", + "matcher":"pathAny", + "state":"failure" + }, + { + "expected":"ResourceNotFoundFault", + "matcher":"error", + "state":"success" + } + ], + "delay":15, + "description":"Wait until DMS replication instance is deleted.", + "maxAttempts":60, + "operation":"DescribeReplicationInstances" + }, + "ReplicationTaskReady":{ + "acceptors":[ + { + "argument":"ReplicationTasks[].Status", + "expected":"ready", + "matcher":"pathAll", + "state":"success" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"starting", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"running", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"stopping", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"stopped", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"failed", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"modifying", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"testing", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"deleting", + "matcher":"pathAny", + "state":"failure" + } + ], + "delay":15, + "description":"Wait until DMS replication task is ready.", + "maxAttempts":60, + "operation":"DescribeReplicationTasks" + }, + "ReplicationTaskStopped":{ + "acceptors":[ + { + "argument":"ReplicationTasks[].Status", + "expected":"stopped", + "matcher":"pathAll", + "state":"success" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"ready", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"creating", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"starting", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"failed", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"modifying", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"testing", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"deleting", + "matcher":"pathAny", + "state":"failure" + } + ], + "delay":15, + "description":"Wait until DMS replication task is stopped.", + "maxAttempts":60, + "operation":"DescribeReplicationTasks" + }, + "ReplicationTaskRunning":{ + "acceptors":[ + { + "argument":"ReplicationTasks[].Status", + "expected":"running", + "matcher":"pathAll", + "state":"success" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"ready", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"creating", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"stopping", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"stopped", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"failed", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"modifying", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"testing", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"deleting", + "matcher":"pathAny", + "state":"failure" + } + ], + "delay":15, + "description":"Wait until DMS replication task is running.", + "maxAttempts":60, + "operation":"DescribeReplicationTasks" + }, + "ReplicationTaskDeleted":{ + "acceptors":[ + { + "argument":"ReplicationTasks[].Status", + "expected":"ready", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"creating", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"stopped", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"running", + "matcher":"pathAny", + "state":"failure" + }, + { + "argument":"ReplicationTasks[].Status", + "expected":"failed", + "matcher":"pathAny", + "state":"failure" + }, + { + "expected":"ResourceNotFoundFault", + "matcher":"error", + "state":"success" + } + ], + "delay":15, + "description":"Wait until DMS replication task is deleted.", + "maxAttempts":60, + "operation":"DescribeReplicationTasks" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/docdb/2014-10-31/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/docdb/2014-10-31/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/docdb/2014-10-31/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/docdb/2014-10-31/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/docdb/2014-10-31/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..cc1a2f17bc6dfe8acf31394a6c64ce40bd17b17f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/docdb/2014-10-31/paginators-1.json @@ -0,0 +1,82 @@ +{ + "pagination": { + "DescribeCertificates": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "Certificates" + }, + "DescribeDBClusterParameterGroups": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "DBClusterParameterGroups" + }, + "DescribeDBClusterParameters": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "Parameters" + }, + "DescribeDBClusterSnapshots": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "DBClusterSnapshots" + }, + "DescribeDBClusters": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "DBClusters" + }, + "DescribeDBEngineVersions": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "DBEngineVersions" + }, + "DescribeDBInstances": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "DBInstances" + }, + "DescribeDBSubnetGroups": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "DBSubnetGroups" + }, + "DescribeEvents": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "Events" + }, + "DescribeOrderableDBInstanceOptions": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "OrderableDBInstanceOptions" + }, + "DescribePendingMaintenanceActions": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "PendingMaintenanceActions" + }, + "DescribeEventSubscriptions": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "EventSubscriptionsList" + }, + "DescribeGlobalClusters": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "GlobalClusters" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/docdb/2014-10-31/service-2.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/docdb/2014-10-31/service-2.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..85e8a104c29182d185856acecaef2151b1f57dbc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/docdb/2014-10-31/service-2.sdk-extras.json @@ -0,0 +1,23 @@ + { + "version": 1.0, + "merge": { + "shapes": { + "CopyDBClusterSnapshotMessage": { + "members": { + "SourceRegion": { + "shape": "String", + "documentation": "

The ID of the region that contains the snapshot to be copied.

" + } + } + }, + "CreateDBClusterMessage": { + "members": { + "SourceRegion": { + "shape": "String", + "documentation": "

The ID of the region that contains the source for the db cluster.

" + } + } + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/docdb/2014-10-31/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/docdb/2014-10-31/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..e75f03b2aa85effd56e8587292971006d06035e0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/docdb/2014-10-31/waiters-2.json @@ -0,0 +1,90 @@ +{ + "version": 2, + "waiters": { + "DBInstanceAvailable": { + "delay": 30, + "operation": "DescribeDBInstances", + "maxAttempts": 60, + "acceptors": [ + { + "expected": "available", + "matcher": "pathAll", + "state": "success", + "argument": "DBInstances[].DBInstanceStatus" + }, + { + "expected": "deleted", + "matcher": "pathAny", + "state": "failure", + "argument": "DBInstances[].DBInstanceStatus" + }, + { + "expected": "deleting", + "matcher": "pathAny", + "state": "failure", + "argument": "DBInstances[].DBInstanceStatus" + }, + { + "expected": "failed", + "matcher": "pathAny", + "state": "failure", + "argument": "DBInstances[].DBInstanceStatus" + }, + { + "expected": "incompatible-restore", + "matcher": "pathAny", + "state": "failure", + "argument": "DBInstances[].DBInstanceStatus" + }, + { + "expected": "incompatible-parameters", + "matcher": "pathAny", + "state": "failure", + "argument": "DBInstances[].DBInstanceStatus" + } + ] + }, + "DBInstanceDeleted": { + "delay": 30, + "operation": "DescribeDBInstances", + "maxAttempts": 60, + "acceptors": [ + { + "expected": "deleted", + "matcher": "pathAll", + "state": "success", + "argument": "DBInstances[].DBInstanceStatus" + }, + { + "expected": "DBInstanceNotFound", + "matcher": "error", + "state": "success" + }, + { + "expected": "creating", + "matcher": "pathAny", + "state": "failure", + "argument": "DBInstances[].DBInstanceStatus" + }, + { + "expected": "modifying", + "matcher": "pathAny", + "state": "failure", + "argument": "DBInstances[].DBInstanceStatus" + }, + { + "expected": "rebooting", + "matcher": "pathAny", + "state": "failure", + "argument": "DBInstances[].DBInstanceStatus" + }, + { + "expected": "resetting-master-credentials", + "matcher": "pathAny", + "state": "failure", + "argument": "DBInstances[].DBInstanceStatus" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/drs/2020-02-26/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/drs/2020-02-26/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/drs/2020-02-26/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/drs/2020-02-26/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/drs/2020-02-26/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..cfe134c789e821aa2d96e934d60b33658af24944 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/drs/2020-02-26/paginators-1.json @@ -0,0 +1,70 @@ +{ + "pagination": { + "DescribeJobLogItems": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "DescribeJobs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "DescribeRecoveryInstances": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "DescribeRecoverySnapshots": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "DescribeReplicationConfigurationTemplates": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "DescribeSourceServers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListExtensibleSourceServers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListStagingAccounts": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "accounts" + }, + "DescribeLaunchConfigurationTemplates": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "DescribeSourceNetworks": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListLaunchActions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/dsql/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/dsql/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..c9cfb66eb2f5889d4b7ee2dd5d25c3ad60a4c3c2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/dsql/2018-05-10/paginators-1.json @@ -0,0 +1,10 @@ +{ + "pagination": { + "ListClusters": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "clusters" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/dsql/2018-05-10/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/dsql/2018-05-10/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..69cd9baaeb5bce3ae38084ae338c00ac1dcc6225 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/dsql/2018-05-10/waiters-2.json @@ -0,0 +1,28 @@ +{ + "version" : 2, + "waiters" : { + "ClusterActive" : { + "description" : "Wait until a Cluster is ACTIVE", + "delay" : 2, + "maxAttempts" : 60, + "operation" : "GetCluster", + "acceptors" : [ { + "matcher" : "path", + "argument" : "status", + "state" : "success", + "expected" : "ACTIVE" + } ] + }, + "ClusterNotExists" : { + "description" : "Wait until a Cluster is gone", + "delay" : 2, + "maxAttempts" : 60, + "operation" : "GetCluster", + "acceptors" : [ { + "matcher" : "error", + "state" : "success", + "expected" : "ResourceNotFoundException" + } ] + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/dynamodb/2011-12-05/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/dynamodb/2011-12-05/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/dynamodb/2011-12-05/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/dynamodb/2012-08-10/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/dynamodb/2012-08-10/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..bbc763c982a76f0500bc928792321fa8761d0e6f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/dynamodb/2012-08-10/examples-1.json @@ -0,0 +1,631 @@ +{ + "version": "1.0", + "examples": { + "BatchGetItem": [ + { + "input": { + "RequestItems": { + "Music": { + "Keys": [ + { + "Artist": { + "S": "No One You Know" + }, + "SongTitle": { + "S": "Call Me Today" + } + }, + { + "Artist": { + "S": "Acme Band" + }, + "SongTitle": { + "S": "Happy Day" + } + }, + { + "Artist": { + "S": "No One You Know" + }, + "SongTitle": { + "S": "Scared of My Shadow" + } + } + ], + "ProjectionExpression": "AlbumTitle" + } + } + }, + "output": { + "Responses": { + "Music": [ + { + "AlbumTitle": { + "S": "Somewhat Famous" + } + }, + { + "AlbumTitle": { + "S": "Blue Sky Blues" + } + }, + { + "AlbumTitle": { + "S": "Louder Than Ever" + } + } + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example reads multiple items from the Music table using a batch of three GetItem requests. Only the AlbumTitle attribute is returned.", + "id": "to-retrieve-multiple-items-from-a-table-1476118438992", + "title": "To retrieve multiple items from a table" + } + ], + "BatchWriteItem": [ + { + "input": { + "RequestItems": { + "Music": [ + { + "PutRequest": { + "Item": { + "AlbumTitle": { + "S": "Somewhat Famous" + }, + "Artist": { + "S": "No One You Know" + }, + "SongTitle": { + "S": "Call Me Today" + } + } + } + }, + { + "PutRequest": { + "Item": { + "AlbumTitle": { + "S": "Songs About Life" + }, + "Artist": { + "S": "Acme Band" + }, + "SongTitle": { + "S": "Happy Day" + } + } + } + }, + { + "PutRequest": { + "Item": { + "AlbumTitle": { + "S": "Blue Sky Blues" + }, + "Artist": { + "S": "No One You Know" + }, + "SongTitle": { + "S": "Scared of My Shadow" + } + } + } + } + ] + } + }, + "output": { + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example adds three new items to the Music table using a batch of three PutItem requests.", + "id": "to-add-multiple-items-to-a-table-1476118519747", + "title": "To add multiple items to a table" + } + ], + "CreateTable": [ + { + "input": { + "AttributeDefinitions": [ + { + "AttributeName": "Artist", + "AttributeType": "S" + }, + { + "AttributeName": "SongTitle", + "AttributeType": "S" + } + ], + "KeySchema": [ + { + "AttributeName": "Artist", + "KeyType": "HASH" + }, + { + "AttributeName": "SongTitle", + "KeyType": "RANGE" + } + ], + "ProvisionedThroughput": { + "ReadCapacityUnits": 5, + "WriteCapacityUnits": 5 + }, + "TableName": "Music" + }, + "output": { + "TableDescription": { + "AttributeDefinitions": [ + { + "AttributeName": "Artist", + "AttributeType": "S" + }, + { + "AttributeName": "SongTitle", + "AttributeType": "S" + } + ], + "CreationDateTime": "1421866952.062", + "ItemCount": 0, + "KeySchema": [ + { + "AttributeName": "Artist", + "KeyType": "HASH" + }, + { + "AttributeName": "SongTitle", + "KeyType": "RANGE" + } + ], + "ProvisionedThroughput": { + "ReadCapacityUnits": 5, + "WriteCapacityUnits": 5 + }, + "TableName": "Music", + "TableSizeBytes": 0, + "TableStatus": "CREATING" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example creates a table named Music.", + "id": "to-create-a-table-1476116291743", + "title": "To create a table" + } + ], + "DeleteItem": [ + { + "input": { + "Key": { + "Artist": { + "S": "No One You Know" + }, + "SongTitle": { + "S": "Scared of My Shadow" + } + }, + "TableName": "Music" + }, + "output": { + "ConsumedCapacity": { + "CapacityUnits": 1, + "TableName": "Music" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deletes an item from the Music table.", + "id": "to-delete-an-item-1475884573758", + "title": "To delete an item" + } + ], + "DeleteTable": [ + { + "input": { + "TableName": "Music" + }, + "output": { + "TableDescription": { + "ItemCount": 0, + "ProvisionedThroughput": { + "NumberOfDecreasesToday": 1, + "ReadCapacityUnits": 5, + "WriteCapacityUnits": 5 + }, + "TableName": "Music", + "TableSizeBytes": 0, + "TableStatus": "DELETING" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deletes the Music table.", + "id": "to-delete-a-table-1475884368755", + "title": "To delete a table" + } + ], + "DescribeLimits": [ + { + "input": { + }, + "output": { + "AccountMaxReadCapacityUnits": 20000, + "AccountMaxWriteCapacityUnits": 20000, + "TableMaxReadCapacityUnits": 10000, + "TableMaxWriteCapacityUnits": 10000 + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns the maximum read and write capacity units per table, and for the AWS account, in the current AWS region.", + "id": "to-determine-capacity-limits-per-table-and-account-in-the-current-aws-region-1475884162064", + "title": "To determine capacity limits per table and account, in the current AWS region" + } + ], + "DescribeTable": [ + { + "input": { + "TableName": "Music" + }, + "output": { + "Table": { + "AttributeDefinitions": [ + { + "AttributeName": "Artist", + "AttributeType": "S" + }, + { + "AttributeName": "SongTitle", + "AttributeType": "S" + } + ], + "CreationDateTime": "1421866952.062", + "ItemCount": 0, + "KeySchema": [ + { + "AttributeName": "Artist", + "KeyType": "HASH" + }, + { + "AttributeName": "SongTitle", + "KeyType": "RANGE" + } + ], + "ProvisionedThroughput": { + "NumberOfDecreasesToday": 1, + "ReadCapacityUnits": 5, + "WriteCapacityUnits": 5 + }, + "TableName": "Music", + "TableSizeBytes": 0, + "TableStatus": "ACTIVE" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the Music table.", + "id": "to-describe-a-table-1475884440502", + "title": "To describe a table" + } + ], + "GetItem": [ + { + "input": { + "Key": { + "Artist": { + "S": "Acme Band" + }, + "SongTitle": { + "S": "Happy Day" + } + }, + "TableName": "Music" + }, + "output": { + "Item": { + "AlbumTitle": { + "S": "Songs About Life" + }, + "Artist": { + "S": "Acme Band" + }, + "SongTitle": { + "S": "Happy Day" + } + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example retrieves an item from the Music table. The table has a partition key and a sort key (Artist and SongTitle), so you must specify both of these attributes.", + "id": "to-read-an-item-from-a-table-1475884258350", + "title": "To read an item from a table" + } + ], + "ListTables": [ + { + "input": { + }, + "output": { + "TableNames": [ + "Forum", + "ProductCatalog", + "Reply", + "Thread" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example lists all of the tables associated with the current AWS account and endpoint.", + "id": "to-list-tables-1475884741238", + "title": "To list tables" + } + ], + "PutItem": [ + { + "input": { + "Item": { + "AlbumTitle": { + "S": "Somewhat Famous" + }, + "Artist": { + "S": "No One You Know" + }, + "SongTitle": { + "S": "Call Me Today" + } + }, + "ReturnConsumedCapacity": "TOTAL", + "TableName": "Music" + }, + "output": { + "ConsumedCapacity": { + "CapacityUnits": 1, + "TableName": "Music" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example adds a new item to the Music table.", + "id": "to-add-an-item-to-a-table-1476116191110", + "title": "To add an item to a table" + } + ], + "Query": [ + { + "input": { + "ExpressionAttributeValues": { + ":v1": { + "S": "No One You Know" + } + }, + "KeyConditionExpression": "Artist = :v1", + "ProjectionExpression": "SongTitle", + "TableName": "Music" + }, + "output": { + "ConsumedCapacity": { + }, + "Count": 2, + "Items": [ + { + "SongTitle": { + "S": "Call Me Today" + } + } + ], + "ScannedCount": 2 + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example queries items in the Music table. The table has a partition key and sort key (Artist and SongTitle), but this query only specifies the partition key value. It returns song titles by the artist named \"No One You Know\".", + "id": "to-query-an-item-1475883874631", + "title": "To query an item" + } + ], + "Scan": [ + { + "input": { + "ExpressionAttributeNames": { + "#AT": "AlbumTitle", + "#ST": "SongTitle" + }, + "ExpressionAttributeValues": { + ":a": { + "S": "No One You Know" + } + }, + "FilterExpression": "Artist = :a", + "ProjectionExpression": "#ST, #AT", + "TableName": "Music" + }, + "output": { + "ConsumedCapacity": { + }, + "Count": 2, + "Items": [ + { + "AlbumTitle": { + "S": "Somewhat Famous" + }, + "SongTitle": { + "S": "Call Me Today" + } + }, + { + "AlbumTitle": { + "S": "Blue Sky Blues" + }, + "SongTitle": { + "S": "Scared of My Shadow" + } + } + ], + "ScannedCount": 3 + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example scans the entire Music table, and then narrows the results to songs by the artist \"No One You Know\". For each item, only the album title and song title are returned.", + "id": "to-scan-a-table-1475883652470", + "title": "To scan a table" + } + ], + "UpdateItem": [ + { + "input": { + "ExpressionAttributeNames": { + "#AT": "AlbumTitle", + "#Y": "Year" + }, + "ExpressionAttributeValues": { + ":t": { + "S": "Louder Than Ever" + }, + ":y": { + "N": "2015" + } + }, + "Key": { + "Artist": { + "S": "Acme Band" + }, + "SongTitle": { + "S": "Happy Day" + } + }, + "ReturnValues": "ALL_NEW", + "TableName": "Music", + "UpdateExpression": "SET #Y = :y, #AT = :t" + }, + "output": { + "Attributes": { + "AlbumTitle": { + "S": "Louder Than Ever" + }, + "Artist": { + "S": "Acme Band" + }, + "SongTitle": { + "S": "Happy Day" + }, + "Year": { + "N": "2015" + } + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example updates an item in the Music table. It adds a new attribute (Year) and modifies the AlbumTitle attribute. All of the attributes in the item, as they appear after the update, are returned in the response.", + "id": "to-update-an-item-in-a-table-1476118250055", + "title": "To update an item in a table" + } + ], + "UpdateTable": [ + { + "input": { + "ProvisionedThroughput": { + "ReadCapacityUnits": 10, + "WriteCapacityUnits": 10 + }, + "TableName": "MusicCollection" + }, + "output": { + "TableDescription": { + "AttributeDefinitions": [ + { + "AttributeName": "Artist", + "AttributeType": "S" + }, + { + "AttributeName": "SongTitle", + "AttributeType": "S" + } + ], + "CreationDateTime": "1421866952.062", + "ItemCount": 0, + "KeySchema": [ + { + "AttributeName": "Artist", + "KeyType": "HASH" + }, + { + "AttributeName": "SongTitle", + "KeyType": "RANGE" + } + ], + "ProvisionedThroughput": { + "LastIncreaseDateTime": "1421874759.194", + "NumberOfDecreasesToday": 1, + "ReadCapacityUnits": 1, + "WriteCapacityUnits": 1 + }, + "TableName": "MusicCollection", + "TableSizeBytes": 0, + "TableStatus": "UPDATING" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example increases the provisioned read and write capacity on the Music table.", + "id": "to-modify-a-tables-provisioned-throughput-1476118076147", + "title": "To modify a table's provisioned throughput" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/dynamodb/2012-08-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/dynamodb/2012-08-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..8e10a0c75675e8b786b8d4da4e1d2ea5a27dc75b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/dynamodb/2012-08-10/paginators-1.json @@ -0,0 +1,47 @@ +{ + "pagination": { + "ListBackups": { + "input_token": "ExclusiveStartBackupArn", + "output_token": "LastEvaluatedBackupArn", + "limit_key": "Limit", + "result_key": "BackupSummaries" + }, + "ListTables": { + "input_token": "ExclusiveStartTableName", + "output_token": "LastEvaluatedTableName", + "limit_key": "Limit", + "result_key": "TableNames" + }, + "Query": { + "input_token": "ExclusiveStartKey", + "output_token": "LastEvaluatedKey", + "limit_key": "Limit", + "result_key": [ + "Items", + "Count", + "ScannedCount" + ], + "non_aggregate_keys": [ + "ConsumedCapacity" + ] + }, + "Scan": { + "input_token": "ExclusiveStartKey", + "output_token": "LastEvaluatedKey", + "limit_key": "Limit", + "result_key": [ + "Items", + "Count", + "ScannedCount" + ], + "non_aggregate_keys": [ + "ConsumedCapacity" + ] + }, + "ListTagsOfResource": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Tags" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/dynamodb/2012-08-10/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/dynamodb/2012-08-10/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..43a55ca7bd9ddb71d17c5119642bace6da75b323 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/dynamodb/2012-08-10/waiters-2.json @@ -0,0 +1,35 @@ +{ + "version": 2, + "waiters": { + "TableExists": { + "delay": 20, + "operation": "DescribeTable", + "maxAttempts": 25, + "acceptors": [ + { + "expected": "ACTIVE", + "matcher": "path", + "state": "success", + "argument": "Table.TableStatus" + }, + { + "expected": "ResourceNotFoundException", + "matcher": "error", + "state": "retry" + } + ] + }, + "TableNotExists": { + "delay": 20, + "operation": "DescribeTable", + "maxAttempts": 25, + "acceptors": [ + { + "expected": "ResourceNotFoundException", + "matcher": "error", + "state": "success" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ec2-instance-connect/2018-04-02/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/ec2-instance-connect/2018-04-02/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..c5c60013a712c0bb1a7c70b21967bfb02be1e76f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ec2-instance-connect/2018-04-02/examples-1.json @@ -0,0 +1,34 @@ +{ + "version": "1.0", + "examples": { + "SendSSHPublicKey": [ + { + "input": { + "AvailabilityZone": "us-west-2a", + "InstanceId": "i-abcd1234", + "InstanceOSUser": "ec2-user", + "SSHPublicKey": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC3FlHqj2eqCdrGHuA6dRjfZXQ4HX5lXEIRHaNbxEwE5Te7xNF7StwhrDtiV7IdT5fDqbRyGw/szPj3xGkNTVoElCZ2dDFb2qYZ1WLIpZwj/UhO9l2mgfjR56UojjQut5Jvn2KZ1OcyrNO0J83kCaJCV7JoVbXY79FBMUccYNY45zmv9+1FMCfY6i2jdIhwR6+yLk8oubL8lIPyq7X+6b9S0yKCkB7Peml1DvghlybpAIUrC9vofHt6XP4V1i0bImw1IlljQS+DUmULRFSccATDscCX9ajnj7Crhm0HAZC0tBPXpFdHkPwL3yzYo546SCS9LKEwz62ymxxbL9k7h09t" + }, + "output": { + "RequestId": "abcd1234-abcd-1234-abcd-1234abcd1234", + "Success": true + }, + "comments": { + "input": { + "AvailabilityZone": "The zone where the instance was launched", + "InstanceId": "The instance ID to publish the key to.", + "InstanceOSUser": "This should be the user you wish to be when ssh-ing to the instance (eg, ec2-user@[instance IP])", + "SSHPublicKey": "This should be in standard OpenSSH format (ssh-rsa [key body])" + }, + "output": { + "RequestId": "This request ID should be provided when contacting AWS Support.", + "Success": "Should be true if the service does not return an error response." + } + }, + "description": "The following example pushes a sample SSH public key to the EC2 instance i-abcd1234 in AZ us-west-2b for use by the instance OS user ec2-user.", + "id": "send-ssh-key-to-an-ec2-instance-1518124883100", + "title": "To push an SSH key to an EC2 instance" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ec2-instance-connect/2018-04-02/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/ec2-instance-connect/2018-04-02/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ec2-instance-connect/2018-04-02/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ecr-public/2020-10-30/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/ecr-public/2020-10-30/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ecr-public/2020-10-30/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ecr-public/2020-10-30/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/ecr-public/2020-10-30/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..b9dbda45c90624a3694901c0fc98a675e389284b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ecr-public/2020-10-30/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "DescribeImageTags": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "imageTagDetails" + }, + "DescribeImages": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "imageDetails" + }, + "DescribeRegistries": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "registries" + }, + "DescribeRepositories": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "repositories" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/eks-auth/2023-11-26/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/eks-auth/2023-11-26/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/eks-auth/2023-11-26/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/eks-auth/2023-11-26/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/eks-auth/2023-11-26/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..4b20636aa4c8b334eca901959d698c0b98cba6d6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/eks-auth/2023-11-26/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/eks/2017-11-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/eks/2017-11-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..8ea2517578df4bc3f83337aaffe42eaeadd12875 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/eks/2017-11-01/examples-1.json @@ -0,0 +1,135 @@ +{ + "version": "1.0", + "examples": { + "CreateCluster": [ + { + "input": { + "version": "1.10", + "name": "prod", + "clientRequestToken": "1d2129a1-3d38-460a-9756-e5b91fddb951", + "resourcesVpcConfig": { + "securityGroupIds": [ + "sg-6979fe18" + ], + "subnetIds": [ + "subnet-6782e71e", + "subnet-e7e761ac" + ] + }, + "roleArn": "arn:aws:iam::012345678910:role/eks-service-role-AWSServiceRoleForAmazonEKS-J7ONKE3BQ4PI" + }, + "output": { + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example creates an Amazon EKS cluster called prod.", + "id": "to-create-a-new-cluster-1527868185648", + "title": "To create a new cluster" + } + ], + "DeleteCluster": [ + { + "input": { + "name": "devel" + }, + "output": { + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example command deletes a cluster named `devel` in your default region.", + "id": "to-delete-a-cluster-1527868641252", + "title": "To delete a cluster" + } + ], + "DescribeCluster": [ + { + "input": { + "name": "devel" + }, + "output": { + "cluster": { + "version": "1.10", + "name": "devel", + "arn": "arn:aws:eks:us-west-2:012345678910:cluster/devel", + "certificateAuthority": { + "data": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRFNE1EVXpNVEl6TVRFek1Wb1hEVEk0TURVeU9ESXpNVEV6TVZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTTZWCjVUaG4rdFcySm9Xa2hQMzRlVUZMNitaRXJOZGIvWVdrTmtDdWNGS2RaaXl2TjlMVmdvUmV2MjlFVFZlN1ZGbSsKUTJ3ZURyRXJiQyt0dVlibkFuN1ZLYmE3ay9hb1BHekZMdmVnb0t6b0M1N2NUdGVwZzRIazRlK2tIWHNaME10MApyb3NzcjhFM1ROeExETnNJTThGL1cwdjhsTGNCbWRPcjQyV2VuTjFHZXJnaDNSZ2wzR3JIazBnNTU0SjFWenJZCm9hTi8zODFUczlOTFF2QTBXb0xIcjBFRlZpTFdSZEoyZ3lXaC9ybDVyOFNDOHZaQXg1YW1BU0hVd01aTFpWRC8KTDBpOW4wRVM0MkpVdzQyQmxHOEdpd3NhTkJWV3lUTHZKclNhRXlDSHFtVVZaUTFDZkFXUjl0L3JleVVOVXM3TApWV1FqM3BFbk9RMitMSWJrc0RzQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFNZ3RsQ1dIQ2U2YzVHMXl2YlFTS0Q4K2hUalkKSm1NSG56L2EvRGt0WG9YUjFVQzIrZUgzT1BZWmVjRVZZZHVaSlZCckNNQ2VWR0ZkeWdBYlNLc1FxWDg0S2RXbAp1MU5QaERDSmEyRHliN2pVMUV6VThTQjFGZUZ5ZFE3a0hNS1E1blpBRVFQOTY4S01hSGUrSm0yQ2x1UFJWbEJVCjF4WlhTS1gzTVZ0K1Q0SU1EV2d6c3JRSjVuQkRjdEtLcUZtM3pKdVVubHo5ZEpVckdscEltMjVJWXJDckxYUFgKWkUwRUtRNWEzMHhkVWNrTHRGQkQrOEtBdFdqSS9yZUZPNzM1YnBMdVoyOTBaNm42QlF3elRrS0p4cnhVc3QvOAppNGsxcnlsaUdWMm5SSjBUYjNORkczNHgrYWdzYTRoSTFPbU90TFM0TmgvRXJxT3lIUXNDc2hEQUtKUT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=" + }, + "createdAt": 1527807879.988, + "endpoint": "https://A0DCCD80A04F01705DD065655C30CC3D.yl4.us-west-2.eks.amazonaws.com", + "resourcesVpcConfig": { + "securityGroupIds": [ + "sg-6979fe18" + ], + "subnetIds": [ + "subnet-6782e71e", + "subnet-e7e761ac" + ], + "vpcId": "vpc-950809ec" + }, + "roleArn": "arn:aws:iam::012345678910:role/eks-service-role-AWSServiceRoleForAmazonEKS-J7ONKE3BQ4PI", + "status": "ACTIVE" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example command provides a description of the specified cluster in your default region.", + "id": "to-describe-a-cluster-1527868708512", + "title": "To describe a cluster" + } + ], + "ListClusters": [ + { + "input": { + }, + "output": { + "clusters": [ + "devel", + "prod" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example command lists all of your available clusters in your default region.", + "id": "to-list-your-available-clusters-1527868801040", + "title": "To list your available clusters" + } + ], + "ListTagsForResource": [ + { + "input": { + "resourceArn": "arn:aws:eks:us-west-2:012345678910:cluster/beta" + }, + "output": { + "tags": { + "aws:tag:domain": "beta" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example lists all of the tags for the `beta` cluster.", + "id": "to-list-tags-for-a-cluster-1568666903378", + "title": "To list tags for a cluster" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/eks/2017-11-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/eks/2017-11-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..652eef167ec9f4a7c478e3890aea2a5177f8bb2e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/eks/2017-11-01/paginators-1.json @@ -0,0 +1,98 @@ +{ + "pagination": { + "ListClusters": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "clusters" + }, + "ListUpdates": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "updateIds" + }, + "ListNodegroups": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "nodegroups" + }, + "ListFargateProfiles": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "fargateProfileNames" + }, + "DescribeAddonVersions": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "addons" + }, + "ListAddons": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "addons" + }, + "ListIdentityProviderConfigs": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "identityProviderConfigs" + }, + "ListEksAnywhereSubscriptions": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "subscriptions" + }, + "ListPodIdentityAssociations": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "associations" + }, + "ListAccessEntries": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "accessEntries" + }, + "ListAccessPolicies": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "accessPolicies" + }, + "ListAssociatedAccessPolicies": { + "input_token": "nextToken", + "limit_key": "maxResults", + "non_aggregate_keys": [ + "clusterName", + "principalArn" + ], + "output_token": "nextToken", + "result_key": "associatedAccessPolicies" + }, + "ListInsights": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "insights" + }, + "DescribeClusterVersions": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "clusterVersions" + }, + "ListCapabilities": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "capabilities" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/eks/2017-11-01/service-2.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/eks/2017-11-01/service-2.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..b636c2112e6db1908225043a18c009a8c3d06229 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/eks/2017-11-01/service-2.sdk-extras.json @@ -0,0 +1,8 @@ +{ + "version": 1.0, + "merge": { + "metadata": { + "serviceId":"EKS" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/eks/2017-11-01/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/eks/2017-11-01/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..c06890979c8e3b17b71eae5526689cb5b4831c9c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/eks/2017-11-01/waiters-2.json @@ -0,0 +1,177 @@ +{ + "version": 2, + "waiters": { + "ClusterActive": { + "delay": 30, + "operation": "DescribeCluster", + "maxAttempts": 40, + "acceptors": [ + { + "expected": "DELETING", + "matcher": "path", + "state": "failure", + "argument": "cluster.status" + }, + { + "expected": "FAILED", + "matcher": "path", + "state": "failure", + "argument": "cluster.status" + }, + { + "expected": "ACTIVE", + "matcher": "path", + "state": "success", + "argument": "cluster.status" + } + ] + }, + "ClusterDeleted": { + "delay": 30, + "operation": "DescribeCluster", + "maxAttempts": 40, + "acceptors": [ + { + "expected": "ACTIVE", + "matcher": "path", + "state": "failure", + "argument": "cluster.status" + }, + { + "expected": "CREATING", + "matcher": "path", + "state": "failure", + "argument": "cluster.status" + }, + { + "expected": "PENDING", + "matcher": "path", + "state": "failure", + "argument": "cluster.status" + }, + { + "expected": "ResourceNotFoundException", + "matcher": "error", + "state": "success" + } + ] + }, + "NodegroupActive": { + "delay": 30, + "operation": "DescribeNodegroup", + "maxAttempts": 80, + "acceptors": [ + { + "expected": "CREATE_FAILED", + "matcher": "path", + "state": "failure", + "argument": "nodegroup.status" + }, + { + "expected": "ACTIVE", + "matcher": "path", + "state": "success", + "argument": "nodegroup.status" + } + ] + }, + "NodegroupDeleted": { + "delay": 30, + "operation": "DescribeNodegroup", + "maxAttempts": 40, + "acceptors": [ + { + "expected": "DELETE_FAILED", + "matcher": "path", + "state": "failure", + "argument": "nodegroup.status" + }, + { + "expected": "ResourceNotFoundException", + "matcher": "error", + "state": "success" + } + ] + }, + "AddonActive": { + "delay": 10, + "operation": "DescribeAddon", + "maxAttempts": 60, + "acceptors": [ + { + "expected": "CREATE_FAILED", + "matcher": "path", + "state": "failure", + "argument": "addon.status" + }, + { + "expected": "DEGRADED", + "matcher": "path", + "state": "failure", + "argument": "addon.status" + }, + { + "expected": "ACTIVE", + "matcher": "path", + "state": "success", + "argument": "addon.status" + } + ] + }, + "AddonDeleted": { + "delay": 10, + "operation": "DescribeAddon", + "maxAttempts": 60, + "acceptors": [ + { + "expected": "DELETE_FAILED", + "matcher": "path", + "state": "failure", + "argument": "addon.status" + }, + { + "expected": "ResourceNotFoundException", + "matcher": "error", + "state": "success" + } + ] + }, + "FargateProfileActive": { + "delay": 10, + "operation": "DescribeFargateProfile", + "maxAttempts": 60, + "acceptors": [ + { + "expected": "CREATE_FAILED", + "matcher": "path", + "state": "failure", + "argument": "fargateProfile.status" + }, + { + "expected": "ACTIVE", + "matcher": "path", + "state": "success", + "argument": "fargateProfile.status" + } + ] + }, + "FargateProfileDeleted": { + "delay": 30, + "operation": "DescribeFargateProfile", + "maxAttempts": 60, + "acceptors": [ + { + "expected": "DELETE_FAILED", + "matcher": "path", + "state": "failure", + "argument": "fargateProfile.status" + }, + { + "expected": "ResourceNotFoundException", + "matcher": "error", + "state": "success" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/elasticbeanstalk/2010-12-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/elasticbeanstalk/2010-12-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0fded62815628f6b0586acfda2445a5a5774f7ee --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/elasticbeanstalk/2010-12-01/examples-1.json @@ -0,0 +1,1109 @@ +{ + "version": "1.0", + "examples": { + "AbortEnvironmentUpdate": [ + { + "input": { + "EnvironmentName": "my-env" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following code aborts a running application version deployment for an environment named my-env:", + "id": "to-abort-a-deployment-1456267848227", + "title": "To abort a deployment" + } + ], + "CheckDNSAvailability": [ + { + "input": { + "CNAMEPrefix": "my-cname" + }, + "output": { + "Available": true, + "FullyQualifiedCNAME": "my-cname.us-west-2.elasticbeanstalk.com" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation checks the availability of the subdomain my-cname:", + "id": "to-check-the-availability-of-a-cname-1456268589537", + "title": "To check the availability of a CNAME" + } + ], + "CreateApplication": [ + { + "input": { + "ApplicationName": "my-app", + "Description": "my application" + }, + "output": { + "Application": { + "ApplicationName": "my-app", + "ConfigurationTemplates": [ + + ], + "DateCreated": "2015-02-12T18:32:21.181Z", + "DateUpdated": "2015-02-12T18:32:21.181Z", + "Description": "my application" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation creates a new application named my-app:", + "id": "to-create-a-new-application-1456268895683", + "title": "To create a new application" + } + ], + "CreateApplicationVersion": [ + { + "input": { + "ApplicationName": "my-app", + "AutoCreateApplication": true, + "Description": "my-app-v1", + "Process": true, + "SourceBundle": { + "S3Bucket": "my-bucket", + "S3Key": "sample.war" + }, + "VersionLabel": "v1" + }, + "output": { + "ApplicationVersion": { + "ApplicationName": "my-app", + "DateCreated": "2015-02-03T23:01:25.412Z", + "DateUpdated": "2015-02-03T23:01:25.412Z", + "Description": "my-app-v1", + "SourceBundle": { + "S3Bucket": "my-bucket", + "S3Key": "sample.war" + }, + "VersionLabel": "v1" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation creates a new version (v1) of an application named my-app:", + "id": "to-create-a-new-application-1456268895683", + "title": "To create a new application" + } + ], + "CreateConfigurationTemplate": [ + { + "input": { + "ApplicationName": "my-app", + "EnvironmentId": "e-rpqsewtp2j", + "TemplateName": "my-app-v1" + }, + "output": { + "ApplicationName": "my-app", + "DateCreated": "2015-08-12T18:40:39Z", + "DateUpdated": "2015-08-12T18:40:39Z", + "SolutionStackName": "64bit Amazon Linux 2015.03 v2.0.0 running Tomcat 8 Java 8", + "TemplateName": "my-app-v1" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation creates a configuration template named my-app-v1 from the settings applied to an environment with the id e-rpqsewtp2j:", + "id": "to-create-a-configuration-template-1456269283586", + "title": "To create a configuration template" + } + ], + "CreateEnvironment": [ + { + "input": { + "ApplicationName": "my-app", + "CNAMEPrefix": "my-app", + "EnvironmentName": "my-env", + "SolutionStackName": "64bit Amazon Linux 2015.03 v2.0.0 running Tomcat 8 Java 8", + "VersionLabel": "v1" + }, + "output": { + "ApplicationName": "my-app", + "CNAME": "my-app.elasticbeanstalk.com", + "DateCreated": "2015-02-03T23:04:54.479Z", + "DateUpdated": "2015-02-03T23:04:54.479Z", + "EnvironmentId": "e-izqpassy4h", + "EnvironmentName": "my-env", + "Health": "Grey", + "SolutionStackName": "64bit Amazon Linux 2015.03 v2.0.0 running Tomcat 8 Java 8", + "Status": "Launching", + "Tier": { + "Name": "WebServer", + "Type": "Standard", + "Version": " " + }, + "VersionLabel": "v1" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation creates a new environment for version v1 of a java application named my-app:", + "id": "to-create-a-new-environment-for-an-application-1456269380396", + "title": "To create a new environment for an application" + } + ], + "CreateStorageLocation": [ + { + "output": { + "S3Bucket": "elasticbeanstalk-us-west-2-0123456789012" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation creates a new environment for version v1 of a java application named my-app:", + "id": "to-create-a-new-environment-for-an-application-1456269380396", + "title": "To create a new environment for an application" + } + ], + "DeleteApplication": [ + { + "input": { + "ApplicationName": "my-app" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation deletes an application named my-app:", + "id": "to-delete-an-application-1456269699366", + "title": "To delete an application" + } + ], + "DeleteApplicationVersion": [ + { + "input": { + "ApplicationName": "my-app", + "DeleteSourceBundle": true, + "VersionLabel": "22a0-stage-150819_182129" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation deletes an application version named 22a0-stage-150819_182129 for an application named my-app:", + "id": "to-delete-an-application-version-1456269792956", + "title": "To delete an application version" + } + ], + "DeleteConfigurationTemplate": [ + { + "input": { + "ApplicationName": "my-app", + "TemplateName": "my-template" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation deletes a configuration template named my-template for an application named my-app:", + "id": "to-delete-a-configuration-template-1456269836701", + "title": "To delete a configuration template" + } + ], + "DeleteEnvironmentConfiguration": [ + { + "input": { + "ApplicationName": "my-app", + "EnvironmentName": "my-env" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation deletes a draft configuration for an environment named my-env:", + "id": "to-delete-a-draft-configuration-1456269886654", + "title": "To delete a draft configuration" + } + ], + "DescribeApplicationVersions": [ + { + "input": { + "ApplicationName": "my-app", + "VersionLabels": [ + "v2" + ] + }, + "output": { + "ApplicationVersions": [ + { + "ApplicationName": "my-app", + "DateCreated": "2015-07-23T01:32:26.079Z", + "DateUpdated": "2015-07-23T01:32:26.079Z", + "Description": "update cover page", + "SourceBundle": { + "S3Bucket": "elasticbeanstalk-us-west-2-015321684451", + "S3Key": "my-app/5026-stage-150723_224258.war" + }, + "VersionLabel": "v2" + }, + { + "ApplicationName": "my-app", + "DateCreated": "2015-07-23T22:26:10.816Z", + "DateUpdated": "2015-07-23T22:26:10.816Z", + "Description": "initial version", + "SourceBundle": { + "S3Bucket": "elasticbeanstalk-us-west-2-015321684451", + "S3Key": "my-app/5026-stage-150723_222618.war" + }, + "VersionLabel": "v1" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation retrieves information about an application version labeled v2:", + "id": "to-view-information-about-an-application-version-1456269947428", + "title": "To view information about an application version" + } + ], + "DescribeApplications": [ + { + "input": { + }, + "output": { + "Applications": [ + { + "ApplicationName": "ruby", + "ConfigurationTemplates": [ + + ], + "DateCreated": "2015-08-13T21:05:44.376Z", + "DateUpdated": "2015-08-13T21:05:44.376Z", + "Versions": [ + "Sample Application" + ] + }, + { + "ApplicationName": "pythonsample", + "ConfigurationTemplates": [ + + ], + "DateCreated": "2015-08-13T19:05:43.637Z", + "DateUpdated": "2015-08-13T19:05:43.637Z", + "Description": "Application created from the EB CLI using \"eb init\"", + "Versions": [ + "Sample Application" + ] + }, + { + "ApplicationName": "nodejs-example", + "ConfigurationTemplates": [ + + ], + "DateCreated": "2015-08-06T17:50:02.486Z", + "DateUpdated": "2015-08-06T17:50:02.486Z", + "Versions": [ + "add elasticache", + "First Release" + ] + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation retrieves information about applications in the current region:", + "id": "to-view-a-list-of-applications-1456270027373", + "title": "To view a list of applications" + } + ], + "DescribeConfigurationOptions": [ + { + "input": { + "ApplicationName": "my-app", + "EnvironmentName": "my-env" + }, + "output": { + "Options": [ + { + "ChangeSeverity": "NoInterruption", + "DefaultValue": "30", + "MaxValue": 300, + "MinValue": 5, + "Name": "Interval", + "Namespace": "aws:elb:healthcheck", + "UserDefined": false, + "ValueType": "Scalar" + }, + { + "ChangeSeverity": "NoInterruption", + "DefaultValue": "2000000", + "MinValue": 0, + "Name": "LowerThreshold", + "Namespace": "aws:autoscaling:trigger", + "UserDefined": false, + "ValueType": "Scalar" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation retrieves descriptions of all available configuration options for an environment named my-env:", + "id": "to-view-configuration-options-for-an-environment-1456276763917", + "title": "To view configuration options for an environment" + } + ], + "DescribeConfigurationSettings": [ + { + "input": { + "ApplicationName": "my-app", + "EnvironmentName": "my-env" + }, + "output": { + "ConfigurationSettings": [ + { + "ApplicationName": "my-app", + "DateCreated": "2015-08-13T19:16:25Z", + "DateUpdated": "2015-08-13T23:30:07Z", + "DeploymentStatus": "deployed", + "Description": "Environment created from the EB CLI using \"eb create\"", + "EnvironmentName": "my-env", + "OptionSettings": [ + { + "Namespace": "aws:autoscaling:asg", + "OptionName": "Availability Zones", + "ResourceName": "AWSEBAutoScalingGroup", + "Value": "Any" + }, + { + "Namespace": "aws:autoscaling:asg", + "OptionName": "Cooldown", + "ResourceName": "AWSEBAutoScalingGroup", + "Value": "360" + }, + { + "Namespace": "aws:elb:policies", + "OptionName": "ConnectionDrainingTimeout", + "ResourceName": "AWSEBLoadBalancer", + "Value": "20" + }, + { + "Namespace": "aws:elb:policies", + "OptionName": "ConnectionSettingIdleTimeout", + "ResourceName": "AWSEBLoadBalancer", + "Value": "60" + } + ], + "SolutionStackName": "64bit Amazon Linux 2015.03 v2.0.0 running Tomcat 8 Java 8" + } + ] + }, + "comments": { + "input": { + }, + "output": { + "abbreviated": "Output is abbreviated" + } + }, + "description": "The following operation retrieves configuration settings for an environment named my-env:", + "id": "to-view-configurations-settings-for-an-environment-1456276924537", + "title": "To view configurations settings for an environment" + } + ], + "DescribeEnvironmentHealth": [ + { + "input": { + "AttributeNames": [ + "All" + ], + "EnvironmentName": "my-env" + }, + "output": { + "ApplicationMetrics": { + "Duration": 10, + "Latency": { + "P10": 0.001, + "P50": 0.001, + "P75": 0.002, + "P85": 0.003, + "P90": 0.003, + "P95": 0.004, + "P99": 0.004, + "P999": 0.004 + }, + "RequestCount": 45, + "StatusCodes": { + "Status2xx": 45, + "Status3xx": 0, + "Status4xx": 0, + "Status5xx": 0 + } + }, + "Causes": [ + + ], + "Color": "Green", + "EnvironmentName": "my-env", + "HealthStatus": "Ok", + "InstancesHealth": { + "Degraded": 0, + "Info": 0, + "NoData": 0, + "Ok": 1, + "Pending": 0, + "Severe": 0, + "Unknown": 0, + "Warning": 0 + }, + "RefreshedAt": "2015-08-20T21:09:18Z" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation retrieves overall health information for an environment named my-env:", + "id": "to-view-environment-health-1456277109510", + "title": "To view environment health" + } + ], + "DescribeEnvironmentResources": [ + { + "input": { + "EnvironmentName": "my-env" + }, + "output": { + "EnvironmentResources": { + "AutoScalingGroups": [ + { + "Name": "awseb-e-qu3fyyjyjs-stack-AWSEBAutoScalingGroup-QSB2ZO88SXZT" + } + ], + "EnvironmentName": "my-env", + "Instances": [ + { + "Id": "i-0c91c786" + } + ], + "LaunchConfigurations": [ + { + "Name": "awseb-e-qu3fyyjyjs-stack-AWSEBAutoScalingLaunchConfiguration-1UUVQIBC96TQ2" + } + ], + "LoadBalancers": [ + { + "Name": "awseb-e-q-AWSEBLoa-1EEPZ0K98BIF0" + } + ], + "Queues": [ + + ], + "Triggers": [ + + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation retrieves information about resources in an environment named my-env:", + "id": "to-view-information-about-the-aws-resources-in-your-environment-1456277206232", + "title": "To view information about the AWS resources in your environment" + } + ], + "DescribeEnvironments": [ + { + "input": { + "EnvironmentNames": [ + "my-env" + ] + }, + "output": { + "Environments": [ + { + "AbortableOperationInProgress": false, + "ApplicationName": "my-app", + "CNAME": "my-env.elasticbeanstalk.com", + "DateCreated": "2015-08-07T20:48:49.599Z", + "DateUpdated": "2015-08-12T18:16:55.019Z", + "EndpointURL": "awseb-e-w-AWSEBLoa-1483140XB0Q4L-109QXY8121.us-west-2.elb.amazonaws.com", + "EnvironmentId": "e-rpqsewtp2j", + "EnvironmentName": "my-env", + "Health": "Green", + "SolutionStackName": "64bit Amazon Linux 2015.03 v2.0.0 running Tomcat 8 Java 8", + "Status": "Ready", + "Tier": { + "Name": "WebServer", + "Type": "Standard", + "Version": " " + }, + "VersionLabel": "7f58-stage-150812_025409" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation retrieves information about an environment named my-env:", + "id": "to-view-information-about-an-environment-1456277288662", + "title": "To view information about an environment" + } + ], + "DescribeEvents": [ + { + "input": { + "EnvironmentName": "my-env" + }, + "output": { + "Events": [ + { + "ApplicationName": "my-app", + "EnvironmentName": "my-env", + "EventDate": "2015-08-20T07:06:53.535Z", + "Message": "Environment health has transitioned from Info to Ok.", + "Severity": "INFO" + }, + { + "ApplicationName": "my-app", + "EnvironmentName": "my-env", + "EventDate": "2015-08-20T07:06:02.049Z", + "Message": "Environment update completed successfully.", + "RequestId": "b7f3960b-4709-11e5-ba1e-07e16200da41", + "Severity": "INFO" + }, + { + "ApplicationName": "my-app", + "EnvironmentName": "my-env", + "EventDate": "2015-08-13T19:16:27.561Z", + "Message": "Using elasticbeanstalk-us-west-2-012445113685 as Amazon S3 storage bucket for environment data.", + "RequestId": "ca8dfbf6-41ef-11e5-988b-651aa638f46b", + "Severity": "INFO" + }, + { + "ApplicationName": "my-app", + "EnvironmentName": "my-env", + "EventDate": "2015-08-13T19:16:26.581Z", + "Message": "createEnvironment is starting.", + "RequestId": "cdfba8f6-41ef-11e5-988b-65638f41aa6b", + "Severity": "INFO" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation retrieves events for an environment named my-env:", + "id": "to-view-events-for-an-environment-1456277367589", + "title": "To view events for an environment" + } + ], + "DescribeInstancesHealth": [ + { + "input": { + "AttributeNames": [ + "All" + ], + "EnvironmentName": "my-env" + }, + "output": { + "InstanceHealthList": [ + { + "ApplicationMetrics": { + "Duration": 10, + "Latency": { + "P10": 0, + "P50": 0.001, + "P75": 0.002, + "P85": 0.003, + "P90": 0.004, + "P95": 0.005, + "P99": 0.006, + "P999": 0.006 + }, + "RequestCount": 48, + "StatusCodes": { + "Status2xx": 47, + "Status3xx": 0, + "Status4xx": 1, + "Status5xx": 0 + } + }, + "Causes": [ + + ], + "Color": "Green", + "HealthStatus": "Ok", + "InstanceId": "i-08691cc7", + "LaunchedAt": "2015-08-13T19:17:09Z", + "System": { + "CPUUtilization": { + "IOWait": 0.2, + "IRQ": 0, + "Idle": 97.8, + "Nice": 0.1, + "SoftIRQ": 0.1, + "System": 0.3, + "User": 1.5 + }, + "LoadAverage": [ + 0, + 0.02, + 0.05 + ] + } + } + ], + "RefreshedAt": "2015-08-20T21:09:08Z" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation retrieves health information for instances in an environment named my-env:", + "id": "to-view-environment-health-1456277424757", + "title": "To view environment health" + } + ], + "ListAvailableSolutionStacks": [ + { + "output": { + "SolutionStackDetails": [ + { + "PermittedFileTypes": [ + "zip" + ], + "SolutionStackName": "64bit Amazon Linux 2015.03 v2.0.0 running Node.js" + } + ], + "SolutionStacks": [ + "64bit Amazon Linux 2015.03 v2.0.0 running Node.js", + "64bit Amazon Linux 2015.03 v2.0.0 running PHP 5.6", + "64bit Amazon Linux 2015.03 v2.0.0 running PHP 5.5", + "64bit Amazon Linux 2015.03 v2.0.0 running PHP 5.4", + "64bit Amazon Linux 2015.03 v2.0.0 running Python 3.4", + "64bit Amazon Linux 2015.03 v2.0.0 running Python 2.7", + "64bit Amazon Linux 2015.03 v2.0.0 running Python", + "64bit Amazon Linux 2015.03 v2.0.0 running Ruby 2.2 (Puma)", + "64bit Amazon Linux 2015.03 v2.0.0 running Ruby 2.2 (Passenger Standalone)", + "64bit Amazon Linux 2015.03 v2.0.0 running Ruby 2.1 (Puma)", + "64bit Amazon Linux 2015.03 v2.0.0 running Ruby 2.1 (Passenger Standalone)", + "64bit Amazon Linux 2015.03 v2.0.0 running Ruby 2.0 (Puma)", + "64bit Amazon Linux 2015.03 v2.0.0 running Ruby 2.0 (Passenger Standalone)", + "64bit Amazon Linux 2015.03 v2.0.0 running Ruby 1.9.3", + "64bit Amazon Linux 2015.03 v2.0.0 running Tomcat 8 Java 8", + "64bit Amazon Linux 2015.03 v2.0.0 running Tomcat 7 Java 7", + "64bit Amazon Linux 2015.03 v2.0.0 running Tomcat 7 Java 6", + "64bit Windows Server Core 2012 R2 running IIS 8.5", + "64bit Windows Server 2012 R2 running IIS 8.5", + "64bit Windows Server 2012 running IIS 8", + "64bit Windows Server 2008 R2 running IIS 7.5", + "64bit Amazon Linux 2015.03 v2.0.0 running Docker 1.6.2", + "64bit Amazon Linux 2015.03 v2.0.0 running Multi-container Docker 1.6.2 (Generic)", + "64bit Debian jessie v2.0.0 running GlassFish 4.1 Java 8 (Preconfigured - Docker)", + "64bit Debian jessie v2.0.0 running GlassFish 4.0 Java 7 (Preconfigured - Docker)", + "64bit Debian jessie v2.0.0 running Go 1.4 (Preconfigured - Docker)", + "64bit Debian jessie v2.0.0 running Go 1.3 (Preconfigured - Docker)", + "64bit Debian jessie v2.0.0 running Python 3.4 (Preconfigured - Docker)" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation lists solution stacks for all currently available platform configurations and any that you have used in the past:", + "id": "to-view-solution-stacks-1456277504811", + "title": "To view solution stacks" + } + ], + "RebuildEnvironment": [ + { + "input": { + "EnvironmentName": "my-env" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation terminates and recreates the resources in an environment named my-env:", + "id": "to-rebuild-an-environment-1456277600918", + "title": "To rebuild an environment" + } + ], + "RequestEnvironmentInfo": [ + { + "input": { + "EnvironmentName": "my-env", + "InfoType": "tail" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation requests logs from an environment named my-env:", + "id": "to-request-tailed-logs-1456277657045", + "title": "To request tailed logs" + } + ], + "RestartAppServer": [ + { + "input": { + "EnvironmentName": "my-env" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation restarts application servers on all instances in an environment named my-env:", + "id": "to-restart-application-servers-1456277739302", + "title": "To restart application servers" + } + ], + "RetrieveEnvironmentInfo": [ + { + "input": { + "EnvironmentName": "my-env", + "InfoType": "tail" + }, + "output": { + "EnvironmentInfo": [ + { + "Ec2InstanceId": "i-09c1c867", + "InfoType": "tail", + "Message": "https://elasticbeanstalk-us-west-2-0123456789012.s3.amazonaws.com/resources/environments/logs/tail/e-fyqyju3yjs/i-09c1c867/TailLogs-1440109397703.out?AWSAccessKeyId=AKGPT4J56IAJ2EUBL5CQ&Expires=1440195891&Signature=n%2BEalOV6A2HIOx4Rcfb7LT16bBM%3D", + "SampleTimestamp": "2015-08-20T22:23:17.703Z" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation retrieves a link to logs from an environment named my-env:", + "id": "to-retrieve-tailed-logs-1456277792734", + "title": "To retrieve tailed logs" + } + ], + "SwapEnvironmentCNAMEs": [ + { + "input": { + "DestinationEnvironmentName": "my-env-green", + "SourceEnvironmentName": "my-env-blue" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation swaps the assigned subdomains of two environments:", + "id": "to-swap-environment-cnames-1456277839438", + "title": "To swap environment CNAMES" + } + ], + "TerminateEnvironment": [ + { + "input": { + "EnvironmentName": "my-env" + }, + "output": { + "AbortableOperationInProgress": false, + "ApplicationName": "my-app", + "CNAME": "my-env.elasticbeanstalk.com", + "DateCreated": "2015-08-12T18:52:53.622Z", + "DateUpdated": "2015-08-12T19:05:54.744Z", + "EndpointURL": "awseb-e-f-AWSEBLoa-1I9XUMP4-8492WNUP202574.us-west-2.elb.amazonaws.com", + "EnvironmentId": "e-fh2eravpns", + "EnvironmentName": "my-env", + "Health": "Grey", + "SolutionStackName": "64bit Amazon Linux 2015.03 v2.0.0 running Tomcat 8 Java 8", + "Status": "Terminating", + "Tier": { + "Name": "WebServer", + "Type": "Standard", + "Version": " " + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation terminates an Elastic Beanstalk environment named my-env:", + "id": "to-terminate-an-environment-1456277888556", + "title": "To terminate an environment" + } + ], + "UpdateApplication": [ + { + "input": { + "ApplicationName": "my-app", + "Description": "my Elastic Beanstalk application" + }, + "output": { + "Application": { + "ApplicationName": "my-app", + "ConfigurationTemplates": [ + + ], + "DateCreated": "2015-08-13T19:15:50.449Z", + "DateUpdated": "2015-08-20T22:34:56.195Z", + "Description": "my Elastic Beanstalk application", + "Versions": [ + "2fba-stage-150819_234450", + "bf07-stage-150820_214945", + "93f8", + "fd7c-stage-150820_000431", + "22a0-stage-150819_185942" + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation updates the description of an application named my-app:", + "id": "to-change-an-applications-description-1456277957075", + "title": "To change an application's description" + } + ], + "UpdateApplicationVersion": [ + { + "input": { + "ApplicationName": "my-app", + "Description": "new description", + "VersionLabel": "22a0-stage-150819_185942" + }, + "output": { + "ApplicationVersion": { + "ApplicationName": "my-app", + "DateCreated": "2015-08-19T18:59:17.646Z", + "DateUpdated": "2015-08-20T22:53:28.871Z", + "Description": "new description", + "SourceBundle": { + "S3Bucket": "elasticbeanstalk-us-west-2-0123456789012", + "S3Key": "my-app/22a0-stage-150819_185942.war" + }, + "VersionLabel": "22a0-stage-150819_185942" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation updates the description of an application version named 22a0-stage-150819_185942:", + "id": "to-change-an-application-versions-description-1456278019237", + "title": "To change an application version's description" + } + ], + "UpdateConfigurationTemplate": [ + { + "input": { + "ApplicationName": "my-app", + "OptionsToRemove": [ + { + "Namespace": "aws:elasticbeanstalk:healthreporting:system", + "OptionName": "ConfigDocument" + } + ], + "TemplateName": "my-template" + }, + "output": { + "ApplicationName": "my-app", + "DateCreated": "2015-08-20T22:39:31Z", + "DateUpdated": "2015-08-20T22:43:11Z", + "SolutionStackName": "64bit Amazon Linux 2015.03 v2.0.0 running Tomcat 8 Java 8", + "TemplateName": "my-template" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation removes the configured CloudWatch custom health metrics configuration ConfigDocument from a saved configuration template named my-template:", + "id": "to-update-a-configuration-template-1456278075300", + "title": "To update a configuration template" + } + ], + "UpdateEnvironment": [ + { + "input": { + "EnvironmentName": "my-env", + "VersionLabel": "v2" + }, + "output": { + "ApplicationName": "my-app", + "CNAME": "my-env.elasticbeanstalk.com", + "DateCreated": "2015-02-03T23:04:54.453Z", + "DateUpdated": "2015-02-03T23:12:29.119Z", + "EndpointURL": "awseb-e-i-AWSEBLoa-1RDLX6TC9VUAO-0123456789.us-west-2.elb.amazonaws.com", + "EnvironmentId": "e-szqipays4h", + "EnvironmentName": "my-env", + "Health": "Grey", + "SolutionStackName": "64bit Amazon Linux running Tomcat 7", + "Status": "Updating", + "Tier": { + "Name": "WebServer", + "Type": "Standard", + "Version": " " + }, + "VersionLabel": "v2" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation updates an environment named \"my-env\" to version \"v2\" of the application to which it belongs:", + "id": "to-update-an-environment-to-a-new-version-1456278210718", + "title": "To update an environment to a new version" + }, + { + "input": { + "EnvironmentName": "my-env", + "OptionSettings": [ + { + "Namespace": "aws:elb:healthcheck", + "OptionName": "Interval", + "Value": "15" + }, + { + "Namespace": "aws:elb:healthcheck", + "OptionName": "Timeout", + "Value": "8" + }, + { + "Namespace": "aws:elb:healthcheck", + "OptionName": "HealthyThreshold", + "Value": "2" + }, + { + "Namespace": "aws:elb:healthcheck", + "OptionName": "UnhealthyThreshold", + "Value": "3" + } + ] + }, + "output": { + "AbortableOperationInProgress": true, + "ApplicationName": "my-app", + "CNAME": "my-env.elasticbeanstalk.com", + "DateCreated": "2015-08-07T20:48:49.599Z", + "DateUpdated": "2015-08-12T18:15:23.804Z", + "EndpointURL": "awseb-e-w-AWSEBLoa-14XB83101Q4L-104QXY80921.sa-east-1.elb.amazonaws.com", + "EnvironmentId": "e-wtp2rpqsej", + "EnvironmentName": "my-env", + "Health": "Grey", + "SolutionStackName": "64bit Amazon Linux 2015.03 v2.0.0 running Tomcat 8 Java 8", + "Status": "Updating", + "Tier": { + "Name": "WebServer", + "Type": "Standard", + "Version": " " + }, + "VersionLabel": "7f58-stage-150812_025409" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation configures several options in the aws:elb:loadbalancer namespace:", + "id": "to-configure-option-settings-1456278286349", + "title": "To configure option settings" + } + ], + "ValidateConfigurationSettings": [ + { + "input": { + "ApplicationName": "my-app", + "EnvironmentName": "my-env", + "OptionSettings": [ + { + "Namespace": "aws:elasticbeanstalk:healthreporting:system", + "OptionName": "ConfigDocument", + "Value": "{\"CloudWatchMetrics\": {\"Environment\": {\"ApplicationLatencyP99.9\": null,\"InstancesSevere\": 60,\"ApplicationLatencyP90\": 60,\"ApplicationLatencyP99\": null,\"ApplicationLatencyP95\": 60,\"InstancesUnknown\": 60,\"ApplicationLatencyP85\": 60,\"InstancesInfo\": null,\"ApplicationRequests2xx\": null,\"InstancesDegraded\": null,\"InstancesWarning\": 60,\"ApplicationLatencyP50\": 60,\"ApplicationRequestsTotal\": null,\"InstancesNoData\": null,\"InstancesPending\": 60,\"ApplicationLatencyP10\": null,\"ApplicationRequests5xx\": null,\"ApplicationLatencyP75\": null,\"InstancesOk\": 60,\"ApplicationRequests3xx\": null,\"ApplicationRequests4xx\": null},\"Instance\": {\"ApplicationLatencyP99.9\": null,\"ApplicationLatencyP90\": 60,\"ApplicationLatencyP99\": null,\"ApplicationLatencyP95\": null,\"ApplicationLatencyP85\": null,\"CPUUser\": 60,\"ApplicationRequests2xx\": null,\"CPUIdle\": null,\"ApplicationLatencyP50\": null,\"ApplicationRequestsTotal\": 60,\"RootFilesystemUtil\": null,\"LoadAverage1min\": null,\"CPUIrq\": null,\"CPUNice\": 60,\"CPUIowait\": 60,\"ApplicationLatencyP10\": null,\"LoadAverage5min\": null,\"ApplicationRequests5xx\": null,\"ApplicationLatencyP75\": 60,\"CPUSystem\": 60,\"ApplicationRequests3xx\": 60,\"ApplicationRequests4xx\": null,\"InstanceHealth\": null,\"CPUSoftirq\": 60}},\"Version\": 1}" + } + ] + }, + "output": { + "Messages": [ + + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation validates a CloudWatch custom metrics config document:", + "id": "to-validate-configuration-settings-1456278393654", + "title": "To validate configuration settings" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/elasticbeanstalk/2010-12-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/elasticbeanstalk/2010-12-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..4f53c866eb881afb056907e1e79ec9224b1f03fc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/elasticbeanstalk/2010-12-01/paginators-1.json @@ -0,0 +1,34 @@ +{ + "pagination": { + "DescribeEvents": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxRecords", + "result_key": "Events" + }, + "DescribeApplicationVersions": { + "input_token": "NextToken", + "limit_key": "MaxRecords", + "output_token": "NextToken", + "result_key": "ApplicationVersions" + }, + "DescribeEnvironmentManagedActionHistory": { + "input_token": "NextToken", + "limit_key": "MaxItems", + "output_token": "NextToken", + "result_key": "ManagedActionHistoryItems" + }, + "DescribeEnvironments": { + "input_token": "NextToken", + "limit_key": "MaxRecords", + "output_token": "NextToken", + "result_key": "Environments" + }, + "ListPlatformVersions": { + "input_token": "NextToken", + "limit_key": "MaxRecords", + "output_token": "NextToken", + "result_key": "PlatformSummaryList" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/elasticbeanstalk/2010-12-01/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/elasticbeanstalk/2010-12-01/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..4fb906b4f14ba945fc088e96337a35cc23f35499 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/elasticbeanstalk/2010-12-01/waiters-2.json @@ -0,0 +1,63 @@ +{ + "version": 2, + "waiters": { + "EnvironmentExists": { + "delay": 20, + "maxAttempts": 20, + "operation": "DescribeEnvironments", + "acceptors": [ + { + "state": "success", + "matcher": "pathAll", + "argument": "Environments[].Status", + "expected": "Ready" + }, + { + "state": "retry", + "matcher": "pathAll", + "argument": "Environments[].Status", + "expected": "Launching" + } + ] + }, + "EnvironmentUpdated": { + "delay": 20, + "maxAttempts": 20, + "operation": "DescribeEnvironments", + "acceptors": [ + { + "state": "success", + "matcher": "pathAll", + "argument": "Environments[].Status", + "expected": "Ready" + }, + { + "state": "retry", + "matcher": "pathAll", + "argument": "Environments[].Status", + "expected": "Updating" + } + ] + }, + "EnvironmentTerminated": { + "delay": 20, + "maxAttempts": 20, + "operation": "DescribeEnvironments", + "acceptors": [ + { + "state": "success", + "matcher": "pathAll", + "argument": "Environments[].Status", + "expected": "Terminated" + }, + { + "state": "retry", + "matcher": "pathAll", + "argument": "Environments[].Status", + "expected": "Terminating" + } + ] + } + } +} + diff --git a/.venv/lib/python3.13/site-packages/botocore/data/elbv2/2015-12-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/elbv2/2015-12-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..508b0991ca2fbf17cb1b4b65ab2f26f89d09d59b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/elbv2/2015-12-01/examples-1.json @@ -0,0 +1,1384 @@ +{ + "version": "1.0", + "examples": { + "AddTags": [ + { + "input": { + "ResourceArns": [ + "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188" + ], + "Tags": [ + { + "Key": "project", + "Value": "lima" + }, + { + "Key": "department", + "Value": "digital-media" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example adds the specified tags to the specified load balancer.", + "id": "elbv2-add-tags-1", + "title": "To add tags to a load balancer" + } + ], + "CreateListener": [ + { + "input": { + "DefaultActions": [ + { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "Type": "forward" + } + ], + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188", + "Port": 80, + "Protocol": "HTTP" + }, + "output": { + "Listeners": [ + { + "DefaultActions": [ + { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "Type": "forward" + } + ], + "ListenerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2", + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188", + "Port": 80, + "Protocol": "HTTP" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example creates an HTTP listener for the specified load balancer that forwards requests to the specified target group.", + "id": "elbv2-create-listener-1", + "title": "To create an HTTP listener" + }, + { + "input": { + "Certificates": [ + { + "CertificateArn": "arn:aws:iam::123456789012:server-certificate/my-server-cert" + } + ], + "DefaultActions": [ + { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "Type": "forward" + } + ], + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188", + "Port": 443, + "Protocol": "HTTPS", + "SslPolicy": "ELBSecurityPolicy-2015-05" + }, + "output": { + "Listeners": [ + { + "Certificates": [ + { + "CertificateArn": "arn:aws:iam::123456789012:server-certificate/my-server-cert" + } + ], + "DefaultActions": [ + { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "Type": "forward" + } + ], + "ListenerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2", + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188", + "Port": 443, + "Protocol": "HTTPS", + "SslPolicy": "ELBSecurityPolicy-2015-05" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example creates an HTTPS listener for the specified load balancer that forwards requests to the specified target group. Note that you must specify an SSL certificate for an HTTPS listener. You can create and manage certificates using AWS Certificate Manager (ACM). Alternatively, you can create a certificate using SSL/TLS tools, get the certificate signed by a certificate authority (CA), and upload the certificate to AWS Identity and Access Management (IAM).", + "id": "elbv2-create-listener-2", + "title": "To create an HTTPS listener" + } + ], + "CreateLoadBalancer": [ + { + "input": { + "Name": "my-load-balancer", + "Subnets": [ + "subnet-b7d581c0", + "subnet-8360a9e7" + ] + }, + "output": { + "LoadBalancers": [ + { + "AvailabilityZones": [ + { + "SubnetId": "subnet-8360a9e7", + "ZoneName": "us-west-2a" + }, + { + "SubnetId": "subnet-b7d581c0", + "ZoneName": "us-west-2b" + } + ], + "CanonicalHostedZoneId": "Z2P70J7EXAMPLE", + "CreatedTime": "2016-03-25T21:26:12.920Z", + "DNSName": "my-load-balancer-424835706.us-west-2.elb.amazonaws.com", + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188", + "LoadBalancerName": "my-load-balancer", + "Scheme": "internet-facing", + "SecurityGroups": [ + "sg-5943793c" + ], + "State": { + "Code": "provisioning" + }, + "Type": "application", + "VpcId": "vpc-3ac0fb5f" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example creates an Internet-facing load balancer and enables the Availability Zones for the specified subnets.", + "id": "elbv2-create-load-balancer-1", + "title": "To create an Internet-facing load balancer" + }, + { + "input": { + "Name": "my-internal-load-balancer", + "Scheme": "internal", + "SecurityGroups": [ + + ], + "Subnets": [ + "subnet-b7d581c0", + "subnet-8360a9e7" + ] + }, + "output": { + "LoadBalancers": [ + { + "AvailabilityZones": [ + { + "SubnetId": "subnet-8360a9e7", + "ZoneName": "us-west-2a" + }, + { + "SubnetId": "subnet-b7d581c0", + "ZoneName": "us-west-2b" + } + ], + "CanonicalHostedZoneId": "Z2P70J7EXAMPLE", + "CreatedTime": "2016-03-25T21:29:48.850Z", + "DNSName": "internal-my-internal-load-balancer-1529930873.us-west-2.elb.amazonaws.com", + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-internal-load-balancer/5b49b8d4303115c2", + "LoadBalancerName": "my-internal-load-balancer", + "Scheme": "internal", + "SecurityGroups": [ + "sg-5943793c" + ], + "State": { + "Code": "provisioning" + }, + "Type": "application", + "VpcId": "vpc-3ac0fb5f" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example creates an internal load balancer and enables the Availability Zones for the specified subnets.", + "id": "elbv2-create-load-balancer-2", + "title": "To create an internal load balancer" + } + ], + "CreateRule": [ + { + "input": { + "Actions": [ + { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "Type": "forward" + } + ], + "Conditions": [ + { + "Field": "path-pattern", + "Values": [ + "/img/*" + ] + } + ], + "ListenerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2", + "Priority": 10 + }, + "output": { + "Rules": [ + { + "Actions": [ + { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "Type": "forward" + } + ], + "Conditions": [ + { + "Field": "path-pattern", + "Values": [ + "/img/*" + ] + } + ], + "IsDefault": false, + "Priority": "10", + "RuleArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener-rule/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2/9683b2d02a6cabee" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example creates a rule that forwards requests to the specified target group if the URL contains the specified pattern (for example, /img/*).", + "id": "elbv2-create-rule-1", + "title": "To create a rule" + } + ], + "CreateTargetGroup": [ + { + "input": { + "Name": "my-targets", + "Port": 80, + "Protocol": "HTTP", + "VpcId": "vpc-3ac0fb5f" + }, + "output": { + "TargetGroups": [ + { + "HealthCheckIntervalSeconds": 30, + "HealthCheckPath": "/", + "HealthCheckPort": "traffic-port", + "HealthCheckProtocol": "HTTP", + "HealthCheckTimeoutSeconds": 5, + "HealthyThresholdCount": 5, + "Matcher": { + "HttpCode": "200" + }, + "Port": 80, + "Protocol": "HTTP", + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "TargetGroupName": "my-targets", + "UnhealthyThresholdCount": 2, + "VpcId": "vpc-3ac0fb5f" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example creates a target group that you can use to route traffic to targets using HTTP on port 80. This target group uses the default health check configuration.", + "id": "elbv2-create-target-group-1", + "title": "To create a target group" + } + ], + "DeleteListener": [ + { + "input": { + "ListenerArn": "arn:aws:elasticloadbalancing:ua-west-2:123456789012:listener/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deletes the specified listener.", + "id": "elbv2-delete-listener-1", + "title": "To delete a listener" + } + ], + "DeleteLoadBalancer": [ + { + "input": { + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deletes the specified load balancer.", + "id": "elbv2-delete-load-balancer-1", + "title": "To delete a load balancer" + } + ], + "DeleteRule": [ + { + "input": { + "RuleArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener-rule/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2/1291d13826f405c3" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deletes the specified rule.", + "id": "elbv2-delete-rule-1", + "title": "To delete a rule" + } + ], + "DeleteTargetGroup": [ + { + "input": { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deletes the specified target group.", + "id": "elbv2-delete-target-group-1", + "title": "To delete a target group" + } + ], + "DeregisterTargets": [ + { + "input": { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "Targets": [ + { + "Id": "i-0f76fade" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deregisters the specified instance from the specified target group.", + "id": "elbv2-deregister-targets-1", + "title": "To deregister a target from a target group" + } + ], + "DescribeListeners": [ + { + "input": { + "ListenerArns": [ + "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2" + ] + }, + "output": { + "Listeners": [ + { + "DefaultActions": [ + { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "Type": "forward" + } + ], + "ListenerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2", + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188", + "Port": 80, + "Protocol": "HTTP" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the specified listener.", + "id": "elbv2-describe-listeners-1", + "title": "To describe a listener" + } + ], + "DescribeLoadBalancerAttributes": [ + { + "input": { + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188" + }, + "output": { + "Attributes": [ + { + "Key": "access_logs.s3.enabled", + "Value": "false" + }, + { + "Key": "idle_timeout.timeout_seconds", + "Value": "60" + }, + { + "Key": "access_logs.s3.prefix", + "Value": "" + }, + { + "Key": "deletion_protection.enabled", + "Value": "false" + }, + { + "Key": "access_logs.s3.bucket", + "Value": "" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the attributes of the specified load balancer.", + "id": "elbv2-describe-load-balancer-attributes-1", + "title": "To describe load balancer attributes" + } + ], + "DescribeLoadBalancers": [ + { + "input": { + "LoadBalancerArns": [ + "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188" + ] + }, + "output": { + "LoadBalancers": [ + { + "AvailabilityZones": [ + { + "SubnetId": "subnet-8360a9e7", + "ZoneName": "us-west-2a" + }, + { + "SubnetId": "subnet-b7d581c0", + "ZoneName": "us-west-2b" + } + ], + "CanonicalHostedZoneId": "Z2P70J7EXAMPLE", + "CreatedTime": "2016-03-25T21:26:12.920Z", + "DNSName": "my-load-balancer-424835706.us-west-2.elb.amazonaws.com", + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188", + "LoadBalancerName": "my-load-balancer", + "Scheme": "internet-facing", + "SecurityGroups": [ + "sg-5943793c" + ], + "State": { + "Code": "active" + }, + "Type": "application", + "VpcId": "vpc-3ac0fb5f" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the specified load balancer.", + "id": "elbv2-describe-load-balancers-1", + "title": "To describe a load balancer" + } + ], + "DescribeRules": [ + { + "input": { + "RuleArns": [ + "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener-rule/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2/9683b2d02a6cabee" + ] + }, + "output": { + "Rules": [ + { + "Actions": [ + { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "Type": "forward" + } + ], + "Conditions": [ + { + "Field": "path-pattern", + "Values": [ + "/img/*" + ] + } + ], + "IsDefault": false, + "Priority": "10", + "RuleArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener-rule/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2/9683b2d02a6cabee" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the specified rule.", + "id": "elbv2-describe-rules-1", + "title": "To describe a rule" + } + ], + "DescribeSSLPolicies": [ + { + "input": { + "Names": [ + "ELBSecurityPolicy-2015-05" + ] + }, + "output": { + "SslPolicies": [ + { + "Ciphers": [ + { + "Name": "ECDHE-ECDSA-AES128-GCM-SHA256", + "Priority": 1 + }, + { + "Name": "ECDHE-RSA-AES128-GCM-SHA256", + "Priority": 2 + }, + { + "Name": "ECDHE-ECDSA-AES128-SHA256", + "Priority": 3 + }, + { + "Name": "ECDHE-RSA-AES128-SHA256", + "Priority": 4 + }, + { + "Name": "ECDHE-ECDSA-AES128-SHA", + "Priority": 5 + }, + { + "Name": "ECDHE-RSA-AES128-SHA", + "Priority": 6 + }, + { + "Name": "DHE-RSA-AES128-SHA", + "Priority": 7 + }, + { + "Name": "ECDHE-ECDSA-AES256-GCM-SHA384", + "Priority": 8 + }, + { + "Name": "ECDHE-RSA-AES256-GCM-SHA384", + "Priority": 9 + }, + { + "Name": "ECDHE-ECDSA-AES256-SHA384", + "Priority": 10 + }, + { + "Name": "ECDHE-RSA-AES256-SHA384", + "Priority": 11 + }, + { + "Name": "ECDHE-RSA-AES256-SHA", + "Priority": 12 + }, + { + "Name": "ECDHE-ECDSA-AES256-SHA", + "Priority": 13 + }, + { + "Name": "AES128-GCM-SHA256", + "Priority": 14 + }, + { + "Name": "AES128-SHA256", + "Priority": 15 + }, + { + "Name": "AES128-SHA", + "Priority": 16 + }, + { + "Name": "AES256-GCM-SHA384", + "Priority": 17 + }, + { + "Name": "AES256-SHA256", + "Priority": 18 + }, + { + "Name": "AES256-SHA", + "Priority": 19 + } + ], + "Name": "ELBSecurityPolicy-2015-05", + "SslProtocols": [ + "TLSv1", + "TLSv1.1", + "TLSv1.2" + ] + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the specified policy used for SSL negotiation.", + "id": "elbv2-describe-ssl-policies-1", + "title": "To describe a policy used for SSL negotiation" + } + ], + "DescribeTags": [ + { + "input": { + "ResourceArns": [ + "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188" + ] + }, + "output": { + "TagDescriptions": [ + { + "ResourceArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188", + "Tags": [ + { + "Key": "project", + "Value": "lima" + }, + { + "Key": "department", + "Value": "digital-media" + } + ] + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the tags assigned to the specified load balancer.", + "id": "elbv2-describe-tags-1", + "title": "To describe the tags assigned to a load balancer" + } + ], + "DescribeTargetGroupAttributes": [ + { + "input": { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067" + }, + "output": { + "Attributes": [ + { + "Key": "stickiness.enabled", + "Value": "false" + }, + { + "Key": "deregistration_delay.timeout_seconds", + "Value": "300" + }, + { + "Key": "stickiness.type", + "Value": "lb_cookie" + }, + { + "Key": "stickiness.lb_cookie.duration_seconds", + "Value": "86400" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the attributes of the specified target group.", + "id": "elbv2-describe-target-group-attributes-1", + "title": "To describe target group attributes" + } + ], + "DescribeTargetGroups": [ + { + "input": { + "TargetGroupArns": [ + "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067" + ] + }, + "output": { + "TargetGroups": [ + { + "HealthCheckIntervalSeconds": 30, + "HealthCheckPath": "/", + "HealthCheckPort": "traffic-port", + "HealthCheckProtocol": "HTTP", + "HealthCheckTimeoutSeconds": 5, + "HealthyThresholdCount": 5, + "LoadBalancerArns": [ + "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188" + ], + "Matcher": { + "HttpCode": "200" + }, + "Port": 80, + "Protocol": "HTTP", + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "TargetGroupName": "my-targets", + "UnhealthyThresholdCount": 2, + "VpcId": "vpc-3ac0fb5f" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the specified target group.", + "id": "elbv2-describe-target-groups-1", + "title": "To describe a target group" + } + ], + "DescribeTargetHealth": [ + { + "input": { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067" + }, + "output": { + "TargetHealthDescriptions": [ + { + "Target": { + "Id": "i-0f76fade", + "Port": 80 + }, + "TargetHealth": { + "Description": "Given target group is not configured to receive traffic from ELB", + "Reason": "Target.NotInUse", + "State": "unused" + } + }, + { + "HealthCheckPort": "80", + "Target": { + "Id": "i-0f76fade", + "Port": 80 + }, + "TargetHealth": { + "State": "healthy" + } + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the health of the targets for the specified target group. One target is healthy but the other is not specified in an action, so it can't receive traffic from the load balancer.", + "id": "elbv2-describe-target-health-1", + "title": "To describe the health of the targets for a target group" + }, + { + "input": { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "Targets": [ + { + "Id": "i-0f76fade", + "Port": 80 + } + ] + }, + "output": { + "TargetHealthDescriptions": [ + { + "HealthCheckPort": "80", + "Target": { + "Id": "i-0f76fade", + "Port": 80 + }, + "TargetHealth": { + "State": "healthy" + } + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example describes the health of the specified target. This target is healthy.", + "id": "elbv2-describe-target-health-2", + "title": "To describe the health of a target" + } + ], + "ModifyListener": [ + { + "input": { + "DefaultActions": [ + { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-new-targets/2453ed029918f21f", + "Type": "forward" + } + ], + "ListenerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2" + }, + "output": { + "Listeners": [ + { + "DefaultActions": [ + { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-new-targets/2453ed029918f21f", + "Type": "forward" + } + ], + "ListenerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2", + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188", + "Port": 80, + "Protocol": "HTTP" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example changes the default action for the specified listener.", + "id": "elbv2-modify-listener-1", + "title": "To change the default action for a listener" + }, + { + "input": { + "Certificates": [ + { + "CertificateArn": "arn:aws:iam::123456789012:server-certificate/my-new-server-cert" + } + ], + "ListenerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener/app/my-load-balancer/50dc6c495c0c9188/0467ef3c8400ae65" + }, + "output": { + "Listeners": [ + { + "Certificates": [ + { + "CertificateArn": "arn:aws:iam::123456789012:server-certificate/my-new-server-cert" + } + ], + "DefaultActions": [ + { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "Type": "forward" + } + ], + "ListenerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener/app/my-load-balancer/50dc6c495c0c9188/0467ef3c8400ae65", + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188", + "Port": 443, + "Protocol": "HTTPS", + "SslPolicy": "ELBSecurityPolicy-2015-05" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example changes the server certificate for the specified HTTPS listener.", + "id": "elbv2-modify-listener-2", + "title": "To change the server certificate" + } + ], + "ModifyLoadBalancerAttributes": [ + { + "input": { + "Attributes": [ + { + "Key": "deletion_protection.enabled", + "Value": "true" + } + ], + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188" + }, + "output": { + "Attributes": [ + { + "Key": "deletion_protection.enabled", + "Value": "true" + }, + { + "Key": "access_logs.s3.enabled", + "Value": "false" + }, + { + "Key": "idle_timeout.timeout_seconds", + "Value": "60" + }, + { + "Key": "access_logs.s3.prefix", + "Value": "" + }, + { + "Key": "access_logs.s3.bucket", + "Value": "" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example enables deletion protection for the specified load balancer.", + "id": "elbv2-modify-load-balancer-attributes-1", + "title": "To enable deletion protection" + }, + { + "input": { + "Attributes": [ + { + "Key": "idle_timeout.timeout_seconds", + "Value": "30" + } + ], + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188" + }, + "output": { + "Attributes": [ + { + "Key": "idle_timeout.timeout_seconds", + "Value": "30" + }, + { + "Key": "access_logs.s3.enabled", + "Value": "false" + }, + { + "Key": "access_logs.s3.prefix", + "Value": "" + }, + { + "Key": "deletion_protection.enabled", + "Value": "true" + }, + { + "Key": "access_logs.s3.bucket", + "Value": "" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example changes the idle timeout value for the specified load balancer.", + "id": "elbv2-modify-load-balancer-attributes-2", + "title": "To change the idle timeout" + }, + { + "input": { + "Attributes": [ + { + "Key": "access_logs.s3.enabled", + "Value": "true" + }, + { + "Key": "access_logs.s3.bucket", + "Value": "my-loadbalancer-logs" + }, + { + "Key": "access_logs.s3.prefix", + "Value": "myapp" + } + ], + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188" + }, + "output": { + "Attributes": [ + { + "Key": "access_logs.s3.enabled", + "Value": "true" + }, + { + "Key": "access_logs.s3.bucket", + "Value": "my-load-balancer-logs" + }, + { + "Key": "access_logs.s3.prefix", + "Value": "myapp" + }, + { + "Key": "idle_timeout.timeout_seconds", + "Value": "60" + }, + { + "Key": "deletion_protection.enabled", + "Value": "false" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example enables access logs for the specified load balancer. Note that the S3 bucket must exist in the same region as the load balancer and must have a policy attached that grants access to the Elastic Load Balancing service.", + "id": "elbv2-modify-load-balancer-attributes-3", + "title": "To enable access logs" + } + ], + "ModifyRule": [ + { + "input": { + "Conditions": [ + { + "Field": "path-pattern", + "Values": [ + "/images/*" + ] + } + ], + "RuleArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener-rule/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2/9683b2d02a6cabee" + }, + "output": { + "Rules": [ + { + "Actions": [ + { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "Type": "forward" + } + ], + "Conditions": [ + { + "Field": "path-pattern", + "Values": [ + "/images/*" + ] + } + ], + "IsDefault": false, + "Priority": "10", + "RuleArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener-rule/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2/9683b2d02a6cabee" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example modifies the condition for the specified rule.", + "id": "elbv2-modify-rule-1", + "title": "To modify a rule" + } + ], + "ModifyTargetGroup": [ + { + "input": { + "HealthCheckPort": "443", + "HealthCheckProtocol": "HTTPS", + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-https-targets/2453ed029918f21f" + }, + "output": { + "TargetGroups": [ + { + "HealthCheckIntervalSeconds": 30, + "HealthCheckPort": "443", + "HealthCheckProtocol": "HTTPS", + "HealthCheckTimeoutSeconds": 5, + "HealthyThresholdCount": 5, + "LoadBalancerArns": [ + "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188" + ], + "Matcher": { + "HttpCode": "200" + }, + "Port": 443, + "Protocol": "HTTPS", + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-https-targets/2453ed029918f21f", + "TargetGroupName": "my-https-targets", + "UnhealthyThresholdCount": 2, + "VpcId": "vpc-3ac0fb5f" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example changes the configuration of the health checks used to evaluate the health of the targets for the specified target group.", + "id": "elbv2-modify-target-group-1", + "title": "To modify the health check configuration for a target group" + } + ], + "ModifyTargetGroupAttributes": [ + { + "input": { + "Attributes": [ + { + "Key": "deregistration_delay.timeout_seconds", + "Value": "600" + } + ], + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067" + }, + "output": { + "Attributes": [ + { + "Key": "stickiness.enabled", + "Value": "false" + }, + { + "Key": "deregistration_delay.timeout_seconds", + "Value": "600" + }, + { + "Key": "stickiness.type", + "Value": "lb_cookie" + }, + { + "Key": "stickiness.lb_cookie.duration_seconds", + "Value": "86400" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example sets the deregistration delay timeout to the specified value for the specified target group.", + "id": "elbv2-modify-target-group-attributes-1", + "title": "To modify the deregistration delay timeout" + } + ], + "RegisterTargets": [ + { + "input": { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "Targets": [ + { + "Id": "i-80c8dd94" + }, + { + "Id": "i-ceddcd4d" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example registers the specified instances with the specified target group.", + "id": "elbv2-register-targets-1", + "title": "To register targets with a target group" + }, + { + "input": { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-new-targets/3bb63f11dfb0faf9", + "Targets": [ + { + "Id": "i-80c8dd94", + "Port": 80 + }, + { + "Id": "i-80c8dd94", + "Port": 766 + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example registers the specified instance with the specified target group using multiple ports. This enables you to register ECS containers on the same instance as targets in the target group.", + "id": "elbv2-register-targets-2", + "title": "To register targets with a target group using port overrides" + } + ], + "RemoveTags": [ + { + "input": { + "ResourceArns": [ + "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188" + ], + "TagKeys": [ + "project", + "department" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example removes the specified tags from the specified load balancer.", + "id": "elbv2-remove-tags-1", + "title": "To remove tags from a load balancer" + } + ], + "SetRulePriorities": [ + { + "input": { + "RulePriorities": [ + { + "Priority": 5, + "RuleArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener-rule/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2/1291d13826f405c3" + } + ] + }, + "output": { + "Rules": [ + { + "Actions": [ + { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067", + "Type": "forward" + } + ], + "Conditions": [ + { + "Field": "path-pattern", + "Values": [ + "/img/*" + ] + } + ], + "IsDefault": false, + "Priority": "5", + "RuleArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener-rule/app/my-load-balancer/50dc6c495c0c9188/f2f7dc8efc522ab2/1291d13826f405c3" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example sets the priority of the specified rule.", + "id": "elbv2-set-rule-priorities-1", + "title": "To set the rule priority" + } + ], + "SetSecurityGroups": [ + { + "input": { + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188", + "SecurityGroups": [ + "sg-5943793c" + ] + }, + "output": { + "SecurityGroupIds": [ + "sg-5943793c" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example associates the specified security group with the specified load balancer.", + "id": "elbv2-set-security-groups-1", + "title": "To associate a security group with a load balancer" + } + ], + "SetSubnets": [ + { + "input": { + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188", + "Subnets": [ + "subnet-8360a9e7", + "subnet-b7d581c0" + ] + }, + "output": { + "AvailabilityZones": [ + { + "SubnetId": "subnet-8360a9e7", + "ZoneName": "us-west-2a" + }, + { + "SubnetId": "subnet-b7d581c0", + "ZoneName": "us-west-2b" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example enables the Availability Zones for the specified subnets for the specified load balancer.", + "id": "elbv2-set-subnets-1", + "title": "To enable Availability Zones for a load balancer" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/elbv2/2015-12-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/elbv2/2015-12-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..a8e8468717282d486e271cc4de3f4a68a3184d0a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/elbv2/2015-12-01/paginators-1.json @@ -0,0 +1,64 @@ +{ + "pagination": { + "DescribeLoadBalancers": { + "input_token": "Marker", + "output_token": "NextMarker", + "limit_key": "PageSize", + "result_key": "LoadBalancers" + }, + "DescribeTargetGroups": { + "input_token": "Marker", + "output_token": "NextMarker", + "limit_key": "PageSize", + "result_key": "TargetGroups" + }, + "DescribeListeners": { + "input_token": "Marker", + "output_token": "NextMarker", + "limit_key": "PageSize", + "result_key": "Listeners" + }, + "DescribeAccountLimits": { + "input_token": "Marker", + "limit_key": "PageSize", + "output_token": "NextMarker", + "result_key": "Limits" + }, + "DescribeListenerCertificates": { + "input_token": "Marker", + "limit_key": "PageSize", + "output_token": "NextMarker", + "result_key": "Certificates" + }, + "DescribeRules": { + "input_token": "Marker", + "limit_key": "PageSize", + "output_token": "NextMarker", + "result_key": "Rules" + }, + "DescribeSSLPolicies": { + "input_token": "Marker", + "limit_key": "PageSize", + "output_token": "NextMarker", + "result_key": "SslPolicies" + }, + "DescribeTrustStoreAssociations": { + "input_token": "Marker", + "limit_key": "PageSize", + "output_token": "NextMarker", + "result_key": "TrustStoreAssociations" + }, + "DescribeTrustStoreRevocations": { + "input_token": "Marker", + "limit_key": "PageSize", + "output_token": "NextMarker", + "result_key": "TrustStoreRevocations" + }, + "DescribeTrustStores": { + "input_token": "Marker", + "limit_key": "PageSize", + "output_token": "NextMarker", + "result_key": "TrustStores" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/elbv2/2015-12-01/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/elbv2/2015-12-01/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..9f3d77d828fa2b429137e1c224fbef47d6b6d02f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/elbv2/2015-12-01/waiters-2.json @@ -0,0 +1,100 @@ +{ + "version": 2, + "waiters": { + "LoadBalancerExists": { + "delay": 15, + "operation": "DescribeLoadBalancers", + "maxAttempts": 40, + "acceptors": [ + { + "matcher": "status", + "expected": 200, + "state": "success" + }, + { + "matcher": "error", + "expected": "LoadBalancerNotFound", + "state": "retry" + } + ] + }, + "LoadBalancerAvailable": { + "delay": 15, + "operation": "DescribeLoadBalancers", + "maxAttempts": 40, + "acceptors": [ + { + "state": "success", + "matcher": "pathAll", + "argument": "LoadBalancers[].State.Code", + "expected": "active" + }, + { + "state": "retry", + "matcher": "pathAny", + "argument": "LoadBalancers[].State.Code", + "expected": "provisioning" + }, + { + "state": "retry", + "matcher": "error", + "expected": "LoadBalancerNotFound" + } + ] + }, + "LoadBalancersDeleted": { + "delay": 15, + "operation": "DescribeLoadBalancers", + "maxAttempts": 40, + "acceptors": [ + { + "state": "retry", + "matcher": "pathAll", + "argument": "LoadBalancers[].State.Code", + "expected": "active" + }, + { + "matcher": "error", + "expected": "LoadBalancerNotFound", + "state": "success" + } + ] + }, + "TargetInService":{ + "delay":15, + "maxAttempts":40, + "operation":"DescribeTargetHealth", + "acceptors":[ + { + "argument":"TargetHealthDescriptions[].TargetHealth.State", + "expected":"healthy", + "matcher":"pathAll", + "state":"success" + }, + { + "matcher": "error", + "expected": "InvalidInstance", + "state": "retry" + } + ] + }, + "TargetDeregistered": { + "delay": 15, + "maxAttempts": 40, + "operation": "DescribeTargetHealth", + "acceptors": [ + { + "matcher": "error", + "expected": "InvalidTarget", + "state": "success" + }, + { + "argument":"TargetHealthDescriptions[].TargetHealth.State", + "expected":"unused", + "matcher":"pathAll", + "state":"success" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/emr-containers/2020-10-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/emr-containers/2020-10-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/emr-containers/2020-10-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/emr-containers/2020-10-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/emr-containers/2020-10-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..c21db2de34797938fcfb7730782c355a765e9588 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/emr-containers/2020-10-01/paginators-1.json @@ -0,0 +1,34 @@ +{ + "pagination": { + "ListJobRuns": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "jobRuns" + }, + "ListManagedEndpoints": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "endpoints" + }, + "ListVirtualClusters": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "virtualClusters" + }, + "ListJobTemplates": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "templates" + }, + "ListSecurityConfigurations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "securityConfigurations" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/emr/2009-03-31/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/emr/2009-03-31/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/emr/2009-03-31/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/emr/2009-03-31/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/emr/2009-03-31/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..447759f158c5488dfea768509cad25360503fb4e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/emr/2009-03-31/paginators-1.json @@ -0,0 +1,54 @@ +{ + "pagination": { + "ListBootstrapActions": { + "input_token": "Marker", + "output_token": "Marker", + "result_key": "BootstrapActions" + }, + "ListClusters": { + "input_token": "Marker", + "output_token": "Marker", + "result_key": "Clusters" + }, + "ListInstanceGroups": { + "input_token": "Marker", + "output_token": "Marker", + "result_key": "InstanceGroups" + }, + "ListInstances": { + "input_token": "Marker", + "output_token": "Marker", + "result_key": "Instances" + }, + "ListSteps": { + "input_token": "Marker", + "output_token": "Marker", + "result_key": "Steps" + }, + "ListInstanceFleets": { + "input_token": "Marker", + "output_token": "Marker", + "result_key": "InstanceFleets" + }, + "ListSecurityConfigurations": { + "input_token": "Marker", + "output_token": "Marker", + "result_key": "SecurityConfigurations" + }, + "ListNotebookExecutions": { + "input_token": "Marker", + "output_token": "Marker", + "result_key": "NotebookExecutions" + }, + "ListStudioSessionMappings": { + "input_token": "Marker", + "output_token": "Marker", + "result_key": "SessionMappings" + }, + "ListStudios": { + "input_token": "Marker", + "output_token": "Marker", + "result_key": "Studios" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/emr/2009-03-31/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/emr/2009-03-31/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..abba8c3c29d20beb37fff177e48f3e28c844bc5c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/emr/2009-03-31/waiters-2.json @@ -0,0 +1,86 @@ +{ + "version": 2, + "waiters": { + "ClusterRunning": { + "delay": 30, + "operation": "DescribeCluster", + "maxAttempts": 60, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "Cluster.Status.State", + "expected": "RUNNING" + }, + { + "state": "success", + "matcher": "path", + "argument": "Cluster.Status.State", + "expected": "WAITING" + }, + { + "state": "failure", + "matcher": "path", + "argument": "Cluster.Status.State", + "expected": "TERMINATING" + }, + { + "state": "failure", + "matcher": "path", + "argument": "Cluster.Status.State", + "expected": "TERMINATED" + }, + { + "state": "failure", + "matcher": "path", + "argument": "Cluster.Status.State", + "expected": "TERMINATED_WITH_ERRORS" + } + ] + }, + "StepComplete": { + "delay": 30, + "operation": "DescribeStep", + "maxAttempts": 60, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "Step.Status.State", + "expected": "COMPLETED" + }, + { + "state": "failure", + "matcher": "path", + "argument": "Step.Status.State", + "expected": "FAILED" + }, + { + "state": "failure", + "matcher": "path", + "argument": "Step.Status.State", + "expected": "CANCELLED" + } + ] + }, + "ClusterTerminated": { + "delay": 30, + "operation": "DescribeCluster", + "maxAttempts": 60, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "Cluster.Status.State", + "expected": "TERMINATED" + }, + { + "state": "failure", + "matcher": "path", + "argument": "Cluster.Status.State", + "expected": "TERMINATED_WITH_ERRORS" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/endpoints.json b/.venv/lib/python3.13/site-packages/botocore/data/endpoints.json new file mode 100644 index 0000000000000000000000000000000000000000..ec9f1a2fd0cf69acd2a686e2640d0d9775606065 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/endpoints.json @@ -0,0 +1,40725 @@ +{ + "partitions" : [ { + "defaults" : { + "hostname" : "{service}.{region}.{dnsSuffix}", + "protocols" : [ "https" ], + "signatureVersions" : [ "v4" ], + "variants" : [ { + "dnsSuffix" : "amazonaws.com", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + }, { + "dnsSuffix" : "api.aws", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "dualstack", "fips" ] + }, { + "dnsSuffix" : "api.aws", + "hostname" : "{service}.{region}.{dnsSuffix}", + "tags" : [ "dualstack" ] + } ] + }, + "dnsSuffix" : "amazonaws.com", + "partition" : "aws", + "partitionName" : "AWS Standard", + "regionRegex" : "^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$", + "regions" : { + "af-south-1" : { + "description" : "Africa (Cape Town)" + }, + "ap-east-1" : { + "description" : "Asia Pacific (Hong Kong)" + }, + "ap-east-2" : { + "description" : "Asia Pacific (Taipei)" + }, + "ap-northeast-1" : { + "description" : "Asia Pacific (Tokyo)" + }, + "ap-northeast-2" : { + "description" : "Asia Pacific (Seoul)" + }, + "ap-northeast-3" : { + "description" : "Asia Pacific (Osaka)" + }, + "ap-south-1" : { + "description" : "Asia Pacific (Mumbai)" + }, + "ap-south-2" : { + "description" : "Asia Pacific (Hyderabad)" + }, + "ap-southeast-1" : { + "description" : "Asia Pacific (Singapore)" + }, + "ap-southeast-2" : { + "description" : "Asia Pacific (Sydney)" + }, + "ap-southeast-3" : { + "description" : "Asia Pacific (Jakarta)" + }, + "ap-southeast-4" : { + "description" : "Asia Pacific (Melbourne)" + }, + "ap-southeast-5" : { + "description" : "Asia Pacific (Malaysia)" + }, + "ap-southeast-6" : { + "description" : "Asia Pacific (New Zealand)" + }, + "ap-southeast-7" : { + "description" : "Asia Pacific (Thailand)" + }, + "ca-central-1" : { + "description" : "Canada (Central)" + }, + "ca-west-1" : { + "description" : "Canada West (Calgary)" + }, + "eu-central-1" : { + "description" : "Europe (Frankfurt)" + }, + "eu-central-2" : { + "description" : "Europe (Zurich)" + }, + "eu-north-1" : { + "description" : "Europe (Stockholm)" + }, + "eu-south-1" : { + "description" : "Europe (Milan)" + }, + "eu-south-2" : { + "description" : "Europe (Spain)" + }, + "eu-west-1" : { + "description" : "Europe (Ireland)" + }, + "eu-west-2" : { + "description" : "Europe (London)" + }, + "eu-west-3" : { + "description" : "Europe (Paris)" + }, + "il-central-1" : { + "description" : "Israel (Tel Aviv)" + }, + "me-central-1" : { + "description" : "Middle East (UAE)" + }, + "me-south-1" : { + "description" : "Middle East (Bahrain)" + }, + "mx-central-1" : { + "description" : "Mexico (Central)" + }, + "sa-east-1" : { + "description" : "South America (Sao Paulo)" + }, + "us-east-1" : { + "description" : "US East (N. Virginia)" + }, + "us-east-2" : { + "description" : "US East (Ohio)" + }, + "us-west-1" : { + "description" : "US West (N. California)" + }, + "us-west-2" : { + "description" : "US West (Oregon)" + } + }, + "services" : { + "access-analyzer" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "access-analyzer.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "access-analyzer.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "access-analyzer.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "access-analyzer.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "access-analyzer.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "access-analyzer.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "access-analyzer.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "access-analyzer.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "access-analyzer.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "access-analyzer.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "access-analyzer.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "access-analyzer.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "access-analyzer.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "access-analyzer-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "access-analyzer-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "access-analyzer.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "access-analyzer-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "access-analyzer-fips.ca-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "access-analyzer.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "access-analyzer.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "access-analyzer.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "access-analyzer.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "access-analyzer.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "access-analyzer.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "access-analyzer.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "access-analyzer.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "access-analyzer.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "access-analyzer-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "access-analyzer-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "access-analyzer-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "access-analyzer-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "access-analyzer-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "access-analyzer-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "access-analyzer.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "access-analyzer.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "access-analyzer.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "access-analyzer.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "access-analyzer.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "access-analyzer-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "access-analyzer-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "access-analyzer.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "access-analyzer-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "access-analyzer-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "access-analyzer.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "access-analyzer-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "access-analyzer-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "access-analyzer.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "access-analyzer-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "access-analyzer-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "access-analyzer.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "account" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "account.us-east-1.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "acm" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "acm-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "acm-fips.ca-central-1.amazonaws.com" + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "acm-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1-fips" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "acm-fips.ca-west-1.amazonaws.com" + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "acm-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "acm-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "acm-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "acm-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "acm-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "acm-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "acm-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "acm-fips.us-west-2.amazonaws.com" + } + } + }, + "acm-pca" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "acm-pca-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "acm-pca-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "acm-pca-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "acm-pca-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "acm-pca-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "acm-pca-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "acm-pca-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "acm-pca-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "acm-pca-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "acm-pca-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "acm-pca-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "acm-pca-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "agreement-marketplace" : { + "endpoints" : { + "us-east-1" : { + "variants" : [ { + "hostname" : "agreement-marketplace.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "airflow" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "amplify" : { + "endpoints" : { + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "amplifybackend" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "amplifyuibuilder" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "aoss" : { + "endpoints" : { + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "api.detective" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "detective.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "detective.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "detective.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "detective.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "detective.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "detective.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "detective.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "api.detective-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "detective-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "detective.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "api.detective-fips.ca-central-1.amazonaws.com" + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "detective.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "detective.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "detective.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "detective.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "detective.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "detective.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "detective.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "detective.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "detective.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "api.detective-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "detective-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "detective.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "api.detective-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "api.detective-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "detective-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "detective.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "api.detective-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "api.detective-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "detective-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "detective.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "api.detective-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "api.detective-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "detective-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "detective.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "api.detective-fips.us-west-2.amazonaws.com" + } + } + }, + "api.ecr" : { + "defaults" : { + "variants" : [ { + "hostname" : "ecr-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "af-south-1" : { + "credentialScope" : { + "region" : "af-south-1" + }, + "hostname" : "api.ecr.af-south-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "credentialScope" : { + "region" : "ap-east-1" + }, + "hostname" : "api.ecr.ap-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "api.ecr.ap-northeast-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "hostname" : "api.ecr.ap-northeast-2.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "credentialScope" : { + "region" : "ap-northeast-3" + }, + "hostname" : "api.ecr.ap-northeast-3.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "hostname" : "api.ecr.ap-south-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "credentialScope" : { + "region" : "ap-south-2" + }, + "hostname" : "api.ecr.ap-south-2.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "api.ecr.ap-southeast-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "api.ecr.ap-southeast-2.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "credentialScope" : { + "region" : "ap-southeast-3" + }, + "hostname" : "api.ecr.ap-southeast-3.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "credentialScope" : { + "region" : "ap-southeast-4" + }, + "hostname" : "api.ecr.ap-southeast-4.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "credentialScope" : { + "region" : "ap-southeast-5" + }, + "hostname" : "api.ecr.ap-southeast-5.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "credentialScope" : { + "region" : "ap-southeast-7" + }, + "hostname" : "api.ecr.ap-southeast-7.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "hostname" : "api.ecr.ca-central-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "hostname" : "api.ecr.ca-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "dkr-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "ecr-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "dkr-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "ecr-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "dkr-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "ecr-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "dkr-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "ecr-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "api.ecr.eu-central-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "credentialScope" : { + "region" : "eu-central-2" + }, + "hostname" : "api.ecr.eu-central-2.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "credentialScope" : { + "region" : "eu-north-1" + }, + "hostname" : "api.ecr.eu-north-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "credentialScope" : { + "region" : "eu-south-1" + }, + "hostname" : "api.ecr.eu-south-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "credentialScope" : { + "region" : "eu-south-2" + }, + "hostname" : "api.ecr.eu-south-2.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "api.ecr.eu-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "hostname" : "api.ecr.eu-west-2.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "hostname" : "api.ecr.eu-west-3.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-dkr-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "ecr-fips.us-east-1.amazonaws.com" + }, + "fips-dkr-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "ecr-fips.us-east-2.amazonaws.com" + }, + "fips-dkr-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "ecr-fips.us-west-1.amazonaws.com" + }, + "fips-dkr-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "ecr-fips.us-west-2.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "ecr-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "ecr-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "ecr-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "ecr-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "credentialScope" : { + "region" : "il-central-1" + }, + "hostname" : "api.ecr.il-central-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "credentialScope" : { + "region" : "me-central-1" + }, + "hostname" : "api.ecr.me-central-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "credentialScope" : { + "region" : "me-south-1" + }, + "hostname" : "api.ecr.me-south-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "credentialScope" : { + "region" : "mx-central-1" + }, + "hostname" : "api.ecr.mx-central-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "hostname" : "api.ecr.sa-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "api.ecr.us-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ecr-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "ecr.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "api.ecr.us-east-2.amazonaws.com", + "variants" : [ { + "hostname" : "ecr-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ecr-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "ecr.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "hostname" : "api.ecr.us-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ecr-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "ecr.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "api.ecr.us-west-2.amazonaws.com", + "variants" : [ { + "hostname" : "ecr-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ecr-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "ecr.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "api.ecr-public" : { + "endpoints" : { + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "api.ecr-public.us-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr-public.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "api.ecr-public.us-west-2.amazonaws.com" + } + } + }, + "api.iotdeviceadvisor" : { + "endpoints" : { + "ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "api.iotdeviceadvisor.ap-northeast-1.amazonaws.com" + }, + "eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "api.iotdeviceadvisor.eu-west-1.amazonaws.com" + }, + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "api.iotdeviceadvisor.us-east-1.amazonaws.com" + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "api.iotdeviceadvisor.us-west-2.amazonaws.com" + } + } + }, + "api.iotwireless" : { + "endpoints" : { + "ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "api.iotwireless.ap-northeast-1.amazonaws.com" + }, + "ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "api.iotwireless.ap-southeast-2.amazonaws.com" + }, + "eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "api.iotwireless.eu-central-1.amazonaws.com" + }, + "eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "api.iotwireless.eu-west-1.amazonaws.com" + }, + "sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "hostname" : "api.iotwireless.sa-east-1.amazonaws.com" + }, + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "api.iotwireless.us-east-1.amazonaws.com" + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "api.iotwireless.us-west-2.amazonaws.com" + } + } + }, + "api.mediatailor" : { + "endpoints" : { + "af-south-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-4" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-3" : { }, + "me-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "api.pricing" : { + "defaults" : { + "credentialScope" : { + "service" : "pricing" + } + }, + "endpoints" : { + "ap-south-1" : { }, + "eu-central-1" : { }, + "us-east-1" : { } + } + }, + "api.sagemaker" : { + "defaults" : { + "variants" : [ { + "hostname" : "api-fips.sagemaker.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "api-fips.sagemaker.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "api-fips.sagemaker.ca-central-1.amazonaws.com" + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "api-fips.sagemaker.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1-fips" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "api-fips.sagemaker.ca-west-1.amazonaws.com" + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "api-fips.sagemaker.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "api-fips.sagemaker.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "api-fips.sagemaker.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "api-fips.sagemaker.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "api-fips.sagemaker.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "api-fips.sagemaker.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "api-fips.sagemaker.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "api-fips.sagemaker.us-west-2.amazonaws.com" + } + } + }, + "api.tunneling.iot" : { + "defaults" : { + "variants" : [ { + "dnsSuffix" : "amazonaws.com", + "hostname" : "api.tunneling.iot-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + }, { + "dnsSuffix" : "api.aws", + "hostname" : "api.iot-tunneling-fips.{region}.{dnsSuffix}", + "tags" : [ "dualstack", "fips" ] + }, { + "dnsSuffix" : "api.aws", + "hostname" : "api.iot-tunneling.{region}.{dnsSuffix}", + "tags" : [ "dualstack" ] + } ] + }, + "endpoints" : { + "ap-east-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "api.iot-tunneling.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "api.iot-tunneling.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "api.iot-tunneling.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "api.tunneling.iot-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "api.iot-tunneling.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "api.iot-tunneling.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "api.tunneling.iot-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "api.tunneling.iot-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "api.tunneling.iot-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "api.tunneling.iot-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "api.tunneling.iot-fips.us-west-2.amazonaws.com" + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "api.iot-tunneling.us-east-1.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "api.tunneling.iot-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "api.iot-tunneling-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "api.iot-tunneling.us-east-2.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "api.tunneling.iot-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "api.iot-tunneling.us-west-1.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "api.tunneling.iot-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "api.iot-tunneling-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "api.iot-tunneling.us-west-2.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "api.tunneling.iot-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "apigateway" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "apigateway-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "apigateway-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "apigateway-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "apigateway-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "apigateway-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "apigateway-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "apigateway-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "apigateway-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "apigateway-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "apigateway-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "apigateway-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "apigateway-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "app-integrations" : { + "endpoints" : { + "af-south-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "appconfig" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "appconfigdata" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "appflow" : { + "endpoints" : { + "af-south-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "appflow-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "appflow-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "appflow-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "appflow-fips.us-west-2.amazonaws.com" + }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "appflow-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "appflow-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "appflow-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "appflow-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "application-autoscaling" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "applicationinsights" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "applicationinsights.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "applicationinsights.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "applicationinsights.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "applicationinsights.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "applicationinsights.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "applicationinsights.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "applicationinsights.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "applicationinsights.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "applicationinsights.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "applicationinsights.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "applicationinsights.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "applicationinsights-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "applicationinsights-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "applicationinsights.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "applicationinsights-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "applicationinsights-fips.ca-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "applicationinsights.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "applicationinsights.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "applicationinsights.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "applicationinsights.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "applicationinsights.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "applicationinsights.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "applicationinsights.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "applicationinsights.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "applicationinsights.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "applicationinsights-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "applicationinsights-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "applicationinsights-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "applicationinsights-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "applicationinsights-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "applicationinsights-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "applicationinsights.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "applicationinsights.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "applicationinsights.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "applicationinsights.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "applicationinsights-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "applicationinsights-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "applicationinsights.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "applicationinsights-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "applicationinsights-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "applicationinsights.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "applicationinsights-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "applicationinsights-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "applicationinsights.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "applicationinsights-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "applicationinsights-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "applicationinsights.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "appmesh" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "appmesh.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "appmesh.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "appmesh.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "appmesh.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "appmesh.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "appmesh.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "appmesh.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "appmesh.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "appmesh.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "appmesh-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "appmesh-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "appmesh.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "appmesh-fips.ca-central-1.amazonaws.com" + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "appmesh.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "appmesh.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "appmesh.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "appmesh.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "appmesh.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "appmesh.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "appmesh.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "appmesh.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "appmesh.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "appmesh.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "appmesh.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "appmesh-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "appmesh-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "appmesh.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "appmesh-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "appmesh-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "appmesh-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "appmesh.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "appmesh-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "appmesh-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "appmesh-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "appmesh.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "appmesh-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "appmesh-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "appmesh-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "appmesh.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "appmesh-fips.us-west-2.amazonaws.com" + } + } + }, + "apprunner" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "apprunner-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "apprunner-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "apprunner-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "apprunner-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "apprunner-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "apprunner-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "appstream2" : { + "defaults" : { + "credentialScope" : { + "service" : "appstream" + }, + "protocols" : [ "https" ] + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-5" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "appstream2-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "appstream2-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "appstream2-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { }, + "us-west-2" : { + "variants" : [ { + "hostname" : "appstream2-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "appstream2-fips.us-west-2.amazonaws.com" + } + } + }, + "appsync" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "appsync.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "appsync.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "appsync.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "appsync.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "appsync.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "appsync.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "appsync.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "appsync.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "appsync.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "appsync.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "appsync.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "appsync.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "appsync.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "appsync.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "appsync.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "appsync.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "appsync.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "appsync.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "appsync.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "appsync.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "appsync.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "appsync.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "appsync.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "appsync.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "appsync.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "appsync.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "appsync.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "appsync.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "aps" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { }, + "ap-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { }, + "ap-southeast-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { }, + "eu-north-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "deprecated" : true + }, + "us-east-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "deprecated" : true + }, + "us-west-1" : { }, + "us-west-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "deprecated" : true + } + } + }, + "arc-zonal-shift" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "athena" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "athena.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "athena.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "athena.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "athena.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "athena.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "athena.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "athena.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "athena.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "athena.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "athena.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "athena.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "athena.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "athena-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "athena-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "athena.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "athena-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "athena-fips.ca-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "athena.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "athena.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "athena.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "athena.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "athena.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "athena.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "athena.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "athena.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "athena.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "athena-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "athena-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "athena-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "athena-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "athena-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "athena-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "athena.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "athena.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "athena.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "athena.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "athena-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "athena-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "athena.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "athena-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "athena-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "athena.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "athena-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "athena-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "athena.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "athena-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "athena-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "athena.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "auditmanager" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "auditmanager-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "auditmanager-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "auditmanager-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "auditmanager-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "auditmanager-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "auditmanager-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "auditmanager-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "auditmanager-fips.us-west-2.amazonaws.com" + } + } + }, + "autoscaling" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "autoscaling-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "autoscaling-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "autoscaling-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "autoscaling-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "autoscaling-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "autoscaling-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "autoscaling-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "autoscaling-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "autoscaling-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "autoscaling-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "autoscaling-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "autoscaling-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "autoscaling-plans" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "backup" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "backup-gateway" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "batch" : { + "defaults" : { + "variants" : [ { + "hostname" : "fips.batch.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "fips.batch.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "fips.batch.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "fips.batch.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "fips.batch.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "fips.batch.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "fips.batch.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "fips.batch.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "fips.batch.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "bedrock" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "bedrock-ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "bedrock.ap-northeast-1.amazonaws.com" + }, + "bedrock-ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "hostname" : "bedrock.ap-northeast-2.amazonaws.com" + }, + "bedrock-ap-northeast-3" : { + "credentialScope" : { + "region" : "ap-northeast-3" + }, + "hostname" : "bedrock.ap-northeast-3.amazonaws.com" + }, + "bedrock-ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "hostname" : "bedrock.ap-south-1.amazonaws.com" + }, + "bedrock-ap-south-2" : { + "credentialScope" : { + "region" : "ap-south-2" + }, + "hostname" : "bedrock.ap-south-2.amazonaws.com" + }, + "bedrock-ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "bedrock.ap-southeast-1.amazonaws.com" + }, + "bedrock-ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "bedrock.ap-southeast-2.amazonaws.com" + }, + "bedrock-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "hostname" : "bedrock.ca-central-1.amazonaws.com" + }, + "bedrock-eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "bedrock.eu-central-1.amazonaws.com" + }, + "bedrock-eu-central-2" : { + "credentialScope" : { + "region" : "eu-central-2" + }, + "hostname" : "bedrock.eu-central-2.amazonaws.com" + }, + "bedrock-eu-north-1" : { + "credentialScope" : { + "region" : "eu-north-1" + }, + "hostname" : "bedrock.eu-north-1.amazonaws.com" + }, + "bedrock-eu-south-1" : { + "credentialScope" : { + "region" : "eu-south-1" + }, + "hostname" : "bedrock.eu-south-1.amazonaws.com" + }, + "bedrock-eu-south-2" : { + "credentialScope" : { + "region" : "eu-south-2" + }, + "hostname" : "bedrock.eu-south-2.amazonaws.com" + }, + "bedrock-eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "bedrock.eu-west-1.amazonaws.com" + }, + "bedrock-eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "hostname" : "bedrock.eu-west-2.amazonaws.com" + }, + "bedrock-eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "hostname" : "bedrock.eu-west-3.amazonaws.com" + }, + "bedrock-fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "hostname" : "bedrock-fips.ca-central-1.amazonaws.com" + }, + "bedrock-fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "bedrock-fips.us-east-1.amazonaws.com" + }, + "bedrock-fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "bedrock-fips.us-east-2.amazonaws.com" + }, + "bedrock-fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "bedrock-fips.us-west-2.amazonaws.com" + }, + "bedrock-runtime-ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "bedrock-runtime.ap-northeast-1.amazonaws.com" + }, + "bedrock-runtime-ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "hostname" : "bedrock-runtime.ap-northeast-2.amazonaws.com" + }, + "bedrock-runtime-ap-northeast-3" : { + "credentialScope" : { + "region" : "ap-northeast-3" + }, + "hostname" : "bedrock-runtime.ap-northeast-3.amazonaws.com" + }, + "bedrock-runtime-ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "hostname" : "bedrock-runtime.ap-south-1.amazonaws.com" + }, + "bedrock-runtime-ap-south-2" : { + "credentialScope" : { + "region" : "ap-south-2" + }, + "hostname" : "bedrock-runtime.ap-south-2.amazonaws.com" + }, + "bedrock-runtime-ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "bedrock-runtime.ap-southeast-1.amazonaws.com" + }, + "bedrock-runtime-ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "bedrock-runtime.ap-southeast-2.amazonaws.com" + }, + "bedrock-runtime-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "hostname" : "bedrock-runtime.ca-central-1.amazonaws.com" + }, + "bedrock-runtime-eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "bedrock-runtime.eu-central-1.amazonaws.com" + }, + "bedrock-runtime-eu-central-2" : { + "credentialScope" : { + "region" : "eu-central-2" + }, + "hostname" : "bedrock-runtime.eu-central-2.amazonaws.com" + }, + "bedrock-runtime-eu-north-1" : { + "credentialScope" : { + "region" : "eu-north-1" + }, + "hostname" : "bedrock-runtime.eu-north-1.amazonaws.com" + }, + "bedrock-runtime-eu-south-1" : { + "credentialScope" : { + "region" : "eu-south-1" + }, + "hostname" : "bedrock-runtime.eu-south-1.amazonaws.com" + }, + "bedrock-runtime-eu-south-2" : { + "credentialScope" : { + "region" : "eu-south-2" + }, + "hostname" : "bedrock-runtime.eu-south-2.amazonaws.com" + }, + "bedrock-runtime-eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "bedrock-runtime.eu-west-1.amazonaws.com" + }, + "bedrock-runtime-eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "hostname" : "bedrock-runtime.eu-west-2.amazonaws.com" + }, + "bedrock-runtime-eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "hostname" : "bedrock-runtime.eu-west-3.amazonaws.com" + }, + "bedrock-runtime-fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "hostname" : "bedrock-runtime-fips.ca-central-1.amazonaws.com" + }, + "bedrock-runtime-fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "bedrock-runtime-fips.us-east-1.amazonaws.com" + }, + "bedrock-runtime-fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "bedrock-runtime-fips.us-east-2.amazonaws.com" + }, + "bedrock-runtime-fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "bedrock-runtime-fips.us-west-2.amazonaws.com" + }, + "bedrock-runtime-sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "hostname" : "bedrock-runtime.sa-east-1.amazonaws.com" + }, + "bedrock-runtime-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "bedrock-runtime.us-east-1.amazonaws.com" + }, + "bedrock-runtime-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "bedrock-runtime.us-east-2.amazonaws.com" + }, + "bedrock-runtime-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "bedrock-runtime.us-west-2.amazonaws.com" + }, + "bedrock-sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "hostname" : "bedrock.sa-east-1.amazonaws.com" + }, + "bedrock-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "bedrock.us-east-1.amazonaws.com" + }, + "bedrock-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "bedrock.us-east-2.amazonaws.com" + }, + "bedrock-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "bedrock.us-west-2.amazonaws.com" + }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "billingconductor" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "billingconductor.us-east-1.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "braket" : { + "endpoints" : { + "eu-north-1" : { + "variants" : [ { + "hostname" : "braket.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "braket.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "braket.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "braket.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "braket.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "budgets" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "budgets.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "cases" : { + "endpoints" : { + "af-south-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-2" : { }, + "fips-us-east-1" : { + "deprecated" : true + }, + "fips-us-west-2" : { + "deprecated" : true + }, + "us-east-1" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + } + } + }, + "cassandra" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "cassandra-fips.us-east-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "cassandra-fips.us-west-2.amazonaws.com" + }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "cassandra-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { + "variants" : [ { + "hostname" : "cassandra-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "catalog.marketplace" : { + "endpoints" : { + "us-east-1" : { } + } + }, + "ce" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "ce.us-east-1.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "chime" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "chime.us-east-1.amazonaws.com", + "protocols" : [ "https" ] + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "cleanrooms" : { + "endpoints" : { + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "cleanrooms.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "cleanrooms.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "cleanrooms.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "cleanrooms.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "cleanrooms.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "cleanrooms.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "cleanrooms.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "cleanrooms.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "cleanrooms-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "cleanrooms-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "cleanrooms-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "cleanrooms-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cleanrooms-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cleanrooms.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "cleanrooms-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cleanrooms-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cleanrooms.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "cleanrooms-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cleanrooms-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cleanrooms.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "cloud9" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "hostname" : "cloud9-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cloud9-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "cloud9-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "cloud9-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "cloud9-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "cloud9-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "cloud9-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "hostname" : "cloud9-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cloud9-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "hostname" : "cloud9-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cloud9-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "hostname" : "cloud9-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cloud9-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "hostname" : "cloud9-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cloud9-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + } + } + }, + "cloudcontrolapi" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cloudcontrolapi-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cloudcontrolapi.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cloudcontrolapi-fips.ca-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cloudcontrolapi.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "cloudcontrolapi-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "cloudcontrolapi-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "cloudcontrolapi-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "cloudcontrolapi-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "cloudcontrolapi-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "cloudcontrolapi-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cloudcontrolapi-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cloudcontrolapi.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "cloudcontrolapi-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cloudcontrolapi-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cloudcontrolapi.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cloudcontrolapi-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cloudcontrolapi.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "cloudcontrolapi-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cloudcontrolapi-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cloudcontrolapi.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "clouddirectory" : { + "endpoints" : { + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "cloudformation" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "cloudformation-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "cloudformation-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "cloudformation-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "cloudformation-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "cloudformation-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "cloudformation-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "cloudformation-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "cloudformation-fips.us-west-2.amazonaws.com" + } + } + }, + "cloudfront" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "cloudfront.amazonaws.com", + "protocols" : [ "http", "https" ] + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "cloudhsm" : { + "endpoints" : { + "us-east-1" : { } + } + }, + "cloudhsmv2" : { + "defaults" : { + "credentialScope" : { + "service" : "cloudhsm" + } + }, + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "cloudhsmv2.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "cloudhsmv2.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "cloudhsmv2.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "cloudhsmv2.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "cloudhsmv2.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "cloudhsmv2.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "cloudhsmv2.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "cloudhsmv2.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "cloudhsmv2.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "cloudhsmv2.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "cloudsearch" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "cloudtrail" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "cloudtrail-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "cloudtrail-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "cloudtrail-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "cloudtrail-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "cloudtrail-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "cloudtrail-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "cloudtrail-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "cloudtrail-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "cloudtrail-data" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "codeartifact" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "codebuild" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "codebuild-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "codebuild-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "codebuild-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "codebuild-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "codebuild-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "codebuild-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "codebuild-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "codebuild-fips.us-west-2.amazonaws.com" + } + } + }, + "codecatalyst" : { + "endpoints" : { + "aws-global" : { + "hostname" : "codecatalyst.global.api.aws" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "codecommit" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "codecommit-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "codecommit-fips.ca-central-1.amazonaws.com" + }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "codecommit-fips.ca-central-1.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "codecommit-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "codecommit-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "codecommit-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "codecommit-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "codecommit-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "codecommit-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "codecommit-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "codecommit-fips.us-west-2.amazonaws.com" + } + } + }, + "codedeploy" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "codedeploy-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "codedeploy-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "codedeploy-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "codedeploy-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "codedeploy-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "codedeploy-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "codedeploy-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "codedeploy-fips.us-west-2.amazonaws.com" + } + } + }, + "codeguru-profiler" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "codeguru-reviewer" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "codepipeline" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "codepipeline-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "codepipeline-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "codepipeline-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "codepipeline-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "codepipeline-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "codepipeline-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "codepipeline-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "codepipeline-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "codepipeline-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "codepipeline-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "codestar-connections" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "codestar-notifications" : { + "endpoints" : { + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "cognito-identity" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "cognito-identity.af-south-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "cognito-identity.ap-east-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "cognito-identity.ap-northeast-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "cognito-identity.ap-northeast-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "cognito-identity.ap-northeast-3.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "cognito-identity.ap-south-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "cognito-identity.ap-south-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "cognito-identity.ap-southeast-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "cognito-identity.ap-southeast-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "cognito-identity.ap-southeast-3.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "cognito-identity.ap-southeast-4.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "cognito-identity.ap-southeast-5.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "cognito-identity.ca-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "cognito-identity.ca-west-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "cognito-identity.eu-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "cognito-identity.eu-central-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "cognito-identity.eu-north-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "cognito-identity.eu-south-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "cognito-identity.eu-south-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "cognito-identity.eu-west-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "cognito-identity.eu-west-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "cognito-identity.eu-west-3.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "cognito-identity-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "cognito-identity-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "cognito-identity-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "cognito-identity-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "cognito-identity.il-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "cognito-identity.me-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "cognito-identity.me-south-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "cognito-identity.sa-east-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "cognito-identity-fips.us-east-1.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cognito-identity-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cognito-identity.us-east-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "cognito-identity-fips.us-east-2.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cognito-identity-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cognito-identity.us-east-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "cognito-identity-fips.us-west-1.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cognito-identity-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cognito-identity.us-west-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "cognito-identity-fips.us-west-2.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cognito-identity-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cognito-identity.us-west-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "cognito-idp" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "cognito-idp.af-south-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "cognito-idp.ap-east-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "cognito-idp.ap-northeast-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "cognito-idp.ap-northeast-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "cognito-idp.ap-northeast-3.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "cognito-idp.ap-south-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "cognito-idp.ap-south-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "cognito-idp.ap-southeast-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "cognito-idp.ap-southeast-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "cognito-idp.ap-southeast-3.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "cognito-idp.ap-southeast-4.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "cognito-idp.ap-southeast-5.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "cognito-idp.ca-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "cognito-idp.ca-west-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "cognito-idp.eu-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "cognito-idp.eu-central-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "cognito-idp.eu-north-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "cognito-idp.eu-south-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "cognito-idp.eu-south-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "cognito-idp.eu-west-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "cognito-idp.eu-west-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "cognito-idp.eu-west-3.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "cognito-idp-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "cognito-idp-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "cognito-idp-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "cognito-idp-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "cognito-idp.il-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "cognito-idp.me-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "cognito-idp.me-south-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "cognito-idp.sa-east-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "cognito-idp-fips.us-east-1.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cognito-idp-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cognito-idp.us-east-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "cognito-idp-fips.us-east-2.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cognito-idp-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cognito-idp.us-east-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "cognito-idp-fips.us-west-1.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cognito-idp-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cognito-idp.us-west-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "cognito-idp-fips.us-west-2.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cognito-idp-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cognito-idp.us-west-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "cognito-sync" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "comprehend" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "comprehend.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "comprehend.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "comprehend.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "comprehend.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "comprehend.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "comprehend-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "comprehend-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "comprehend.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "comprehend.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "comprehend.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "comprehend.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "comprehend-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "comprehend-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "comprehend-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "comprehend-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "comprehend-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "comprehend-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "comprehend.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "comprehend-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "comprehend-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "comprehend.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "comprehend-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "comprehend-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "comprehend.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "comprehendmedical" : { + "endpoints" : { + "ap-southeast-2" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "comprehendmedical-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "comprehendmedical-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "comprehendmedical-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "comprehendmedical-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "comprehendmedical-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "comprehendmedical-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "comprehendmedical-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "comprehendmedical-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "compute-optimizer" : { + "endpoints" : { + "af-south-1" : { + "credentialScope" : { + "region" : "af-south-1" + }, + "hostname" : "compute-optimizer.af-south-1.amazonaws.com" + }, + "ap-east-1" : { + "credentialScope" : { + "region" : "ap-east-1" + }, + "hostname" : "compute-optimizer.ap-east-1.amazonaws.com" + }, + "ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "compute-optimizer.ap-northeast-1.amazonaws.com" + }, + "ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "hostname" : "compute-optimizer.ap-northeast-2.amazonaws.com" + }, + "ap-northeast-3" : { + "credentialScope" : { + "region" : "ap-northeast-3" + }, + "hostname" : "compute-optimizer.ap-northeast-3.amazonaws.com" + }, + "ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "hostname" : "compute-optimizer.ap-south-1.amazonaws.com" + }, + "ap-south-2" : { + "credentialScope" : { + "region" : "ap-south-2" + }, + "hostname" : "compute-optimizer.ap-south-2.amazonaws.com" + }, + "ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "compute-optimizer.ap-southeast-1.amazonaws.com" + }, + "ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "compute-optimizer.ap-southeast-2.amazonaws.com" + }, + "ap-southeast-3" : { + "credentialScope" : { + "region" : "ap-southeast-3" + }, + "hostname" : "compute-optimizer.ap-southeast-3.amazonaws.com" + }, + "ap-southeast-4" : { + "credentialScope" : { + "region" : "ap-southeast-4" + }, + "hostname" : "compute-optimizer.ap-southeast-4.amazonaws.com" + }, + "ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "hostname" : "compute-optimizer.ca-central-1.amazonaws.com" + }, + "eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "compute-optimizer.eu-central-1.amazonaws.com" + }, + "eu-central-2" : { + "credentialScope" : { + "region" : "eu-central-2" + }, + "hostname" : "compute-optimizer.eu-central-2.amazonaws.com" + }, + "eu-north-1" : { + "credentialScope" : { + "region" : "eu-north-1" + }, + "hostname" : "compute-optimizer.eu-north-1.amazonaws.com" + }, + "eu-south-1" : { + "credentialScope" : { + "region" : "eu-south-1" + }, + "hostname" : "compute-optimizer.eu-south-1.amazonaws.com" + }, + "eu-south-2" : { + "credentialScope" : { + "region" : "eu-south-2" + }, + "hostname" : "compute-optimizer.eu-south-2.amazonaws.com" + }, + "eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "compute-optimizer.eu-west-1.amazonaws.com" + }, + "eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "hostname" : "compute-optimizer.eu-west-2.amazonaws.com" + }, + "eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "hostname" : "compute-optimizer.eu-west-3.amazonaws.com" + }, + "il-central-1" : { + "credentialScope" : { + "region" : "il-central-1" + }, + "hostname" : "compute-optimizer.il-central-1.amazonaws.com" + }, + "me-central-1" : { + "credentialScope" : { + "region" : "me-central-1" + }, + "hostname" : "compute-optimizer.me-central-1.amazonaws.com" + }, + "me-south-1" : { + "credentialScope" : { + "region" : "me-south-1" + }, + "hostname" : "compute-optimizer.me-south-1.amazonaws.com" + }, + "sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "hostname" : "compute-optimizer.sa-east-1.amazonaws.com" + }, + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "compute-optimizer.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "compute-optimizer.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "hostname" : "compute-optimizer.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "compute-optimizer.us-west-2.amazonaws.com" + } + } + }, + "config" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "config-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "config-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "config-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "config-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "config-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "config-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "config-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "config-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "connect" : { + "endpoints" : { + "af-south-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "connect-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-west-2" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "connect-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "connect-fips.us-east-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "connect-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "connect-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "connect-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "connect-campaigns" : { + "endpoints" : { + "af-south-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-2" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "connect-campaigns-fips.us-east-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "connect-campaigns-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "connect-campaigns-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "connect-campaigns-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "contact-lens" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "controltower" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "controltower-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "controltower-fips.ca-central-1.amazonaws.com" + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "controltower-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1-fips" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "controltower-fips.ca-west-1.amazonaws.com" + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "controltower-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "controltower-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "controltower-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "controltower-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "controltower-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "controltower-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "controltower-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "controltower-fips.us-west-2.amazonaws.com" + } + } + }, + "cost-optimization-hub" : { + "endpoints" : { + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "cost-optimization-hub.us-east-1.amazonaws.com" + } + } + }, + "cur" : { + "endpoints" : { + "us-east-1" : { } + } + }, + "data-ats.iot" : { + "defaults" : { + "credentialScope" : { + "service" : "iotdata" + }, + "protocols" : [ "https" ] + }, + "endpoints" : { + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-5" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "data.iot-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "service" : "iotdata" + }, + "deprecated" : true, + "hostname" : "data.iot-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "service" : "iotdata" + }, + "deprecated" : true, + "hostname" : "data.iot-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "service" : "iotdata" + }, + "deprecated" : true, + "hostname" : "data.iot-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "service" : "iotdata" + }, + "deprecated" : true, + "hostname" : "data.iot-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "service" : "iotdata" + }, + "deprecated" : true, + "hostname" : "data.iot-fips.us-west-2.amazonaws.com" + }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "data.iot-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "data.iot-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "data.iot-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "data.iot-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "data.iot" : { + "defaults" : { + "credentialScope" : { + "service" : "iotdata" + }, + "protocols" : [ "https" ] + }, + "endpoints" : { + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "data.iot-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "service" : "iotdata" + }, + "deprecated" : true, + "hostname" : "data.iot-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "service" : "iotdata" + }, + "deprecated" : true, + "hostname" : "data.iot-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "service" : "iotdata" + }, + "deprecated" : true, + "hostname" : "data.iot-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "service" : "iotdata" + }, + "deprecated" : true, + "hostname" : "data.iot-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "service" : "iotdata" + }, + "deprecated" : true, + "hostname" : "data.iot-fips.us-west-2.amazonaws.com" + }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "data.iot-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "data.iot-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "data.iot-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "data.iot-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "data.jobs.iot" : { + "endpoints" : { + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-5" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "data.jobs.iot-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "data.jobs.iot-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "data.jobs.iot-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "data.jobs.iot-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "data.jobs.iot-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "data.jobs.iot-fips.us-west-2.amazonaws.com" + }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "data.jobs.iot-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "data.jobs.iot-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "data.jobs.iot-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "data.jobs.iot-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "data.mediastore" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "databrew" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "databrew-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "databrew-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "databrew-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "databrew-fips.us-west-2.amazonaws.com" + }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "databrew-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "databrew-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "databrew-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "databrew-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "dataexchange" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "datapipeline" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-southeast-2" : { }, + "eu-west-1" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "datasync" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "datasync.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "datasync.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "datasync.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "datasync.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "datasync.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "datasync.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "datasync.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "datasync.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "datasync.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "datasync.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "datasync.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "datasync.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "datasync.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "datasync-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "datasync-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "datasync.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "datasync-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "datasync-fips.ca-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "datasync.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "datasync.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "datasync.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "datasync.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "datasync.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "datasync.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "datasync.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "datasync.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "datasync.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "datasync-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "datasync-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "datasync-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "datasync-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "datasync-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "datasync-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "datasync.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "datasync.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "datasync.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "datasync.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "datasync.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "datasync-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "datasync-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "datasync.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "datasync-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "datasync-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "datasync.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "datasync-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "datasync-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "datasync.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "datasync-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "datasync-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "datasync.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "datazone" : { + "defaults" : { + "dnsSuffix" : "api.aws", + "variants" : [ { + "dnsSuffix" : "api.aws", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "hostname" : "datazone.ap-northeast-1.api.aws" + }, + "ap-northeast-2" : { + "hostname" : "datazone.ap-northeast-2.api.aws" + }, + "ap-northeast-3" : { + "hostname" : "datazone.ap-northeast-3.api.aws" + }, + "ap-south-1" : { + "hostname" : "datazone.ap-south-1.api.aws" + }, + "ap-south-2" : { + "hostname" : "datazone.ap-south-2.api.aws" + }, + "ap-southeast-1" : { + "hostname" : "datazone.ap-southeast-1.api.aws" + }, + "ap-southeast-2" : { + "hostname" : "datazone.ap-southeast-2.api.aws" + }, + "ap-southeast-3" : { + "hostname" : "datazone.ap-southeast-3.api.aws" + }, + "ap-southeast-4" : { + "hostname" : "datazone.ap-southeast-4.api.aws" + }, + "ap-southeast-5" : { + "hostname" : "datazone.ap-southeast-5.api.aws" + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "hostname" : "datazone.ap-southeast-7.api.aws" + }, + "ca-central-1" : { + "hostname" : "datazone.ca-central-1.api.aws", + "variants" : [ { + "hostname" : "datazone-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "hostname" : "datazone.ca-west-1.api.aws" + }, + "eu-central-1" : { + "hostname" : "datazone.eu-central-1.api.aws" + }, + "eu-central-2" : { }, + "eu-north-1" : { + "hostname" : "datazone.eu-north-1.api.aws" + }, + "eu-south-1" : { + "hostname" : "datazone.eu-south-1.api.aws" + }, + "eu-west-1" : { + "hostname" : "datazone.eu-west-1.api.aws" + }, + "eu-west-2" : { + "hostname" : "datazone.eu-west-2.api.aws" + }, + "eu-west-3" : { + "hostname" : "datazone.eu-west-3.api.aws" + }, + "il-central-1" : { + "hostname" : "datazone.il-central-1.api.aws" + }, + "me-central-1" : { + "hostname" : "datazone.me-central-1.api.aws" + }, + "me-south-1" : { + "hostname" : "datazone.me-south-1.api.aws" + }, + "mx-central-1" : { + "hostname" : "datazone.mx-central-1.api.aws" + }, + "sa-east-1" : { + "hostname" : "datazone.sa-east-1.api.aws" + }, + "us-east-1" : { + "hostname" : "datazone.us-east-1.api.aws", + "variants" : [ { + "hostname" : "datazone-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "hostname" : "datazone.us-east-2.api.aws", + "variants" : [ { + "hostname" : "datazone-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "hostname" : "datazone.us-west-1.api.aws" + }, + "us-west-2" : { + "hostname" : "datazone.us-west-2.api.aws", + "variants" : [ { + "hostname" : "datazone-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "dax" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "devicefarm" : { + "endpoints" : { + "us-west-2" : { } + } + }, + "devops-guru" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "devops-guru-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "devops-guru-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "devops-guru-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "devops-guru-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "devops-guru-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "devops-guru-fips.us-west-2.amazonaws.com" + }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "devops-guru-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "devops-guru-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "devops-guru-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "devops-guru-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "directconnect" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "directconnect-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "directconnect-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "directconnect-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "directconnect-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "directconnect-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "directconnect-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "directconnect-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "directconnect-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "directconnect-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "directconnect-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "directconnect-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "directconnect-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "discovery" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "dlm" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "dlm.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "dlm.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "dlm.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "dlm.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "dlm.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "dlm.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "dlm.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "dlm.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "dlm.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "dlm.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "dlm.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "dlm.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "dlm.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "dlm-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "dlm.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "dlm-fips.ca-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "dlm.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "dlm.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "dlm.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "dlm.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "dlm.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "dlm.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "dlm.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "dlm.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "dlm.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "dlm.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "dlm.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "dlm.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "dlm.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "dlm.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "dlm-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "dlm.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "dlm-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "dlm.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "dlm-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "dlm.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "dlm-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "dlm.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "dms" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "dms" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "dms-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "dms-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "dms-fips.us-west-1.amazonaws.com" + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "dms-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "dms-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "dms-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "dms-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "dms-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "dms-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "dms-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "dms-fips.us-west-2.amazonaws.com" + } + } + }, + "docdb" : { + "endpoints" : { + "ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "rds.ap-northeast-1.amazonaws.com" + }, + "ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "hostname" : "rds.ap-northeast-2.amazonaws.com" + }, + "ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "hostname" : "rds.ap-south-1.amazonaws.com" + }, + "ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "rds.ap-southeast-1.amazonaws.com" + }, + "ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "rds.ap-southeast-2.amazonaws.com" + }, + "ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "hostname" : "rds.ca-central-1.amazonaws.com" + }, + "eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "rds.eu-central-1.amazonaws.com" + }, + "eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "rds.eu-west-1.amazonaws.com" + }, + "eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "hostname" : "rds.eu-west-2.amazonaws.com" + }, + "eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "hostname" : "rds.eu-west-3.amazonaws.com" + }, + "sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "hostname" : "rds.sa-east-1.amazonaws.com" + }, + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "rds.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "rds.us-east-2.amazonaws.com" + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "rds.us-west-2.amazonaws.com" + } + } + }, + "drs" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "drs-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "drs-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "drs-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "drs-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "drs-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "drs-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "drs-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "drs-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "ds" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "ds-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "ds-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "ds-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "ds-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "ds-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "ds-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "ds-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "ds-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "ds-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "ds-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "ds-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "ds-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "dynamodb" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "dynamodb-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "dynamodb-fips.ca-central-1.amazonaws.com" + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "dynamodb-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1-fips" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "dynamodb-fips.ca-west-1.amazonaws.com" + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "local" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "localhost:8000", + "protocols" : [ "http" ] + }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "dynamodb-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "dynamodb-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "dynamodb-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "dynamodb-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "dynamodb-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "dynamodb-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "dynamodb-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "dynamodb-fips.us-west-2.amazonaws.com" + } + } + }, + "ebs" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "ebs-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "ebs-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "ebs-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "ebs-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "ebs-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "ebs-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "ebs-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "ebs-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "ebs-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "ebs-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "ebs-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "ebs-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "ec2" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "ec2.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "ec2.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "ec2.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "ec2.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "ec2.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "ec2.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "ec2.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "ec2-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ec2.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "ec2-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "ec2.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "ec2.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "ec2.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "ec2.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "ec2.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "ec2.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "ec2-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "ec2-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "ec2-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "ec2-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "ec2-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "ec2-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { + "variants" : [ { + "hostname" : "ec2.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "ec2.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "ec2-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ec2.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "ec2-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ec2.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "ec2-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ec2.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "ec2-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ec2.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "ecs" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "ecs-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "ecs-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "ecs-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "ecs-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "ecs-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "ecs-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "ecs-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "ecs-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "edge.sagemaker" : { + "endpoints" : { + "ap-northeast-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "eks" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "variants" : [ { + "hostname" : "fips.eks.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "fips.eks.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "fips.eks.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "fips.eks.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "fips.eks.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "fips.eks.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "fips.eks.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "fips.eks.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "fips.eks.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "eks-auth" : { + "defaults" : { + "dnsSuffix" : "api.aws", + "variants" : [ { + "dnsSuffix" : "api.aws", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "af-south-1" : { + "hostname" : "eks-auth.af-south-1.api.aws" + }, + "ap-east-1" : { + "hostname" : "eks-auth.ap-east-1.api.aws" + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "hostname" : "eks-auth.ap-northeast-1.api.aws" + }, + "ap-northeast-2" : { + "hostname" : "eks-auth.ap-northeast-2.api.aws" + }, + "ap-northeast-3" : { + "hostname" : "eks-auth.ap-northeast-3.api.aws" + }, + "ap-south-1" : { + "hostname" : "eks-auth.ap-south-1.api.aws" + }, + "ap-south-2" : { + "hostname" : "eks-auth.ap-south-2.api.aws" + }, + "ap-southeast-1" : { + "hostname" : "eks-auth.ap-southeast-1.api.aws" + }, + "ap-southeast-2" : { + "hostname" : "eks-auth.ap-southeast-2.api.aws" + }, + "ap-southeast-3" : { + "hostname" : "eks-auth.ap-southeast-3.api.aws" + }, + "ap-southeast-4" : { + "hostname" : "eks-auth.ap-southeast-4.api.aws" + }, + "ap-southeast-5" : { + "hostname" : "eks-auth.ap-southeast-5.api.aws" + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "hostname" : "eks-auth.ap-southeast-7.api.aws" + }, + "ca-central-1" : { + "hostname" : "eks-auth.ca-central-1.api.aws" + }, + "ca-west-1" : { + "hostname" : "eks-auth.ca-west-1.api.aws" + }, + "eu-central-1" : { + "hostname" : "eks-auth.eu-central-1.api.aws" + }, + "eu-central-2" : { + "hostname" : "eks-auth.eu-central-2.api.aws" + }, + "eu-north-1" : { + "hostname" : "eks-auth.eu-north-1.api.aws" + }, + "eu-south-1" : { + "hostname" : "eks-auth.eu-south-1.api.aws" + }, + "eu-south-2" : { + "hostname" : "eks-auth.eu-south-2.api.aws" + }, + "eu-west-1" : { + "hostname" : "eks-auth.eu-west-1.api.aws" + }, + "eu-west-2" : { + "hostname" : "eks-auth.eu-west-2.api.aws" + }, + "eu-west-3" : { + "hostname" : "eks-auth.eu-west-3.api.aws" + }, + "il-central-1" : { + "hostname" : "eks-auth.il-central-1.api.aws" + }, + "me-central-1" : { + "hostname" : "eks-auth.me-central-1.api.aws" + }, + "me-south-1" : { + "hostname" : "eks-auth.me-south-1.api.aws" + }, + "mx-central-1" : { + "hostname" : "eks-auth.mx-central-1.api.aws" + }, + "sa-east-1" : { + "hostname" : "eks-auth.sa-east-1.api.aws" + }, + "us-east-1" : { + "hostname" : "eks-auth.us-east-1.api.aws" + }, + "us-east-2" : { + "hostname" : "eks-auth.us-east-2.api.aws" + }, + "us-west-1" : { + "hostname" : "eks-auth.us-west-1.api.aws" + }, + "us-west-2" : { + "hostname" : "eks-auth.us-west-2.api.aws" + } + } + }, + "elasticache" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "elasticache-fips.us-west-1.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "elasticache-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "elasticache-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "elasticache-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "elasticache-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "elasticache-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "elasticache-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "elasticache-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "elasticache-fips.us-west-2.amazonaws.com" + } + } + }, + "elasticbeanstalk" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "elasticbeanstalk-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "elasticbeanstalk-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "elasticbeanstalk-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "elasticbeanstalk-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { }, + "me-south-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "elasticbeanstalk-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "elasticbeanstalk.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "elasticbeanstalk-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "elasticbeanstalk-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "elasticbeanstalk.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "elasticbeanstalk-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "elasticbeanstalk.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "elasticbeanstalk-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "elasticbeanstalk-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "elasticbeanstalk.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "elasticfilesystem" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.af-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.ap-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.ap-northeast-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.ap-northeast-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.ap-northeast-3.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.ap-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.ap-south-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.ap-southeast-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.ap-southeast-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.ap-southeast-3.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.ap-southeast-4.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.ap-southeast-5.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.ap-southeast-7.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.eu-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.eu-central-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.eu-north-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.eu-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.eu-south-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.eu-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.eu-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.eu-west-3.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "fips-af-south-1" : { + "credentialScope" : { + "region" : "af-south-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.af-south-1.amazonaws.com" + }, + "fips-ap-east-1" : { + "credentialScope" : { + "region" : "ap-east-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.ap-east-1.amazonaws.com" + }, + "fips-ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.ap-northeast-1.amazonaws.com" + }, + "fips-ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.ap-northeast-2.amazonaws.com" + }, + "fips-ap-northeast-3" : { + "credentialScope" : { + "region" : "ap-northeast-3" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.ap-northeast-3.amazonaws.com" + }, + "fips-ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.ap-south-1.amazonaws.com" + }, + "fips-ap-south-2" : { + "credentialScope" : { + "region" : "ap-south-2" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.ap-south-2.amazonaws.com" + }, + "fips-ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.ap-southeast-1.amazonaws.com" + }, + "fips-ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.ap-southeast-2.amazonaws.com" + }, + "fips-ap-southeast-3" : { + "credentialScope" : { + "region" : "ap-southeast-3" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.ap-southeast-3.amazonaws.com" + }, + "fips-ap-southeast-4" : { + "credentialScope" : { + "region" : "ap-southeast-4" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.ap-southeast-4.amazonaws.com" + }, + "fips-ap-southeast-5" : { + "credentialScope" : { + "region" : "ap-southeast-5" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.ap-southeast-5.amazonaws.com" + }, + "fips-ap-southeast-7" : { + "credentialScope" : { + "region" : "ap-southeast-7" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.ap-southeast-7.amazonaws.com" + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.ca-west-1.amazonaws.com" + }, + "fips-eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.eu-central-1.amazonaws.com" + }, + "fips-eu-central-2" : { + "credentialScope" : { + "region" : "eu-central-2" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.eu-central-2.amazonaws.com" + }, + "fips-eu-north-1" : { + "credentialScope" : { + "region" : "eu-north-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.eu-north-1.amazonaws.com" + }, + "fips-eu-south-1" : { + "credentialScope" : { + "region" : "eu-south-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.eu-south-1.amazonaws.com" + }, + "fips-eu-south-2" : { + "credentialScope" : { + "region" : "eu-south-2" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.eu-south-2.amazonaws.com" + }, + "fips-eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.eu-west-1.amazonaws.com" + }, + "fips-eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.eu-west-2.amazonaws.com" + }, + "fips-eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.eu-west-3.amazonaws.com" + }, + "fips-il-central-1" : { + "credentialScope" : { + "region" : "il-central-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.il-central-1.amazonaws.com" + }, + "fips-me-central-1" : { + "credentialScope" : { + "region" : "me-central-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.me-central-1.amazonaws.com" + }, + "fips-me-south-1" : { + "credentialScope" : { + "region" : "me-south-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.me-south-1.amazonaws.com" + }, + "fips-mx-central-1" : { + "credentialScope" : { + "region" : "mx-central-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.mx-central-1.amazonaws.com" + }, + "fips-sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.sa-east-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.il-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.me-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.me-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.mx-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.sa-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "elasticloadbalancing" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "elasticloadbalancing-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "elasticloadbalancing-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "elasticloadbalancing-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "elasticloadbalancing-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "elasticloadbalancing-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "elasticloadbalancing-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "elasticloadbalancing-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "elasticloadbalancing-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "elasticmapreduce" : { + "defaults" : { + "protocols" : [ "https" ], + "sslCommonName" : "{region}.{service}.{dnsSuffix}" + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "elasticmapreduce-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "elasticmapreduce-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { + "sslCommonName" : "{service}.{region}.{dnsSuffix}" + }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "elasticmapreduce-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "elasticmapreduce-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "elasticmapreduce-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "elasticmapreduce-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "elasticmapreduce-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "elasticmapreduce-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "sslCommonName" : "{service}.{region}.{dnsSuffix}", + "variants" : [ { + "hostname" : "elasticmapreduce-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "elasticmapreduce-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "elasticmapreduce.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "elasticmapreduce-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "elasticmapreduce-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "email" : { + "endpoints" : { + "af-south-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-5" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "email-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "email-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "email-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "email-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "email-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "email-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "email-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "email-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "email-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "email-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "emr-containers" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "emr-containers-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "emr-containers-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "emr-containers-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "emr-containers-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "emr-containers-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "emr-containers-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "emr-containers-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "emr-containers-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "emr-containers-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "emr-containers-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "emr-serverless" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "emr-serverless-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "emr-serverless-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "emr-serverless-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "emr-serverless-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "emr-serverless-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "emr-serverless-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "emr-serverless-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "emr-serverless-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "emr-serverless-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "emr-serverless-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "entitlement.marketplace" : { + "defaults" : { + "credentialScope" : { + "service" : "aws-marketplace" + } + }, + "endpoints" : { + "us-east-1" : { + "variants" : [ { + "hostname" : "entitlement-marketplace.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "es" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "aos.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "aos.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "aos.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "aos.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "aos.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "aos.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "aos.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "aos.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "aos.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "aos.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "aos.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "aos.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "aos.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "aos.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "aos.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "aos.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "aos.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "aos.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "aos.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "aos.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "aos.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "aos.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "aos.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "es-fips.us-west-1.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "aos.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "aos.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "aos.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "aos.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "aos.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "aos.us-east-1.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "es-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "es-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "aos.us-east-2.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "es-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "es-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "aos.us-west-1.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "es-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "es-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "aos.us-west-2.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "es-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "es-fips.us-west-2.amazonaws.com" + } + } + }, + "events" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "events.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "events.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "events.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "events.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "events.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "events.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "events.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "events.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "events.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "events.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "events.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "events.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "events.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "events.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "events.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "events.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "events.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "events.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "events.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "events.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "events.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "events.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "events.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "events-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "events-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "events-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "events-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "events.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "events.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "events.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "events.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "events.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "events-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "events-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "events.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "events-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "events-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "events.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "events-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "events-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "events.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "events-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "events-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "events.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "evidently" : { + "endpoints" : { + "ap-northeast-1" : { + "hostname" : "evidently.ap-northeast-1.amazonaws.com" + }, + "ap-southeast-1" : { + "hostname" : "evidently.ap-southeast-1.amazonaws.com" + }, + "ap-southeast-2" : { + "hostname" : "evidently.ap-southeast-2.amazonaws.com" + }, + "eu-central-1" : { + "hostname" : "evidently.eu-central-1.amazonaws.com" + }, + "eu-north-1" : { + "hostname" : "evidently.eu-north-1.amazonaws.com" + }, + "eu-west-1" : { + "hostname" : "evidently.eu-west-1.amazonaws.com" + }, + "us-east-1" : { + "hostname" : "evidently.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "hostname" : "evidently.us-east-2.amazonaws.com" + }, + "us-west-2" : { + "hostname" : "evidently.us-west-2.amazonaws.com" + } + } + }, + "finspace" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "finspace-api" : { + "endpoints" : { + "ca-central-1" : { }, + "eu-west-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "firehose" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "firehose.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "firehose.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "firehose.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "firehose.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "firehose.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "firehose.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "firehose.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "firehose.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "firehose.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "firehose.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "firehose.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "firehose.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "firehose.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "firehose.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "firehose.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "firehose.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "firehose.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "firehose.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "firehose.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "firehose.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "firehose.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "firehose.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "firehose-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "firehose-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "firehose-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "firehose-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "firehose.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "firehose.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "firehose.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "firehose.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "firehose.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "firehose-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "firehose-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "firehose.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "firehose-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "firehose-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "firehose.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "firehose-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "firehose-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "firehose.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "firehose-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "firehose-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "firehose.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "fms" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "fms-fips.af-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "fms-fips.ap-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "fms-fips.ap-northeast-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "fms-fips.ap-northeast-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-northeast-3" : { }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "fms-fips.ap-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-south-2" : { }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "fms-fips.ap-southeast-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "fms-fips.ap-southeast-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "fms-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "fms-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "fms-fips.eu-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "fms-fips.eu-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-south-2" : { }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "fms-fips.eu-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "fms-fips.eu-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "fms-fips.eu-west-3.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "fips-af-south-1" : { + "credentialScope" : { + "region" : "af-south-1" + }, + "deprecated" : true, + "hostname" : "fms-fips.af-south-1.amazonaws.com" + }, + "fips-ap-east-1" : { + "credentialScope" : { + "region" : "ap-east-1" + }, + "deprecated" : true, + "hostname" : "fms-fips.ap-east-1.amazonaws.com" + }, + "fips-ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "deprecated" : true, + "hostname" : "fms-fips.ap-northeast-1.amazonaws.com" + }, + "fips-ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "deprecated" : true, + "hostname" : "fms-fips.ap-northeast-2.amazonaws.com" + }, + "fips-ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "deprecated" : true, + "hostname" : "fms-fips.ap-south-1.amazonaws.com" + }, + "fips-ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "deprecated" : true, + "hostname" : "fms-fips.ap-southeast-1.amazonaws.com" + }, + "fips-ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "deprecated" : true, + "hostname" : "fms-fips.ap-southeast-2.amazonaws.com" + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "fms-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "fms-fips.ca-west-1.amazonaws.com" + }, + "fips-eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "deprecated" : true, + "hostname" : "fms-fips.eu-central-1.amazonaws.com" + }, + "fips-eu-south-1" : { + "credentialScope" : { + "region" : "eu-south-1" + }, + "deprecated" : true, + "hostname" : "fms-fips.eu-south-1.amazonaws.com" + }, + "fips-eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "deprecated" : true, + "hostname" : "fms-fips.eu-west-1.amazonaws.com" + }, + "fips-eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "deprecated" : true, + "hostname" : "fms-fips.eu-west-2.amazonaws.com" + }, + "fips-eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "deprecated" : true, + "hostname" : "fms-fips.eu-west-3.amazonaws.com" + }, + "fips-me-south-1" : { + "credentialScope" : { + "region" : "me-south-1" + }, + "deprecated" : true, + "hostname" : "fms-fips.me-south-1.amazonaws.com" + }, + "fips-sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "deprecated" : true, + "hostname" : "fms-fips.sa-east-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "fms-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "fms-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "fms-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "fms-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { + "variants" : [ { + "hostname" : "fms-fips.me-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "mx-central-1" : { }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "fms-fips.sa-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "fms-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "fms-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "fms-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "fms-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "forecast" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "forecast-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "forecast-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "forecast-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "forecast-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "forecast-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "forecast-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "forecastquery" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "forecastquery-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "forecastquery-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "forecastquery-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "forecastquery-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "forecastquery-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "forecastquery-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "frauddetector" : { + "endpoints" : { + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-west-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "fsx" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "fsx-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "fsx-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "fsx-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "fsx-fips.ca-west-1.amazonaws.com" + }, + "fips-prod-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "fsx-fips.ca-central-1.amazonaws.com" + }, + "fips-prod-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "fsx-fips.ca-west-1.amazonaws.com" + }, + "fips-prod-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "fsx-fips.us-east-1.amazonaws.com" + }, + "fips-prod-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "fsx-fips.us-east-2.amazonaws.com" + }, + "fips-prod-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "fsx-fips.us-west-1.amazonaws.com" + }, + "fips-prod-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "fsx-fips.us-west-2.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "fsx-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "fsx-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "fsx-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "fsx-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "prod-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "fsx-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "prod-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "fsx-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "prod-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "fsx-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "prod-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "fsx-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "prod-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "fsx-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "prod-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "fsx-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "fsx-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "fsx-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "fsx-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "fsx-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "gamelift" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "gameliftstreams" : { + "defaults" : { + "dnsSuffix" : "api.aws", + "variants" : [ { + "dnsSuffix" : "api.aws", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "af-south-1" : { + "hostname" : "gameliftstreams.af-south-1.api.aws" + }, + "ap-east-1" : { + "hostname" : "gameliftstreams.ap-east-1.api.aws" + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "hostname" : "gameliftstreams.ap-northeast-1.api.aws" + }, + "ap-northeast-2" : { + "hostname" : "gameliftstreams.ap-northeast-2.api.aws" + }, + "ap-northeast-3" : { + "hostname" : "gameliftstreams.ap-northeast-3.api.aws" + }, + "ap-south-1" : { + "hostname" : "gameliftstreams.ap-south-1.api.aws" + }, + "ap-south-2" : { + "hostname" : "gameliftstreams.ap-south-2.api.aws" + }, + "ap-southeast-1" : { + "hostname" : "gameliftstreams.ap-southeast-1.api.aws" + }, + "ap-southeast-2" : { + "hostname" : "gameliftstreams.ap-southeast-2.api.aws" + }, + "ap-southeast-3" : { + "hostname" : "gameliftstreams.ap-southeast-3.api.aws" + }, + "ap-southeast-4" : { + "hostname" : "gameliftstreams.ap-southeast-4.api.aws" + }, + "ap-southeast-5" : { + "hostname" : "gameliftstreams.ap-southeast-5.api.aws" + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "hostname" : "gameliftstreams.ap-southeast-7.api.aws" + }, + "ca-central-1" : { + "hostname" : "gameliftstreams.ca-central-1.api.aws" + }, + "ca-west-1" : { + "hostname" : "gameliftstreams.ca-west-1.api.aws" + }, + "eu-central-1" : { + "hostname" : "gameliftstreams.eu-central-1.api.aws" + }, + "eu-central-2" : { + "hostname" : "gameliftstreams.eu-central-2.api.aws" + }, + "eu-north-1" : { + "hostname" : "gameliftstreams.eu-north-1.api.aws" + }, + "eu-south-1" : { + "hostname" : "gameliftstreams.eu-south-1.api.aws" + }, + "eu-south-2" : { + "hostname" : "gameliftstreams.eu-south-2.api.aws" + }, + "eu-west-1" : { + "hostname" : "gameliftstreams.eu-west-1.api.aws" + }, + "eu-west-2" : { + "hostname" : "gameliftstreams.eu-west-2.api.aws" + }, + "eu-west-3" : { + "hostname" : "gameliftstreams.eu-west-3.api.aws" + }, + "il-central-1" : { + "hostname" : "gameliftstreams.il-central-1.api.aws" + }, + "me-central-1" : { + "hostname" : "gameliftstreams.me-central-1.api.aws" + }, + "me-south-1" : { + "hostname" : "gameliftstreams.me-south-1.api.aws" + }, + "mx-central-1" : { + "hostname" : "gameliftstreams.mx-central-1.api.aws" + }, + "sa-east-1" : { + "hostname" : "gameliftstreams.sa-east-1.api.aws" + }, + "us-east-1" : { + "hostname" : "gameliftstreams.us-east-1.api.aws" + }, + "us-east-2" : { + "hostname" : "gameliftstreams.us-east-2.api.aws" + }, + "us-west-1" : { + "hostname" : "gameliftstreams.us-west-1.api.aws" + }, + "us-west-2" : { + "hostname" : "gameliftstreams.us-west-2.api.aws" + } + } + }, + "geo" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-5" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "glacier" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "glacier-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "glacier-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "glacier-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "glacier-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "glacier-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "glacier-fips.us-west-2.amazonaws.com" + }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "glacier-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "glacier-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "glacier-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "glacier-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "globalaccelerator" : { + "endpoints" : { + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "globalaccelerator-fips.us-west-2.amazonaws.com" + } + } + }, + "glue" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "glue.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "glue.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "glue.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "glue.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "glue.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "glue.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "glue.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "glue.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "glue.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "glue.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "glue.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "glue.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "glue.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "glue.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "glue.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "glue.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "glue.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "glue.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "glue.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "glue.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "glue.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "glue.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "glue.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "glue-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "glue-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "glue-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "glue-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "glue.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "glue.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "glue.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "glue.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "glue.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "glue-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "glue-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "glue.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "glue-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "glue-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "glue.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "glue-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "glue-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "glue.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "glue-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "glue-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "glue.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "grafana" : { + "endpoints" : { + "ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "grafana.ap-northeast-1.amazonaws.com" + }, + "ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "hostname" : "grafana.ap-northeast-2.amazonaws.com" + }, + "ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "grafana.ap-southeast-1.amazonaws.com" + }, + "ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "grafana.ap-southeast-2.amazonaws.com" + }, + "eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "grafana.eu-central-1.amazonaws.com" + }, + "eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "grafana.eu-west-1.amazonaws.com" + }, + "eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "hostname" : "grafana.eu-west-2.amazonaws.com" + }, + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "grafana.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "grafana.us-east-2.amazonaws.com" + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "grafana.us-west-2.amazonaws.com" + } + } + }, + "greengrass" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-5" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "greengrass-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "greengrass-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "greengrass-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "greengrass-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "greengrass-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "greengrass-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "greengrass-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "greengrass-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + }, + "isRegionalized" : true + }, + "groundstation" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "groundstation-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "groundstation-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "groundstation-fips.us-west-2.amazonaws.com" + }, + "me-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "hostname" : "groundstation-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "groundstation-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "hostname" : "groundstation-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "groundstation-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "hostname" : "groundstation-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "groundstation-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + } + } + }, + "guardduty" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "guardduty-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1-fips" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "guardduty-fips.ca-west-1.amazonaws.com" + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "guardduty-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "guardduty-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "guardduty-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "guardduty-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "guardduty-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "guardduty-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "guardduty-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "guardduty-fips.us-west-2.amazonaws.com" + } + }, + "isRegionalized" : true + }, + "health" : { + "defaults" : { + "protocols" : [ "https" ], + "sslCommonName" : "health.us-east-1.amazonaws.com" + }, + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "global.health.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "health-fips.us-east-2.amazonaws.com" + }, + "us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "health-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "healthlake" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "ap-south-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "iam" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "iam.amazonaws.com", + "variants" : [ { + "hostname" : "iam-fips.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "iam.global.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "aws-global-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "iam-fips.amazonaws.com" + }, + "iam" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "iam-fips.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "iam-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "iam-fips.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "identity-chime" : { + "endpoints" : { + "eu-central-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "identity-chime-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "identity-chime-fips.us-east-1.amazonaws.com" + } + } + }, + "identitystore" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "importexport" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1", + "service" : "IngestionService" + }, + "hostname" : "importexport.amazonaws.com", + "signatureVersions" : [ "v2", "v4" ] + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "ingest.timestream" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-south-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "ingest-fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "ingest.timestream-fips.us-east-1.amazonaws.com" + }, + "ingest-fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "ingest.timestream-fips.us-east-2.amazonaws.com" + }, + "ingest-fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "ingest.timestream-fips.us-west-2.amazonaws.com" + }, + "ingest-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "ingest.timestream-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ingest-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "ingest.timestream-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ingest-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "ingest.timestream-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "inspector" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "inspector-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "inspector-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "inspector-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "inspector-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "inspector-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "inspector-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "inspector-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "inspector-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "inspector2" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "inspector2-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "inspector2-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "inspector2-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "inspector2-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "inspector2-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "inspector2-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "inspector2-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "inspector2-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "internetmonitor" : { + "defaults" : { + "dnsSuffix" : "api.aws", + "variants" : [ { + "dnsSuffix" : "api.aws", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "af-south-1" : { + "hostname" : "internetmonitor.af-south-1.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "hostname" : "internetmonitor.ap-east-1.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "hostname" : "internetmonitor.ap-northeast-1.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "hostname" : "internetmonitor.ap-northeast-2.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "hostname" : "internetmonitor.ap-northeast-3.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "hostname" : "internetmonitor.ap-south-1.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "hostname" : "internetmonitor.ap-south-2.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "hostname" : "internetmonitor.ap-southeast-1.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "hostname" : "internetmonitor.ap-southeast-2.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "hostname" : "internetmonitor.ap-southeast-3.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "hostname" : "internetmonitor.ap-southeast-4.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "hostname" : "internetmonitor.ap-southeast-5.api.aws" + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "hostname" : "internetmonitor.ap-southeast-7.api.aws" + }, + "ca-central-1" : { + "hostname" : "internetmonitor.ca-central-1.api.aws", + "variants" : [ { + "hostname" : "internetmonitor-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "internetmonitor-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "internetmonitor.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "hostname" : "internetmonitor.ca-west-1.api.aws" + }, + "eu-central-1" : { + "hostname" : "internetmonitor.eu-central-1.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "hostname" : "internetmonitor.eu-central-2.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "hostname" : "internetmonitor.eu-north-1.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "hostname" : "internetmonitor.eu-south-1.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "hostname" : "internetmonitor.eu-south-2.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "hostname" : "internetmonitor.eu-west-1.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "hostname" : "internetmonitor.eu-west-2.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "hostname" : "internetmonitor.eu-west-3.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "il-central-1" : { + "hostname" : "internetmonitor.il-central-1.api.aws" + }, + "me-central-1" : { + "hostname" : "internetmonitor.me-central-1.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "hostname" : "internetmonitor.me-south-1.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "hostname" : "internetmonitor.mx-central-1.api.aws" + }, + "sa-east-1" : { + "hostname" : "internetmonitor.sa-east-1.api.aws", + "variants" : [ { + "hostname" : "internetmonitor.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "hostname" : "internetmonitor.us-east-1.api.aws", + "variants" : [ { + "hostname" : "internetmonitor-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "internetmonitor-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "internetmonitor.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "hostname" : "internetmonitor.us-east-2.api.aws", + "variants" : [ { + "hostname" : "internetmonitor-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "internetmonitor-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "internetmonitor.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "hostname" : "internetmonitor.us-west-1.api.aws", + "variants" : [ { + "hostname" : "internetmonitor-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "internetmonitor-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "internetmonitor.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "hostname" : "internetmonitor.us-west-2.api.aws", + "variants" : [ { + "hostname" : "internetmonitor-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "internetmonitor-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "internetmonitor.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "iot" : { + "endpoints" : { + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-5" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "iot-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "deprecated" : true, + "hostname" : "iot-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "deprecated" : true, + "hostname" : "iot-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "deprecated" : true, + "hostname" : "iot-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "deprecated" : true, + "hostname" : "iot-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "deprecated" : true, + "hostname" : "iot-fips.us-west-2.amazonaws.com" + }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "iot-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "iot-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "iot-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "iot-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "iotanalytics" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-south-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "iotevents" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "iotevents-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "iotevents-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "iotevents-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "iotevents-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "iotevents-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "iotevents-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "iotevents-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "iotevents-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "ioteventsdata" : { + "endpoints" : { + "ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "data.iotevents.ap-northeast-1.amazonaws.com" + }, + "ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "hostname" : "data.iotevents.ap-northeast-2.amazonaws.com" + }, + "ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "hostname" : "data.iotevents.ap-south-1.amazonaws.com" + }, + "ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "data.iotevents.ap-southeast-1.amazonaws.com" + }, + "ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "data.iotevents.ap-southeast-2.amazonaws.com" + }, + "ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "hostname" : "data.iotevents.ca-central-1.amazonaws.com", + "variants" : [ { + "hostname" : "data.iotevents-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "data.iotevents.eu-central-1.amazonaws.com" + }, + "eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "data.iotevents.eu-west-1.amazonaws.com" + }, + "eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "hostname" : "data.iotevents.eu-west-2.amazonaws.com" + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "data.iotevents-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "data.iotevents-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "data.iotevents-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "data.iotevents-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "data.iotevents.us-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "data.iotevents-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "data.iotevents.us-east-2.amazonaws.com", + "variants" : [ { + "hostname" : "data.iotevents-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "data.iotevents.us-west-2.amazonaws.com", + "variants" : [ { + "hostname" : "data.iotevents-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "iotfleetwise" : { + "endpoints" : { + "ap-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + } + } + }, + "iotsecuredtunneling" : { + "defaults" : { + "variants" : [ { + "hostname" : "api.tunneling.iot-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "api.tunneling.iot-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "api.tunneling.iot-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "api.tunneling.iot-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "api.tunneling.iot-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "api.tunneling.iot-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "api.tunneling.iot-fips.us-west-2.amazonaws.com" + }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "api.tunneling.iot-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "api.tunneling.iot-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "api.tunneling.iot-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "api.tunneling.iot-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "iotsitewise" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "iotsitewise-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "iotsitewise-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "iotsitewise-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "iotsitewise-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "iotsitewise-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "iotsitewise-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "iotsitewise-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "iotsitewise-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "iotthingsgraph" : { + "defaults" : { + "credentialScope" : { + "service" : "iotthingsgraph" + } + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-2" : { }, + "eu-west-1" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "iottwinmaker" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "api-ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "api.iottwinmaker.ap-northeast-1.amazonaws.com" + }, + "api-ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "hostname" : "api.iottwinmaker.ap-northeast-2.amazonaws.com" + }, + "api-ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "hostname" : "api.iottwinmaker.ap-south-1.amazonaws.com" + }, + "api-ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "api.iottwinmaker.ap-southeast-1.amazonaws.com" + }, + "api-ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "api.iottwinmaker.ap-southeast-2.amazonaws.com" + }, + "api-eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "api.iottwinmaker.eu-central-1.amazonaws.com" + }, + "api-eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "api.iottwinmaker.eu-west-1.amazonaws.com" + }, + "api-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "api.iottwinmaker.us-east-1.amazonaws.com" + }, + "api-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "api.iottwinmaker.us-west-2.amazonaws.com" + }, + "data-ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "data.iottwinmaker.ap-northeast-1.amazonaws.com" + }, + "data-ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "hostname" : "data.iottwinmaker.ap-northeast-2.amazonaws.com" + }, + "data-ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "hostname" : "data.iottwinmaker.ap-south-1.amazonaws.com" + }, + "data-ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "data.iottwinmaker.ap-southeast-1.amazonaws.com" + }, + "data-ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "data.iottwinmaker.ap-southeast-2.amazonaws.com" + }, + "data-eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "data.iottwinmaker.eu-central-1.amazonaws.com" + }, + "data-eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "data.iottwinmaker.eu-west-1.amazonaws.com" + }, + "data-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "data.iottwinmaker.us-east-1.amazonaws.com" + }, + "data-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "data.iottwinmaker.us-west-2.amazonaws.com" + }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "fips-api-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "api.iottwinmaker-fips.us-east-1.amazonaws.com" + }, + "fips-api-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "api.iottwinmaker-fips.us-west-2.amazonaws.com" + }, + "fips-data-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "data.iottwinmaker-fips.us-east-1.amazonaws.com" + }, + "fips-data-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "data.iottwinmaker-fips.us-west-2.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "iottwinmaker-fips.us-east-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "iottwinmaker-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "iottwinmaker-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "iottwinmaker-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "iotwireless" : { + "endpoints" : { + "ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "api.iotwireless.ap-northeast-1.amazonaws.com" + }, + "ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "api.iotwireless.ap-southeast-2.amazonaws.com" + }, + "eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "api.iotwireless.eu-west-1.amazonaws.com" + }, + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "api.iotwireless.us-east-1.amazonaws.com" + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "api.iotwireless.us-west-2.amazonaws.com" + } + } + }, + "ivs" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "ivschat" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "ivsrealtime" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "kafka" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "kafka-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "kafka-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "kafka-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "kafka-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "kafka-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "kafka-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "kafka-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "kafka-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "kafka-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "kafka-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "kafka-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "kafka-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "kafkaconnect" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "kendra" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "kendra-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "kendra-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "kendra-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "kendra-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "kendra-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "kendra-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "kendra-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "kendra-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "kendra-ranking" : { + "defaults" : { + "dnsSuffix" : "api.aws", + "variants" : [ { + "dnsSuffix" : "api.aws", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "af-south-1" : { + "hostname" : "kendra-ranking.af-south-1.api.aws" + }, + "ap-east-1" : { + "hostname" : "kendra-ranking.ap-east-1.api.aws" + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "hostname" : "kendra-ranking.ap-northeast-1.api.aws" + }, + "ap-northeast-2" : { + "hostname" : "kendra-ranking.ap-northeast-2.api.aws" + }, + "ap-northeast-3" : { + "hostname" : "kendra-ranking.ap-northeast-3.api.aws" + }, + "ap-south-1" : { + "hostname" : "kendra-ranking.ap-south-1.api.aws" + }, + "ap-south-2" : { + "hostname" : "kendra-ranking.ap-south-2.api.aws" + }, + "ap-southeast-1" : { + "hostname" : "kendra-ranking.ap-southeast-1.api.aws" + }, + "ap-southeast-2" : { + "hostname" : "kendra-ranking.ap-southeast-2.api.aws" + }, + "ap-southeast-3" : { + "hostname" : "kendra-ranking.ap-southeast-3.api.aws" + }, + "ap-southeast-4" : { + "hostname" : "kendra-ranking.ap-southeast-4.api.aws" + }, + "ap-southeast-5" : { + "hostname" : "kendra-ranking.ap-southeast-5.api.aws" + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "hostname" : "kendra-ranking.ap-southeast-7.api.aws" + }, + "ca-central-1" : { + "hostname" : "kendra-ranking.ca-central-1.api.aws", + "variants" : [ { + "hostname" : "kendra-ranking-fips.ca-central-1.api.aws", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "hostname" : "kendra-ranking.ca-west-1.api.aws" + }, + "eu-central-2" : { + "hostname" : "kendra-ranking.eu-central-2.api.aws" + }, + "eu-north-1" : { + "hostname" : "kendra-ranking.eu-north-1.api.aws" + }, + "eu-south-1" : { + "hostname" : "kendra-ranking.eu-south-1.api.aws" + }, + "eu-south-2" : { + "hostname" : "kendra-ranking.eu-south-2.api.aws" + }, + "eu-west-1" : { + "hostname" : "kendra-ranking.eu-west-1.api.aws" + }, + "eu-west-3" : { + "hostname" : "kendra-ranking.eu-west-3.api.aws" + }, + "il-central-1" : { + "hostname" : "kendra-ranking.il-central-1.api.aws" + }, + "me-central-1" : { + "hostname" : "kendra-ranking.me-central-1.api.aws" + }, + "me-south-1" : { + "hostname" : "kendra-ranking.me-south-1.api.aws" + }, + "mx-central-1" : { + "hostname" : "kendra-ranking.mx-central-1.api.aws" + }, + "sa-east-1" : { + "hostname" : "kendra-ranking.sa-east-1.api.aws" + }, + "us-east-1" : { + "hostname" : "kendra-ranking.us-east-1.api.aws", + "variants" : [ { + "hostname" : "kendra-ranking-fips.us-east-1.api.aws", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "hostname" : "kendra-ranking.us-east-2.api.aws", + "variants" : [ { + "hostname" : "kendra-ranking-fips.us-east-2.api.aws", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "hostname" : "kendra-ranking.us-west-1.api.aws" + }, + "us-west-2" : { + "hostname" : "kendra-ranking.us-west-2.api.aws", + "variants" : [ { + "hostname" : "kendra-ranking-fips.us-west-2.api.aws", + "tags" : [ "fips" ] + } ] + } + } + }, + "kinesis" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "kinesis-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "kinesis-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "kinesis-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "kinesis-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "kinesis-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "kinesis-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "kinesis-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "kinesis-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "kinesisanalytics" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "kinesisanalytics-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "kinesisanalytics-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "kinesisanalytics-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "kinesisanalytics-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "kinesisanalytics-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "kinesisanalytics-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "kinesisanalytics-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "kinesisanalytics-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "kinesisanalytics-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "kinesisanalytics-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "kinesisanalytics-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "kinesisanalytics-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "kinesisvideo" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-5" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "kms" : { + "endpoints" : { + "ProdFips" : { + "credentialScope" : { + "region" : "eu-central-2" + }, + "deprecated" : true, + "hostname" : "kms-fips.eu-central-2.amazonaws.com" + }, + "af-south-1" : { + "variants" : [ { + "hostname" : "kms-fips.af-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "af-south-1-fips" : { + "credentialScope" : { + "region" : "af-south-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.af-south-1.amazonaws.com" + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "kms-fips.ap-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-east-1-fips" : { + "credentialScope" : { + "region" : "ap-east-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.ap-east-1.amazonaws.com" + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "kms-fips.ap-northeast-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-northeast-1-fips" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.ap-northeast-1.amazonaws.com" + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "kms-fips.ap-northeast-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-northeast-2-fips" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "deprecated" : true, + "hostname" : "kms-fips.ap-northeast-2.amazonaws.com" + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "kms-fips.ap-northeast-3.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-northeast-3-fips" : { + "credentialScope" : { + "region" : "ap-northeast-3" + }, + "deprecated" : true, + "hostname" : "kms-fips.ap-northeast-3.amazonaws.com" + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "kms-fips.ap-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-south-1-fips" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.ap-south-1.amazonaws.com" + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "kms-fips.ap-south-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-south-2-fips" : { + "credentialScope" : { + "region" : "ap-south-2" + }, + "deprecated" : true, + "hostname" : "kms-fips.ap-south-2.amazonaws.com" + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "kms-fips.ap-southeast-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-1-fips" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.ap-southeast-1.amazonaws.com" + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "kms-fips.ap-southeast-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-2-fips" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "deprecated" : true, + "hostname" : "kms-fips.ap-southeast-2.amazonaws.com" + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "kms-fips.ap-southeast-3.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-3-fips" : { + "credentialScope" : { + "region" : "ap-southeast-3" + }, + "deprecated" : true, + "hostname" : "kms-fips.ap-southeast-3.amazonaws.com" + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "kms-fips.ap-southeast-4.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-4-fips" : { + "credentialScope" : { + "region" : "ap-southeast-4" + }, + "deprecated" : true, + "hostname" : "kms-fips.ap-southeast-4.amazonaws.com" + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "kms-fips.ap-southeast-5.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-5-fips" : { + "credentialScope" : { + "region" : "ap-southeast-5" + }, + "deprecated" : true, + "hostname" : "kms-fips.ap-southeast-5.amazonaws.com" + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "kms-fips.ap-southeast-7.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-7-fips" : { + "credentialScope" : { + "region" : "ap-southeast-7" + }, + "deprecated" : true, + "hostname" : "kms-fips.ap-southeast-7.amazonaws.com" + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "kms-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.ca-central-1.amazonaws.com" + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "kms-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1-fips" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.ca-west-1.amazonaws.com" + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "kms-fips.eu-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1-fips" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.eu-central-1.amazonaws.com" + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "kms-fips.eu-central-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-2-fips" : { + "credentialScope" : { + "region" : "eu-central-2" + }, + "deprecated" : true, + "hostname" : "kms-fips.eu-central-2.amazonaws.com" + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "kms-fips.eu-north-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-north-1-fips" : { + "credentialScope" : { + "region" : "eu-north-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.eu-north-1.amazonaws.com" + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "kms-fips.eu-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-south-1-fips" : { + "credentialScope" : { + "region" : "eu-south-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.eu-south-1.amazonaws.com" + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "kms-fips.eu-south-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-south-2-fips" : { + "credentialScope" : { + "region" : "eu-south-2" + }, + "deprecated" : true, + "hostname" : "kms-fips.eu-south-2.amazonaws.com" + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "kms-fips.eu-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-west-1-fips" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.eu-west-1.amazonaws.com" + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "kms-fips.eu-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-west-2-fips" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "deprecated" : true, + "hostname" : "kms-fips.eu-west-2.amazonaws.com" + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "kms-fips.eu-west-3.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-west-3-fips" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "deprecated" : true, + "hostname" : "kms-fips.eu-west-3.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "kms-fips.il-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "il-central-1-fips" : { + "credentialScope" : { + "region" : "il-central-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.il-central-1.amazonaws.com" + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "kms-fips.me-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "me-central-1-fips" : { + "credentialScope" : { + "region" : "me-central-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.me-central-1.amazonaws.com" + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "kms-fips.me-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "me-south-1-fips" : { + "credentialScope" : { + "region" : "me-south-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.me-south-1.amazonaws.com" + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "kms-fips.mx-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "mx-central-1-fips" : { + "credentialScope" : { + "region" : "mx-central-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.mx-central-1.amazonaws.com" + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "kms-fips.sa-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "sa-east-1-fips" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.sa-east-1.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "kms-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "kms-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "kms-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "kms-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "kms-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "kms-fips.us-west-2.amazonaws.com" + } + } + }, + "lakeformation" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "lakeformation.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "lakeformation.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "lakeformation.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "lakeformation.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "lakeformation.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "lakeformation.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "lakeformation.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "lakeformation.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "lakeformation.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "lakeformation.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "lakeformation.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "lakeformation.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "lakeformation.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "lakeformation.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "lakeformation.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "lakeformation.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "lakeformation.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "lakeformation.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "lakeformation.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "lakeformation.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "lakeformation.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "lakeformation.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "lakeformation.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "lakeformation-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "lakeformation-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "lakeformation-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "lakeformation-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "lakeformation.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "lakeformation.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "lakeformation.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "lakeformation.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "lakeformation.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "lakeformation-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "lakeformation-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "lakeformation.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "lakeformation-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "lakeformation-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "lakeformation.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "lakeformation-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "lakeformation-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "lakeformation.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "lakeformation-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "lakeformation-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "lakeformation.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "lambda" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "lambda.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "lambda.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "lambda.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "lambda.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "lambda.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "lambda.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "lambda.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "lambda.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "lambda.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "lambda.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "lambda.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "lambda.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "lambda.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "lambda.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "lambda.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "lambda.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "lambda.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "lambda.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "lambda.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "lambda.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "lambda.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "lambda.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "lambda.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "lambda-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "lambda-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "lambda-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "lambda-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "lambda.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "lambda.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "lambda.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "lambda.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "lambda.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "lambda-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "lambda.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "lambda-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "lambda.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "lambda-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "lambda.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "lambda-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "lambda.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "license-manager" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "license-manager-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "license-manager-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "license-manager-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "license-manager-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "license-manager-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "license-manager-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "license-manager-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "license-manager-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "license-manager-linux-subscriptions" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "license-manager-linux-subscriptions-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "license-manager-linux-subscriptions-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "license-manager-linux-subscriptions-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "license-manager-linux-subscriptions-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "license-manager-linux-subscriptions-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "license-manager-linux-subscriptions-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "license-manager-linux-subscriptions-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "license-manager-linux-subscriptions-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "license-manager-user-subscriptions" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "license-manager-user-subscriptions-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "license-manager-user-subscriptions-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "license-manager-user-subscriptions-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "license-manager-user-subscriptions-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "license-manager-user-subscriptions-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "license-manager-user-subscriptions-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "license-manager-user-subscriptions-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "license-manager-user-subscriptions-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "lightsail" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "logs" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "logs.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "logs.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "logs.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "logs.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "logs.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "logs.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "logs.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "logs.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "logs.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "logs.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "logs.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "logs-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "logs.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "logs-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "logs.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "logs.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "logs.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "logs.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "logs.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "logs.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "logs.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "logs.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "logs.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "logs-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "logs-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "logs-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "logs-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "logs-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "logs-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "logs.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "logs.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "logs.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "logs.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "logs-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "logs.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "logs-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "logs.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "logs-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "logs.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "logs-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "logs.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "lookoutequipment" : { + "endpoints" : { + "ap-northeast-2" : { }, + "eu-west-1" : { }, + "us-east-1" : { } + } + }, + "m2" : { + "endpoints" : { + "af-south-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "deprecated" : true + }, + "fips-us-east-1" : { + "deprecated" : true + }, + "fips-us-east-2" : { + "deprecated" : true + }, + "fips-us-west-1" : { + "deprecated" : true + }, + "fips-us-west-2" : { + "deprecated" : true + }, + "il-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + } + } + }, + "machinelearning" : { + "endpoints" : { + "eu-west-1" : { }, + "us-east-1" : { } + } + }, + "macie2" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "macie2.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "macie2.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "macie2.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "macie2.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "macie2.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "macie2.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "macie2.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "macie2.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "macie2.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "macie2.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "macie2.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "macie2.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "macie2.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "macie2.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "macie2.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "macie2-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "macie2-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "macie2-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "macie2-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "macie2.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "macie2.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "macie2.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "macie2-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "macie2-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "macie2.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "macie2-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "macie2-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "macie2.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "macie2-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "macie2-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "macie2.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "macie2-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "macie2-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "macie2.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "managedblockchain" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { } + } + }, + "managedblockchain-query" : { + "endpoints" : { + "us-east-1" : { } + } + }, + "marketplacecommerceanalytics" : { + "endpoints" : { + "us-east-1" : { } + } + }, + "media-pipelines-chime" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "media-pipelines-chime-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "media-pipelines-chime-fips.us-east-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "media-pipelines-chime-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "media-pipelines-chime-fips.us-west-2.amazonaws.com" + } + } + }, + "mediaconnect" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-4" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "me-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "mediaconvert" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "mediaconvert.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "mediaconvert.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "mediaconvert.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "mediaconvert.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "mediaconvert.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "mediaconvert.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "mediaconvert.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "mediaconvert.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "mediaconvert-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "mediaconvert-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "mediaconvert.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "mediaconvert.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "mediaconvert.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "mediaconvert.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "mediaconvert.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "mediaconvert.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "mediaconvert-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "mediaconvert-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "mediaconvert-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "mediaconvert-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "mediaconvert-fips.us-west-2.amazonaws.com" + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "mediaconvert.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "mediaconvert.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "mediaconvert-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "mediaconvert-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "mediaconvert.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "mediaconvert-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "mediaconvert-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "mediaconvert.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "mediaconvert-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "mediaconvert-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "mediaconvert.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "mediaconvert-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "mediaconvert-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "mediaconvert.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "medialive" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-4" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "medialive-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "medialive-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "medialive-fips.us-west-2.amazonaws.com" + }, + "me-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "medialive-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "medialive-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "medialive-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "mediapackage" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-4" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "mediapackage-vod" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-4" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "me-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "mediapackagev2" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-4" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "mediapackagev2-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "mediapackagev2-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "mediapackagev2-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "mediapackagev2-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "mediapackagev2-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "mediapackagev2-fips.us-west-2.amazonaws.com" + }, + "me-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "mediapackagev2-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "mediapackagev2-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "mediapackagev2-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "mediapackagev2-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "mediastore" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "meetings-chime" : { + "endpoints" : { + "af-south-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "meetings-chime-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "meetings-chime-fips.ca-central-1.amazonaws.com" + }, + "eu-central-1" : { }, + "eu-west-2" : { }, + "il-central-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "meetings-chime-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "meetings-chime-fips.us-east-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "meetings-chime-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "meetings-chime-fips.us-west-2.amazonaws.com" + } + } + }, + "memory-db" : { + "endpoints" : { + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "hostname" : "memory-db-fips.us-west-1.amazonaws.com" + }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "messaging-chime" : { + "endpoints" : { + "eu-central-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "messaging-chime-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "messaging-chime-fips.us-east-1.amazonaws.com" + } + } + }, + "metering.marketplace" : { + "defaults" : { + "credentialScope" : { + "service" : "aws-marketplace" + } + }, + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "metering-marketplace.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "metering-marketplace.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "metering-marketplace.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "metering-marketplace.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "metering-marketplace.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "metering-marketplace.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "metering-marketplace.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "metering-marketplace.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "metering-marketplace.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "metering-marketplace.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "metering-marketplace.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "metering-marketplace.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "metrics.sagemaker" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "metrics-fips.sagemaker.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "metrics-fips.sagemaker.ca-central-1.amazonaws.com" + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "metrics-fips.sagemaker.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1-fips" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "metrics-fips.sagemaker.ca-west-1.amazonaws.com" + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "metrics-fips.sagemaker.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "metrics-fips.sagemaker.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "metrics-fips.sagemaker.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "metrics-fips.sagemaker.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "metrics-fips.sagemaker.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "metrics-fips.sagemaker.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "metrics-fips.sagemaker.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "metrics-fips.sagemaker.us-west-2.amazonaws.com" + } + } + }, + "mgh" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "mgn" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "mgn-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "mgn-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "mgn-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "mgn-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "mgn-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "mgn-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "mgn-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "mgn-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "migrationhub-orchestrator" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "migrationhub-strategy" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "mobileanalytics" : { + "endpoints" : { + "us-east-1" : { } + } + }, + "models-v2-lex" : { + "endpoints" : { + "af-south-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "models.lex" : { + "defaults" : { + "credentialScope" : { + "service" : "lex" + }, + "variants" : [ { + "hostname" : "models-fips.lex.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "models-fips.lex.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "models-fips.lex.us-east-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "models-fips.lex.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "models-fips.lex.us-west-2.amazonaws.com" + } + } + }, + "monitoring" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "monitoring-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "monitoring-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "monitoring-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "monitoring-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "monitoring-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "monitoring-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "monitoring-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "monitoring-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "mq" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "mq-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "mq-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "mq-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "mq-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "mq-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "mq-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "mq-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "mq-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "mturk-requester" : { + "endpoints" : { + "sandbox" : { + "hostname" : "mturk-requester-sandbox.us-east-1.amazonaws.com" + }, + "us-east-1" : { } + }, + "isRegionalized" : false + }, + "neptune" : { + "endpoints" : { + "ap-east-1" : { + "credentialScope" : { + "region" : "ap-east-1" + }, + "hostname" : "rds.ap-east-1.amazonaws.com" + }, + "ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "rds.ap-northeast-1.amazonaws.com" + }, + "ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "hostname" : "rds.ap-northeast-2.amazonaws.com" + }, + "ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "hostname" : "rds.ap-south-1.amazonaws.com" + }, + "ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "rds.ap-southeast-1.amazonaws.com" + }, + "ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "rds.ap-southeast-2.amazonaws.com" + }, + "ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "hostname" : "rds.ca-central-1.amazonaws.com" + }, + "eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "rds.eu-central-1.amazonaws.com" + }, + "eu-north-1" : { + "credentialScope" : { + "region" : "eu-north-1" + }, + "hostname" : "rds.eu-north-1.amazonaws.com" + }, + "eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "rds.eu-west-1.amazonaws.com" + }, + "eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "hostname" : "rds.eu-west-2.amazonaws.com" + }, + "eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "hostname" : "rds.eu-west-3.amazonaws.com" + }, + "me-south-1" : { + "credentialScope" : { + "region" : "me-south-1" + }, + "hostname" : "rds.me-south-1.amazonaws.com" + }, + "sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "hostname" : "rds.sa-east-1.amazonaws.com" + }, + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "rds.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "rds.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "hostname" : "rds.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "rds.us-west-2.amazonaws.com" + } + } + }, + "network-firewall" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "network-firewall-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "network-firewall-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "network-firewall-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "network-firewall-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "network-firewall-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "network-firewall-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "network-firewall-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "network-firewall-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "network-firewall-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "network-firewall-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "networkmanager" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "networkmanager.us-west-2.amazonaws.com", + "variants" : [ { + "hostname" : "networkmanager-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "networkmanager-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "networkmanager.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-aws-global" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "networkmanager-fips.us-west-2.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "notifications" : { + "defaults" : { + "dnsSuffix" : "api.aws", + "variants" : [ { + "dnsSuffix" : "api.aws", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "af-south-1" : { + "hostname" : "notifications.af-south-1.api.aws" + }, + "ap-east-1" : { + "hostname" : "notifications.ap-east-1.api.aws" + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "hostname" : "notifications.ap-northeast-1.api.aws" + }, + "ap-northeast-2" : { + "hostname" : "notifications.ap-northeast-2.api.aws" + }, + "ap-northeast-3" : { + "hostname" : "notifications.ap-northeast-3.api.aws" + }, + "ap-south-1" : { + "hostname" : "notifications.ap-south-1.api.aws" + }, + "ap-south-2" : { + "hostname" : "notifications.ap-south-2.api.aws" + }, + "ap-southeast-1" : { + "hostname" : "notifications.ap-southeast-1.api.aws" + }, + "ap-southeast-2" : { + "hostname" : "notifications.ap-southeast-2.api.aws" + }, + "ap-southeast-3" : { + "hostname" : "notifications.ap-southeast-3.api.aws" + }, + "ap-southeast-4" : { + "hostname" : "notifications.ap-southeast-4.api.aws" + }, + "ap-southeast-5" : { + "hostname" : "notifications.ap-southeast-5.api.aws" + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "hostname" : "notifications.ap-southeast-7.api.aws" + }, + "ca-central-1" : { + "hostname" : "notifications.ca-central-1.api.aws" + }, + "ca-west-1" : { + "hostname" : "notifications.ca-west-1.api.aws" + }, + "eu-central-1" : { + "hostname" : "notifications.eu-central-1.api.aws" + }, + "eu-central-2" : { + "hostname" : "notifications.eu-central-2.api.aws" + }, + "eu-north-1" : { + "hostname" : "notifications.eu-north-1.api.aws" + }, + "eu-south-1" : { + "hostname" : "notifications.eu-south-1.api.aws" + }, + "eu-south-2" : { + "hostname" : "notifications.eu-south-2.api.aws" + }, + "eu-west-1" : { + "hostname" : "notifications.eu-west-1.api.aws" + }, + "eu-west-2" : { + "hostname" : "notifications.eu-west-2.api.aws" + }, + "eu-west-3" : { + "hostname" : "notifications.eu-west-3.api.aws" + }, + "il-central-1" : { + "hostname" : "notifications.il-central-1.api.aws" + }, + "me-central-1" : { + "hostname" : "notifications.me-central-1.api.aws" + }, + "me-south-1" : { + "hostname" : "notifications.me-south-1.api.aws" + }, + "mx-central-1" : { + "hostname" : "notifications.mx-central-1.api.aws" + }, + "sa-east-1" : { + "hostname" : "notifications.sa-east-1.api.aws" + }, + "us-east-1" : { + "hostname" : "notifications.us-east-1.api.aws" + }, + "us-east-2" : { + "hostname" : "notifications.us-east-2.api.aws" + }, + "us-west-1" : { + "hostname" : "notifications.us-west-1.api.aws" + }, + "us-west-2" : { + "hostname" : "notifications.us-west-2.api.aws" + } + } + }, + "notifications-contacts" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "notifications-contacts.us-east-1.api.aws" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "nova-act" : { + "endpoints" : { + "us-east-1" : { } + } + }, + "oam" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "oidc" : { + "endpoints" : { + "af-south-1" : { + "credentialScope" : { + "region" : "af-south-1" + }, + "hostname" : "oidc.af-south-1.amazonaws.com" + }, + "ap-east-1" : { + "credentialScope" : { + "region" : "ap-east-1" + }, + "hostname" : "oidc.ap-east-1.amazonaws.com" + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "oidc.ap-northeast-1.amazonaws.com" + }, + "ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "hostname" : "oidc.ap-northeast-2.amazonaws.com" + }, + "ap-northeast-3" : { + "credentialScope" : { + "region" : "ap-northeast-3" + }, + "hostname" : "oidc.ap-northeast-3.amazonaws.com" + }, + "ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "hostname" : "oidc.ap-south-1.amazonaws.com" + }, + "ap-south-2" : { + "credentialScope" : { + "region" : "ap-south-2" + }, + "hostname" : "oidc.ap-south-2.amazonaws.com" + }, + "ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "oidc.ap-southeast-1.amazonaws.com" + }, + "ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "oidc.ap-southeast-2.amazonaws.com" + }, + "ap-southeast-3" : { + "credentialScope" : { + "region" : "ap-southeast-3" + }, + "hostname" : "oidc.ap-southeast-3.amazonaws.com" + }, + "ap-southeast-4" : { + "credentialScope" : { + "region" : "ap-southeast-4" + }, + "hostname" : "oidc.ap-southeast-4.amazonaws.com" + }, + "ap-southeast-5" : { + "credentialScope" : { + "region" : "ap-southeast-5" + }, + "hostname" : "oidc.ap-southeast-5.amazonaws.com" + }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "hostname" : "oidc.ca-central-1.amazonaws.com" + }, + "ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "hostname" : "oidc.ca-west-1.amazonaws.com" + }, + "eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "oidc.eu-central-1.amazonaws.com" + }, + "eu-central-2" : { + "credentialScope" : { + "region" : "eu-central-2" + }, + "hostname" : "oidc.eu-central-2.amazonaws.com" + }, + "eu-north-1" : { + "credentialScope" : { + "region" : "eu-north-1" + }, + "hostname" : "oidc.eu-north-1.amazonaws.com" + }, + "eu-south-1" : { + "credentialScope" : { + "region" : "eu-south-1" + }, + "hostname" : "oidc.eu-south-1.amazonaws.com" + }, + "eu-south-2" : { + "credentialScope" : { + "region" : "eu-south-2" + }, + "hostname" : "oidc.eu-south-2.amazonaws.com" + }, + "eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "oidc.eu-west-1.amazonaws.com" + }, + "eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "hostname" : "oidc.eu-west-2.amazonaws.com" + }, + "eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "hostname" : "oidc.eu-west-3.amazonaws.com" + }, + "il-central-1" : { + "credentialScope" : { + "region" : "il-central-1" + }, + "hostname" : "oidc.il-central-1.amazonaws.com" + }, + "me-central-1" : { + "credentialScope" : { + "region" : "me-central-1" + }, + "hostname" : "oidc.me-central-1.amazonaws.com" + }, + "me-south-1" : { + "credentialScope" : { + "region" : "me-south-1" + }, + "hostname" : "oidc.me-south-1.amazonaws.com" + }, + "mx-central-1" : { }, + "sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "hostname" : "oidc.sa-east-1.amazonaws.com" + }, + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "oidc.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "oidc.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "hostname" : "oidc.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "oidc.us-west-2.amazonaws.com" + } + } + }, + "omics" : { + "endpoints" : { + "ap-northeast-2" : { }, + "ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "omics.ap-southeast-1.amazonaws.com" + }, + "eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "omics.eu-central-1.amazonaws.com" + }, + "eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "omics.eu-west-1.amazonaws.com" + }, + "eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "hostname" : "omics.eu-west-2.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "omics-fips.us-east-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "omics-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "credentialScope" : { + "region" : "il-central-1" + }, + "hostname" : "omics.il-central-1.amazonaws.com" + }, + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "omics.us-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "omics-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "omics.us-west-2.amazonaws.com", + "variants" : [ { + "hostname" : "omics-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "organizations" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "organizations.us-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "organizations-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "fips-aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "organizations-fips.us-east-1.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "osis" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "outposts" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "outposts-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "outposts-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "outposts-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "outposts-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "outposts-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "outposts-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "outposts-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "outposts-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "outposts-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "outposts-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "participant.connect" : { + "endpoints" : { + "af-south-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-2" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "participant.connect-fips.us-east-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "participant.connect-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "participant.connect-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "participant.connect-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "partnercentral-channel" : { + "endpoints" : { + "us-east-1" : { } + } + }, + "personalize" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "pi" : { + "endpoints" : { + "af-south-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "pi-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "pi.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "pi-fips.ca-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "pi.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "pi-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "pi-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "pi-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "pi-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "pi-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "pi-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "pi-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "pi.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "pi-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "pi.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "pi-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "pi.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "pi-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "pi.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "pinpoint" : { + "defaults" : { + "credentialScope" : { + "service" : "mobiletargeting" + } + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "hostname" : "pinpoint.ca-central-1.amazonaws.com", + "variants" : [ { + "hostname" : "pinpoint-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "pinpoint-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "pinpoint-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "pinpoint-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "pinpoint-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "pinpoint.us-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "pinpoint-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "pinpoint.us-east-2.amazonaws.com", + "variants" : [ { + "hostname" : "pinpoint-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "pinpoint.us-west-2.amazonaws.com", + "variants" : [ { + "hostname" : "pinpoint-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "pipes" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "polly" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "polly.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "polly.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "polly.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "polly.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "polly.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "polly.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "polly.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "polly.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "polly.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "polly-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "polly-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "polly.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "polly.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "polly.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "polly.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "polly.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "polly.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "polly.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "polly-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "polly-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "polly-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "polly-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "polly-fips.us-west-2.amazonaws.com" + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "polly.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "polly.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "polly-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "polly-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "polly.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "polly-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "polly-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "polly.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "polly-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "polly-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "polly.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "polly-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "polly-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "polly.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "portal.sso" : { + "endpoints" : { + "af-south-1" : { + "credentialScope" : { + "region" : "af-south-1" + }, + "hostname" : "portal.sso.af-south-1.amazonaws.com" + }, + "ap-east-1" : { + "credentialScope" : { + "region" : "ap-east-1" + }, + "hostname" : "portal.sso.ap-east-1.amazonaws.com" + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "portal.sso.ap-northeast-1.amazonaws.com" + }, + "ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "hostname" : "portal.sso.ap-northeast-2.amazonaws.com" + }, + "ap-northeast-3" : { + "credentialScope" : { + "region" : "ap-northeast-3" + }, + "hostname" : "portal.sso.ap-northeast-3.amazonaws.com" + }, + "ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "hostname" : "portal.sso.ap-south-1.amazonaws.com" + }, + "ap-south-2" : { + "credentialScope" : { + "region" : "ap-south-2" + }, + "hostname" : "portal.sso.ap-south-2.amazonaws.com" + }, + "ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "portal.sso.ap-southeast-1.amazonaws.com" + }, + "ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "portal.sso.ap-southeast-2.amazonaws.com" + }, + "ap-southeast-3" : { + "credentialScope" : { + "region" : "ap-southeast-3" + }, + "hostname" : "portal.sso.ap-southeast-3.amazonaws.com" + }, + "ap-southeast-4" : { + "credentialScope" : { + "region" : "ap-southeast-4" + }, + "hostname" : "portal.sso.ap-southeast-4.amazonaws.com" + }, + "ap-southeast-5" : { + "credentialScope" : { + "region" : "ap-southeast-5" + }, + "hostname" : "portal.sso.ap-southeast-5.amazonaws.com" + }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "hostname" : "portal.sso.ca-central-1.amazonaws.com" + }, + "ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "hostname" : "portal.sso.ca-west-1.amazonaws.com" + }, + "eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "portal.sso.eu-central-1.amazonaws.com" + }, + "eu-central-2" : { + "credentialScope" : { + "region" : "eu-central-2" + }, + "hostname" : "portal.sso.eu-central-2.amazonaws.com" + }, + "eu-north-1" : { + "credentialScope" : { + "region" : "eu-north-1" + }, + "hostname" : "portal.sso.eu-north-1.amazonaws.com" + }, + "eu-south-1" : { + "credentialScope" : { + "region" : "eu-south-1" + }, + "hostname" : "portal.sso.eu-south-1.amazonaws.com" + }, + "eu-south-2" : { + "credentialScope" : { + "region" : "eu-south-2" + }, + "hostname" : "portal.sso.eu-south-2.amazonaws.com" + }, + "eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "portal.sso.eu-west-1.amazonaws.com" + }, + "eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "hostname" : "portal.sso.eu-west-2.amazonaws.com" + }, + "eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "hostname" : "portal.sso.eu-west-3.amazonaws.com" + }, + "il-central-1" : { + "credentialScope" : { + "region" : "il-central-1" + }, + "hostname" : "portal.sso.il-central-1.amazonaws.com" + }, + "me-central-1" : { + "credentialScope" : { + "region" : "me-central-1" + }, + "hostname" : "portal.sso.me-central-1.amazonaws.com" + }, + "me-south-1" : { + "credentialScope" : { + "region" : "me-south-1" + }, + "hostname" : "portal.sso.me-south-1.amazonaws.com" + }, + "mx-central-1" : { }, + "sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "hostname" : "portal.sso.sa-east-1.amazonaws.com" + }, + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "portal.sso.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "portal.sso.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "hostname" : "portal.sso.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "portal.sso.us-west-2.amazonaws.com" + } + } + }, + "profile" : { + "endpoints" : { + "af-south-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "profile-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-west-2" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "profile-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "profile-fips.us-east-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "profile-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "profile-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "profile-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "proton" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "qbusiness" : { + "defaults" : { + "dnsSuffix" : "api.aws", + "variants" : [ { + "dnsSuffix" : "api.aws", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "af-south-1" : { + "hostname" : "qbusiness.af-south-1.api.aws" + }, + "ap-east-1" : { + "hostname" : "qbusiness.ap-east-1.api.aws" + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "hostname" : "qbusiness.ap-northeast-1.api.aws" + }, + "ap-northeast-2" : { + "hostname" : "qbusiness.ap-northeast-2.api.aws" + }, + "ap-northeast-3" : { + "hostname" : "qbusiness.ap-northeast-3.api.aws" + }, + "ap-south-1" : { + "hostname" : "qbusiness.ap-south-1.api.aws" + }, + "ap-south-2" : { + "hostname" : "qbusiness.ap-south-2.api.aws" + }, + "ap-southeast-1" : { + "hostname" : "qbusiness.ap-southeast-1.api.aws" + }, + "ap-southeast-2" : { + "hostname" : "qbusiness.ap-southeast-2.api.aws" + }, + "ap-southeast-3" : { + "hostname" : "qbusiness.ap-southeast-3.api.aws" + }, + "ap-southeast-4" : { + "hostname" : "qbusiness.ap-southeast-4.api.aws" + }, + "ap-southeast-5" : { + "hostname" : "qbusiness.ap-southeast-5.api.aws" + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "hostname" : "qbusiness.ap-southeast-7.api.aws" + }, + "ca-central-1" : { + "hostname" : "qbusiness.ca-central-1.api.aws" + }, + "ca-west-1" : { + "hostname" : "qbusiness.ca-west-1.api.aws" + }, + "eu-central-1" : { + "hostname" : "qbusiness.eu-central-1.api.aws" + }, + "eu-central-2" : { + "hostname" : "qbusiness.eu-central-2.api.aws" + }, + "eu-north-1" : { + "hostname" : "qbusiness.eu-north-1.api.aws" + }, + "eu-south-1" : { + "hostname" : "qbusiness.eu-south-1.api.aws" + }, + "eu-south-2" : { + "hostname" : "qbusiness.eu-south-2.api.aws" + }, + "eu-west-1" : { + "hostname" : "qbusiness.eu-west-1.api.aws" + }, + "eu-west-2" : { + "hostname" : "qbusiness.eu-west-2.api.aws" + }, + "eu-west-3" : { + "hostname" : "qbusiness.eu-west-3.api.aws" + }, + "il-central-1" : { + "hostname" : "qbusiness.il-central-1.api.aws" + }, + "me-central-1" : { + "hostname" : "qbusiness.me-central-1.api.aws" + }, + "me-south-1" : { + "hostname" : "qbusiness.me-south-1.api.aws" + }, + "mx-central-1" : { + "hostname" : "qbusiness.mx-central-1.api.aws" + }, + "sa-east-1" : { + "hostname" : "qbusiness.sa-east-1.api.aws" + }, + "us-east-1" : { + "hostname" : "qbusiness.us-east-1.api.aws" + }, + "us-east-2" : { + "hostname" : "qbusiness.us-east-2.api.aws" + }, + "us-west-1" : { + "hostname" : "qbusiness.us-west-1.api.aws" + }, + "us-west-2" : { + "hostname" : "qbusiness.us-west-2.api.aws" + } + } + }, + "query.timestream" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-south-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "quicksight" : { + "endpoints" : { + "af-south-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "ram" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "hostname" : "ram-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ram-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "hostname" : "ram-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ram-fips.ca-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "ram-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "ram-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "ram-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "ram-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "ram-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "ram-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "hostname" : "ram-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ram-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "hostname" : "ram-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ram-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "hostname" : "ram-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ram-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "hostname" : "ram-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ram-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + } + } + }, + "rbin" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "rbin.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "rbin.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "rbin.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "rbin.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "rbin.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "rbin.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "rbin.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "rbin.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "rbin.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "rbin.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "rbin.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "rbin.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "rbin-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "rbin-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "rbin.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "rbin-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "rbin-fips.ca-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "rbin.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "rbin.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "rbin.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "rbin.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "rbin.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "rbin.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "rbin.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "rbin.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "rbin.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "rbin-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "rbin-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "rbin-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "rbin-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "rbin-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "rbin-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "rbin.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "rbin.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "rbin.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "rbin.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "rbin-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "rbin-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "rbin.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "rbin-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "rbin-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "rbin.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "rbin-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "rbin-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "rbin.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "rbin-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "rbin-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "rbin.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "rds" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "rds-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "rds-fips.ca-central-1.amazonaws.com" + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "rds-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1-fips" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "rds-fips.ca-west-1.amazonaws.com" + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "rds-fips.ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "rds-fips.ca-central-1.amazonaws.com" + }, + "rds-fips.ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "rds-fips.ca-west-1.amazonaws.com" + }, + "rds-fips.us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "rds-fips.us-east-1.amazonaws.com" + }, + "rds-fips.us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "rds-fips.us-east-2.amazonaws.com" + }, + "rds-fips.us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "rds-fips.us-west-1.amazonaws.com" + }, + "rds-fips.us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "rds-fips.us-west-2.amazonaws.com" + }, + "rds.ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "rds-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "rds.ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "rds-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "rds.us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "rds-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "rds.us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "rds-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "rds.us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "rds-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "rds.us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "rds-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "sa-east-1" : { }, + "us-east-1" : { + "sslCommonName" : "{service}.{dnsSuffix}", + "variants" : [ { + "hostname" : "rds-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "rds-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "rds-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "rds-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "rds-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "rds-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "rds-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "rds-fips.us-west-2.amazonaws.com" + } + } + }, + "rds-data" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "rds-data-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "rds-data-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "rds-data-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "rds-data-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "rds-data-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "rds-data-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "rds-data-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "rds-data-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "redshift" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "redshift-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "redshift-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "redshift-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "redshift-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "redshift-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "redshift-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "redshift-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "redshift-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "redshift-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "redshift-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "redshift-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "redshift-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "redshift-serverless" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "redshift-serverless-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "redshift-serverless-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "redshift-serverless-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "redshift-serverless-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "redshift-serverless-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "redshift-serverless-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "redshift-serverless-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "redshift-serverless-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "redshift-serverless-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "redshift-serverless-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "rekognition" : { + "endpoints" : { + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "rekognition.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "rekognition.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "rekognition.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "rekognition.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "rekognition.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "rekognition-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "rekognition-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "rekognition.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "rekognition-fips.ca-central-1.amazonaws.com" + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "rekognition.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "rekognition.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "rekognition.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "rekognition.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "rekognition.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "rekognition-fips.ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "rekognition-fips.ca-central-1.amazonaws.com" + }, + "rekognition-fips.us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "rekognition-fips.us-east-1.amazonaws.com" + }, + "rekognition-fips.us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "rekognition-fips.us-east-2.amazonaws.com" + }, + "rekognition-fips.us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "rekognition-fips.us-west-1.amazonaws.com" + }, + "rekognition-fips.us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "rekognition-fips.us-west-2.amazonaws.com" + }, + "rekognition.ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "rekognition-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "rekognition.us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "rekognition-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "rekognition.us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "rekognition-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "rekognition.us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "rekognition-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "rekognition.us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "rekognition-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "rekognition-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "rekognition-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "rekognition.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "rekognition-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "rekognition-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "rekognition-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "rekognition.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "rekognition-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "rekognition-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "rekognition-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "rekognition.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "rekognition-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "rekognition-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "rekognition-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "rekognition.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "rekognition-fips.us-west-2.amazonaws.com" + } + } + }, + "resiliencehub" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "resiliencehub.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "resiliencehub.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "resiliencehub.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "resiliencehub.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "resiliencehub.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "resiliencehub.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "resiliencehub.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "resiliencehub.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "resiliencehub.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "resiliencehub.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "resiliencehub.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "resiliencehub.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "resiliencehub.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "resiliencehub.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "resiliencehub.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "resiliencehub.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "resiliencehub.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "resiliencehub.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "resiliencehub.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "resiliencehub.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "resource-explorer-2" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "resource-explorer-2-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "resource-explorer-2-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "resource-explorer-2-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "resource-explorer-2-fips.ca-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "resource-explorer-2-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "resource-explorer-2-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "resource-explorer-2-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "resource-explorer-2-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "resource-explorer-2-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "resource-explorer-2-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "resource-explorer-2-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "resource-explorer-2-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "resource-explorer-2-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "resource-explorer-2-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "resource-explorer-2-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "resource-explorer-2-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "resource-explorer-2-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "resource-explorer-2-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + } + } + }, + "resource-groups" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "resource-groups-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "resource-groups-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "resource-groups-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "resource-groups-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "resource-groups-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "resource-groups-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "resource-groups-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "resource-groups-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "rolesanywhere" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "rolesanywhere-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "rolesanywhere-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "rolesanywhere-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "rolesanywhere-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "rolesanywhere-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "rolesanywhere-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "rolesanywhere-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "rolesanywhere-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "route53" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "route53.amazonaws.com", + "variants" : [ { + "hostname" : "route53-fips.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "fips-aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "route53-fips.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "route53-recovery-control-config" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "route53-recovery-control-config.us-west-2.amazonaws.com" + } + } + }, + "route53domains" : { + "endpoints" : { + "us-east-1" : { } + } + }, + "route53profiles" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "route53profiles.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "route53profiles.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "route53profiles.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "route53profiles.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "route53profiles.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "route53profiles.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "route53profiles.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "route53profiles.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "route53profiles.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "route53profiles.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "route53profiles.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "route53profiles-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "route53profiles.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "route53profiles-fips.ca-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "route53profiles.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "route53profiles.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "route53profiles.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "route53profiles.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "route53profiles.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "route53profiles.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "route53profiles.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "route53profiles.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "route53profiles.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "route53profiles.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "route53profiles.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "route53profiles.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "route53profiles.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "route53profiles-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "route53profiles.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "route53profiles-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "route53profiles.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "route53profiles-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "route53profiles.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "route53profiles-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "route53profiles.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "route53resolver" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "route53resolver.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "route53resolver.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "route53resolver.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "route53resolver.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "route53resolver.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "route53resolver.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "route53resolver.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "route53resolver.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "route53resolver.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "route53resolver.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "route53resolver.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "route53resolver.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "route53resolver.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "route53resolver-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "route53resolver-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "route53resolver.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "route53resolver-fips.ca-central-1.amazonaws.com" + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "route53resolver-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "route53resolver-fips.ca-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "route53resolver.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1-fips" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "route53resolver-fips.ca-west-1.amazonaws.com" + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "route53resolver.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "route53resolver.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "route53resolver.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "route53resolver.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "route53resolver.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "route53resolver.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "route53resolver.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "route53resolver.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "route53resolver.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "route53resolver.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "route53resolver.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "route53resolver.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "route53resolver.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "route53resolver-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "route53resolver-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "route53resolver.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "route53resolver-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "route53resolver-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "route53resolver-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "route53resolver.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "route53resolver-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "route53resolver-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "route53resolver-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "route53resolver.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "route53resolver-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "route53resolver-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "route53resolver-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "route53resolver.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "route53resolver-fips.us-west-2.amazonaws.com" + } + } + }, + "rum" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "runtime-v2-lex" : { + "endpoints" : { + "af-south-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "runtime.lex" : { + "defaults" : { + "credentialScope" : { + "service" : "lex" + }, + "variants" : [ { + "hostname" : "runtime-fips.lex.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "runtime-fips.lex.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "runtime-fips.lex.us-east-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "runtime-fips.lex.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "runtime-fips.lex.us-west-2.amazonaws.com" + } + } + }, + "runtime.sagemaker" : { + "defaults" : { + "variants" : [ { + "hostname" : "runtime-fips.sagemaker.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "runtime-fips.sagemaker.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "runtime-fips.sagemaker.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "runtime-fips.sagemaker.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "runtime-fips.sagemaker.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "runtime-fips.sagemaker.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "runtime-fips.sagemaker.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "runtime-fips.sagemaker.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "runtime-fips.sagemaker.us-west-2.amazonaws.com" + } + } + }, + "s3" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "dnsSuffix" : "amazonaws.com", + "hostname" : "{service}-fips.dualstack.{region}.{dnsSuffix}", + "tags" : [ "dualstack", "fips" ] + }, { + "dnsSuffix" : "amazonaws.com", + "hostname" : "{service}.dualstack.{region}.{dnsSuffix}", + "tags" : [ "dualstack" ] + } ] + }, + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "s3.dualstack.af-south-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "s3.dualstack.ap-east-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "hostname" : "s3.ap-northeast-1.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ], + "variants" : [ { + "hostname" : "s3.dualstack.ap-northeast-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "s3.dualstack.ap-northeast-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "s3.dualstack.ap-northeast-3.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "s3.dualstack.ap-south-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "s3.dualstack.ap-south-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "hostname" : "s3.ap-southeast-1.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ], + "variants" : [ { + "hostname" : "s3.dualstack.ap-southeast-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "hostname" : "s3.ap-southeast-2.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ], + "variants" : [ { + "hostname" : "s3.dualstack.ap-southeast-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "s3.dualstack.ap-southeast-3.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "s3.dualstack.ap-southeast-4.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "s3.dualstack.ap-southeast-5.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "s3.dualstack.ap-southeast-7.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "s3.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "s3-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "s3-fips.dualstack.ca-central-1.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3.dualstack.ca-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "s3-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "s3-fips.dualstack.ca-west-1.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3.dualstack.ca-west-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "s3.dualstack.eu-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "s3.dualstack.eu-central-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "s3.dualstack.eu-north-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "s3.dualstack.eu-south-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "s3.dualstack.eu-south-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "hostname" : "s3.eu-west-1.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ], + "variants" : [ { + "hostname" : "s3.dualstack.eu-west-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "s3.dualstack.eu-west-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "s3.dualstack.eu-west-3.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "s3-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "s3-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "s3-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "s3-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "s3-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "s3-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "s3.dualstack.il-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "s3.dualstack.me-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "s3.dualstack.me-south-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "s3.dualstack.mx-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "s3-external-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "s3-external-1.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ] + }, + "sa-east-1" : { + "hostname" : "s3.sa-east-1.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ], + "variants" : [ { + "hostname" : "s3.dualstack.sa-east-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "hostname" : "s3.us-east-1.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ], + "variants" : [ { + "hostname" : "s3-fips.dualstack.us-east-1.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "s3.dualstack.us-east-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "s3-fips.dualstack.us-east-2.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "s3.dualstack.us-east-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "hostname" : "s3.us-west-1.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ], + "variants" : [ { + "hostname" : "s3-fips.dualstack.us-west-1.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "s3.dualstack.us-west-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "hostname" : "s3.us-west-2.amazonaws.com", + "signatureVersions" : [ "s3", "s3v4" ], + "variants" : [ { + "hostname" : "s3-fips.dualstack.us-west-2.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "s3.dualstack.us-west-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + } + }, + "isRegionalized" : true, + "partitionEndpoint" : "aws-global" + }, + "s3-control" : { + "defaults" : { + "protocols" : [ "https" ], + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "dnsSuffix" : "amazonaws.com", + "hostname" : "{service}-fips.dualstack.{region}.{dnsSuffix}", + "tags" : [ "dualstack", "fips" ] + }, { + "dnsSuffix" : "amazonaws.com", + "hostname" : "{service}.dualstack.{region}.{dnsSuffix}", + "tags" : [ "dualstack" ] + } ] + }, + "endpoints" : { + "af-south-1" : { + "credentialScope" : { + "region" : "af-south-1" + }, + "hostname" : "s3-control.af-south-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.af-south-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "credentialScope" : { + "region" : "ap-east-1" + }, + "hostname" : "s3-control.ap-east-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.ap-east-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "s3-control.ap-northeast-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.ap-northeast-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "hostname" : "s3-control.ap-northeast-2.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.ap-northeast-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "credentialScope" : { + "region" : "ap-northeast-3" + }, + "hostname" : "s3-control.ap-northeast-3.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.ap-northeast-3.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "hostname" : "s3-control.ap-south-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.ap-south-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "credentialScope" : { + "region" : "ap-south-2" + }, + "hostname" : "s3-control.ap-south-2.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.ap-south-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "s3-control.ap-southeast-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.ap-southeast-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "s3-control.ap-southeast-2.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.ap-southeast-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "credentialScope" : { + "region" : "ap-southeast-3" + }, + "hostname" : "s3-control.ap-southeast-3.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.ap-southeast-3.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "credentialScope" : { + "region" : "ap-southeast-4" + }, + "hostname" : "s3-control.ap-southeast-4.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.ap-southeast-4.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "hostname" : "s3-control.ca-central-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "s3-control-fips.dualstack.ca-central-1.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-control.dualstack.ca-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "s3-control-fips.ca-central-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ] + }, + "ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "hostname" : "s3-control.ca-west-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "s3-control-fips.dualstack.ca-west-1.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-control.dualstack.ca-west-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1-fips" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "s3-control-fips.ca-west-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ] + }, + "eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "s3-control.eu-central-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.eu-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "credentialScope" : { + "region" : "eu-central-2" + }, + "hostname" : "s3-control.eu-central-2.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.eu-central-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "credentialScope" : { + "region" : "eu-north-1" + }, + "hostname" : "s3-control.eu-north-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.eu-north-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "credentialScope" : { + "region" : "eu-south-1" + }, + "hostname" : "s3-control.eu-south-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.eu-south-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "credentialScope" : { + "region" : "eu-south-2" + }, + "hostname" : "s3-control.eu-south-2.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.eu-south-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "s3-control.eu-west-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.eu-west-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "hostname" : "s3-control.eu-west-2.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.eu-west-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "hostname" : "s3-control.eu-west-3.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.eu-west-3.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "il-central-1" : { + "credentialScope" : { + "region" : "il-central-1" + }, + "hostname" : "s3-control.il-central-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.il-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "credentialScope" : { + "region" : "me-central-1" + }, + "hostname" : "s3-control.me-central-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.me-central-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "credentialScope" : { + "region" : "me-south-1" + }, + "hostname" : "s3-control.me-south-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.me-south-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "hostname" : "s3-control.sa-east-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.sa-east-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "s3-control.us-east-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control-fips.dualstack.us-east-1.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-control-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "s3-control.dualstack.us-east-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "s3-control-fips.us-east-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ] + }, + "us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "s3-control.us-east-2.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control-fips.dualstack.us-east-2.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-control-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "s3-control.dualstack.us-east-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "s3-control-fips.us-east-2.amazonaws.com", + "signatureVersions" : [ "s3v4" ] + }, + "us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "hostname" : "s3-control.us-west-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control-fips.dualstack.us-west-1.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-control-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "s3-control.dualstack.us-west-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "s3-control-fips.us-west-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ] + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "s3-control.us-west-2.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control-fips.dualstack.us-west-2.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-control-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "s3-control.dualstack.us-west-2.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "s3-control-fips.us-west-2.amazonaws.com", + "signatureVersions" : [ "s3v4" ] + } + } + }, + "s3-outposts" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "deprecated" : true + }, + "fips-us-east-1" : { + "deprecated" : true + }, + "fips-us-east-2" : { + "deprecated" : true + }, + "fips-us-west-1" : { + "deprecated" : true + }, + "fips-us-west-2" : { + "deprecated" : true + }, + "il-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + } + } + }, + "sagemaker-geospatial" : { + "endpoints" : { + "us-west-2" : { } + } + }, + "savingsplans" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "savingsplans.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "scheduler" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "schemas" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "sdb" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "signatureVersions" : [ "v2" ] + }, + "endpoints" : { + "ap-northeast-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-west-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "hostname" : "sdb.amazonaws.com" + }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "secretsmanager" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + }, + "ca-central-1-fips" : { + "deprecated" : true + }, + "ca-west-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + }, + "ca-west-1-fips" : { + "deprecated" : true + }, + "eu-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "il-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "deprecated" : true + }, + "us-east-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "deprecated" : true + }, + "us-west-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "deprecated" : true + }, + "us-west-2" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "deprecated" : true + } + } + }, + "securityhub" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "securityhub.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "securityhub.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "securityhub.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "securityhub.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "securityhub.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "securityhub.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "securityhub.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "securityhub.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "securityhub.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "securityhub.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "securityhub.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "securityhub.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "securityhub.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "securityhub.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "securityhub.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "securityhub.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "securityhub.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "securityhub.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "securityhub.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "securityhub.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "securityhub.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "securityhub.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "securityhub.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "securityhub-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "securityhub-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "securityhub-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "securityhub-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "securityhub.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "securityhub.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "securityhub.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "securityhub.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "securityhub.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "securityhub-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "securityhub.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "securityhub-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "securityhub.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "securityhub-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "securityhub.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "securityhub-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "securityhub.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "securitylake" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "securitylake-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "securitylake-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "securitylake-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "securitylake-fips.us-west-2.amazonaws.com" + }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "securitylake-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "securitylake-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "securitylake-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "securitylake-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "securitylake-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "securitylake-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "securitylake-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "securitylake-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + } + } + }, + "serverlessrepo" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "ap-east-1" : { + "protocols" : [ "https" ] + }, + "ap-northeast-1" : { + "protocols" : [ "https" ] + }, + "ap-northeast-2" : { + "protocols" : [ "https" ] + }, + "ap-south-1" : { + "protocols" : [ "https" ] + }, + "ap-southeast-1" : { + "protocols" : [ "https" ] + }, + "ap-southeast-2" : { + "protocols" : [ "https" ] + }, + "ca-central-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "serverlessrepo-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "serverlessrepo-fips.ca-central-1.amazonaws.com" + }, + "eu-central-1" : { + "protocols" : [ "https" ] + }, + "eu-north-1" : { + "protocols" : [ "https" ] + }, + "eu-west-1" : { + "protocols" : [ "https" ] + }, + "eu-west-2" : { + "protocols" : [ "https" ] + }, + "eu-west-3" : { + "protocols" : [ "https" ] + }, + "me-south-1" : { + "protocols" : [ "https" ] + }, + "sa-east-1" : { + "protocols" : [ "https" ] + }, + "us-east-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "serverlessrepo-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "serverlessrepo-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "serverlessrepo-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "serverlessrepo-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "serverlessrepo-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "serverlessrepo-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "serverlessrepo-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "serverlessrepo-fips.us-west-2.amazonaws.com" + } + } + }, + "servicecatalog" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "servicecatalog-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "servicecatalog-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "servicecatalog-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "servicecatalog-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "servicecatalog-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "servicecatalog-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "servicecatalog-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "servicecatalog-fips.us-west-2.amazonaws.com" + } + } + }, + "servicecatalog-appregistry" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "servicecatalog-appregistry-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "servicecatalog-appregistry-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "servicecatalog-appregistry-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "servicecatalog-appregistry-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "servicecatalog-appregistry-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "servicecatalog-appregistry-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "servicecatalog-appregistry-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "servicecatalog-appregistry-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "servicecatalog-appregistry-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "servicecatalog-appregistry-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "servicediscovery" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "servicediscovery.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "servicediscovery.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "servicediscovery.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "servicediscovery.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "servicediscovery.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "servicediscovery.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "servicediscovery.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "servicediscovery.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "servicediscovery.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "servicediscovery.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "servicediscovery.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "servicediscovery.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "servicediscovery.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "servicediscovery-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "servicediscovery-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "servicediscovery.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "servicediscovery-fips.ca-central-1.amazonaws.com" + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "servicediscovery-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "servicediscovery-fips.ca-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "servicediscovery.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1-fips" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "servicediscovery-fips.ca-west-1.amazonaws.com" + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "servicediscovery.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "servicediscovery.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "servicediscovery.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "servicediscovery.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "servicediscovery.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "servicediscovery.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "servicediscovery.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "servicediscovery.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "servicediscovery.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "servicediscovery.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "servicediscovery.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "servicediscovery.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "servicediscovery.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "servicediscovery-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "servicediscovery-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "servicediscovery.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "servicediscovery-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "servicediscovery-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "servicediscovery-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "servicediscovery.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "servicediscovery-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "servicediscovery-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "servicediscovery-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "servicediscovery.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "servicediscovery-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "servicediscovery-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "servicediscovery-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "servicediscovery.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "servicediscovery-fips.us-west-2.amazonaws.com" + } + } + }, + "servicequotas" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "shield" : { + "defaults" : { + "protocols" : [ "https" ], + "sslCommonName" : "shield.us-east-1.amazonaws.com" + }, + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "shield.us-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "shield-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "fips-aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "shield-fips.us-east-1.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "signer" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "signer-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "signer-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "signer-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "signer-fips.us-west-2.amazonaws.com" + }, + "fips-verification-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "verification.signer-fips.us-east-1.amazonaws.com" + }, + "fips-verification-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "verification.signer-fips.us-east-2.amazonaws.com" + }, + "fips-verification-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "hostname" : "verification.signer-fips.us-west-1.amazonaws.com" + }, + "fips-verification-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "verification.signer-fips.us-west-2.amazonaws.com" + }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "signer-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "signer-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "signer-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "signer-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "verification-af-south-1" : { + "credentialScope" : { + "region" : "af-south-1" + }, + "hostname" : "verification.signer.af-south-1.amazonaws.com" + }, + "verification-ap-east-1" : { + "credentialScope" : { + "region" : "ap-east-1" + }, + "hostname" : "verification.signer.ap-east-1.amazonaws.com" + }, + "verification-ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "verification.signer.ap-northeast-1.amazonaws.com" + }, + "verification-ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "hostname" : "verification.signer.ap-northeast-2.amazonaws.com" + }, + "verification-ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "hostname" : "verification.signer.ap-south-1.amazonaws.com" + }, + "verification-ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "verification.signer.ap-southeast-1.amazonaws.com" + }, + "verification-ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "verification.signer.ap-southeast-2.amazonaws.com" + }, + "verification-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "hostname" : "verification.signer.ca-central-1.amazonaws.com" + }, + "verification-eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "verification.signer.eu-central-1.amazonaws.com" + }, + "verification-eu-north-1" : { + "credentialScope" : { + "region" : "eu-north-1" + }, + "hostname" : "verification.signer.eu-north-1.amazonaws.com" + }, + "verification-eu-south-1" : { + "credentialScope" : { + "region" : "eu-south-1" + }, + "hostname" : "verification.signer.eu-south-1.amazonaws.com" + }, + "verification-eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "verification.signer.eu-west-1.amazonaws.com" + }, + "verification-eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "hostname" : "verification.signer.eu-west-2.amazonaws.com" + }, + "verification-eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "hostname" : "verification.signer.eu-west-3.amazonaws.com" + }, + "verification-me-south-1" : { + "credentialScope" : { + "region" : "me-south-1" + }, + "hostname" : "verification.signer.me-south-1.amazonaws.com" + }, + "verification-sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "hostname" : "verification.signer.sa-east-1.amazonaws.com" + }, + "verification-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "verification.signer.us-east-1.amazonaws.com" + }, + "verification-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "verification.signer.us-east-2.amazonaws.com" + }, + "verification-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "hostname" : "verification.signer.us-west-1.amazonaws.com" + }, + "verification-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "verification.signer.us-west-2.amazonaws.com" + } + } + }, + "simspaceweaver" : { + "endpoints" : { + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "sms-voice" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "sms-voice.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "sms-voice.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "sms-voice.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "sms-voice.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "sms-voice.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "sms-voice.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "sms-voice.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "sms-voice.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "sms-voice.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "sms-voice.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "sms-voice-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sms-voice-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "sms-voice.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "sms-voice-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sms-voice-fips.ca-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "sms-voice.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "sms-voice.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "sms-voice.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "sms-voice.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "sms-voice.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "sms-voice.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "sms-voice.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "sms-voice.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "sms-voice.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "sms-voice-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "sms-voice-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "sms-voice-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "sms-voice-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "sms-voice-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "sms-voice-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "sms-voice.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "sms-voice.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "sms-voice.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "sms-voice.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "sms-voice-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sms-voice-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "sms-voice.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "sms-voice-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sms-voice-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "sms-voice.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "sms-voice-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sms-voice-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "sms-voice.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "sms-voice-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sms-voice-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "sms-voice.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "snowball" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "snowball-fips.af-south-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.af-south-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "snowball-fips.ap-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.ap-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "snowball-fips.ap-northeast-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.ap-northeast-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "snowball-fips.ap-northeast-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.ap-northeast-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "snowball-fips.ap-northeast-3.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.ap-northeast-3.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "snowball-fips.ap-south-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.ap-south-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "snowball-fips.ap-southeast-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.ap-southeast-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "snowball-fips.ap-southeast-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.ap-southeast-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "snowball-fips.ap-southeast-3.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.ap-southeast-3.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "snowball-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "snowball-fips.eu-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.eu-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "snowball-fips.eu-north-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.eu-north-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "snowball-fips.eu-south-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.eu-south-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "snowball-fips.eu-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.eu-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "snowball-fips.eu-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.eu-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "snowball-fips.eu-west-3.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.eu-west-3.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-af-south-1" : { + "credentialScope" : { + "region" : "af-south-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.af-south-1.amazonaws.com" + }, + "fips-ap-east-1" : { + "credentialScope" : { + "region" : "ap-east-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.ap-east-1.amazonaws.com" + }, + "fips-ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.ap-northeast-1.amazonaws.com" + }, + "fips-ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "deprecated" : true, + "hostname" : "snowball-fips.ap-northeast-2.amazonaws.com" + }, + "fips-ap-northeast-3" : { + "credentialScope" : { + "region" : "ap-northeast-3" + }, + "deprecated" : true, + "hostname" : "snowball-fips.ap-northeast-3.amazonaws.com" + }, + "fips-ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.ap-south-1.amazonaws.com" + }, + "fips-ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.ap-southeast-1.amazonaws.com" + }, + "fips-ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "deprecated" : true, + "hostname" : "snowball-fips.ap-southeast-2.amazonaws.com" + }, + "fips-ap-southeast-3" : { + "credentialScope" : { + "region" : "ap-southeast-3" + }, + "deprecated" : true, + "hostname" : "snowball-fips.ap-southeast-3.amazonaws.com" + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.ca-central-1.amazonaws.com" + }, + "fips-eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.eu-central-1.amazonaws.com" + }, + "fips-eu-north-1" : { + "credentialScope" : { + "region" : "eu-north-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.eu-north-1.amazonaws.com" + }, + "fips-eu-south-1" : { + "credentialScope" : { + "region" : "eu-south-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.eu-south-1.amazonaws.com" + }, + "fips-eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.eu-west-1.amazonaws.com" + }, + "fips-eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "deprecated" : true, + "hostname" : "snowball-fips.eu-west-2.amazonaws.com" + }, + "fips-eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "deprecated" : true, + "hostname" : "snowball-fips.eu-west-3.amazonaws.com" + }, + "fips-il-central-1" : { + "credentialScope" : { + "region" : "il-central-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.il-central-1.amazonaws.com" + }, + "fips-me-central-1" : { + "credentialScope" : { + "region" : "me-central-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.me-central-1.amazonaws.com" + }, + "fips-sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.sa-east-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "snowball-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "snowball-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "snowball-fips.il-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.il-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "snowball-fips.me-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.me-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "snowball-fips.sa-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.sa-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "snowball-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "snowball-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "snowball-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "snowball-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "sns" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "sns.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "sns.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "sns.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "sns.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "sns.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "sns.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "sns.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "sns.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "sns.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "sns.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "sns.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "sns.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "sns.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "sns.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "sns-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sns.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "sns.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "sns.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "sns.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "sns.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "sns.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "sns.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "sns.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "sns.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "sns-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "sns-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "sns-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "sns-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "sns-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "sns.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "sns.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "sns.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "sns.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "sns.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "sns-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sns.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "sns-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sns.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "sns-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sns.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "sns-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sns.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "sqs" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "sslCommonName" : "{region}.queue.{dnsSuffix}" + }, + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "sqs.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "sqs.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "sqs.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "sqs.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "sqs.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "sqs.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "sqs.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "sqs.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "sqs.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "sqs.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "sqs.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "sqs.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "sqs.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "sqs-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sqs.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "sqs-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sqs.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "sqs.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "sqs.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "sqs.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "sqs.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "sqs.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "sqs.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "sqs.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "sqs.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "sqs-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "sqs-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "sqs-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "sqs-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "sqs-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "sqs-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "sqs.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "sqs.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "sqs.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "sqs.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "sqs.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "sslCommonName" : "queue.{dnsSuffix}", + "variants" : [ { + "hostname" : "sqs-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sqs.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "sqs-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sqs.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "sqs-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sqs.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "sqs-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sqs.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "ssm" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "ssm-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "ssm-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "ssm-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "ssm-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "ssm-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "ssm-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "ssm-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "ssm-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "ssm-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "ssm-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "ssm-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "ssm-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "ssm-contacts" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "ssm-contacts-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "ssm-contacts-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "ssm-contacts-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "ssm-contacts-fips.us-west-2.amazonaws.com" + }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "ssm-contacts-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "ssm-contacts-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "ssm-contacts-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "ssm-contacts-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "ssm-incidents" : { + "endpoints" : { + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "ssm-incidents.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "ssm-incidents.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "ssm-incidents.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "ssm-incidents.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "ssm-incidents.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "ssm-incidents-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ssm-incidents-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "ssm-incidents.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "ssm-incidents.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "ssm-incidents.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "ssm-incidents.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "ssm-incidents.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "ssm-incidents.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "ssm-incidents-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "ssm-incidents-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "ssm-incidents-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "ssm-incidents-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "ssm-incidents-fips.us-west-2.amazonaws.com" + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "ssm-incidents.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "ssm-incidents-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ssm-incidents-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "ssm-incidents.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "ssm-incidents-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ssm-incidents-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "ssm-incidents.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "ssm-incidents-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ssm-incidents-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "ssm-incidents.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "ssm-incidents-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ssm-incidents-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "ssm-incidents.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "ssm-quicksetup" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "ssm-quicksetup-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "ssm-quicksetup-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "ssm-quicksetup-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "ssm-quicksetup-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "ssm-quicksetup-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "ssm-quicksetup-fips.us-west-2.amazonaws.com" + }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "ssm-quicksetup-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "ssm-quicksetup-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "ssm-quicksetup-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "ssm-quicksetup-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "ssm-sap" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "ssm-sap.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "ssm-sap.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "ssm-sap.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "ssm-sap.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "ssm-sap.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "ssm-sap.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "ssm-sap.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "ssm-sap.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "ssm-sap.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "ssm-sap.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "ssm-sap.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "ssm-sap-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ssm-sap-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "ssm-sap.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "ssm-sap.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "ssm-sap.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "ssm-sap.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "ssm-sap.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "ssm-sap.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "ssm-sap.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "ssm-sap.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "ssm-sap.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "ssm-sap-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "ssm-sap-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "ssm-sap-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "ssm-sap-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "ssm-sap-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "ssm-sap.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "ssm-sap.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "ssm-sap.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "ssm-sap.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "ssm-sap-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ssm-sap-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "ssm-sap.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "ssm-sap-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ssm-sap-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "ssm-sap.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "ssm-sap-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ssm-sap-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "ssm-sap.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "ssm-sap-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ssm-sap-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "ssm-sap.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "sso" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "states" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "states-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "states-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "states-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "states-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "states-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "states-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "states-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "states-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "states-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "states-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "states-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "states-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "storagegateway" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "storagegateway-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "storagegateway-fips.ca-central-1.amazonaws.com" + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "storagegateway-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1-fips" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "storagegateway-fips.ca-west-1.amazonaws.com" + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "storagegateway-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "storagegateway-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "storagegateway-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "storagegateway-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "storagegateway-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "storagegateway-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "storagegateway-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "storagegateway-fips.us-west-2.amazonaws.com" + } + } + }, + "streams.dynamodb" : { + "defaults" : { + "credentialScope" : { + "service" : "dynamodb" + }, + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "local" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "localhost:8000", + "protocols" : [ "http" ] + }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "sts" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "sts.amazonaws.com" + }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "sts-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "sts-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "sts-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "sts-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "sts-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "sts-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "sts-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "sts-fips.us-west-2.amazonaws.com" + } + }, + "partitionEndpoint" : "aws-global" + }, + "support" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "support.us-east-1.amazonaws.com" + } + }, + "partitionEndpoint" : "aws-global" + }, + "supportapp" : { + "endpoints" : { + "eu-west-1" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "swf" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "swf-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "swf-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "swf-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "swf-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "swf-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "swf-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "swf-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "swf-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "swf-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "swf-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "swf-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "swf-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "synthetics" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "synthetics.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "synthetics.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "synthetics.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "synthetics.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-3" : { + "variants" : [ { + "hostname" : "synthetics.ap-northeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "synthetics.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-2" : { + "variants" : [ { + "hostname" : "synthetics.ap-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "synthetics.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "synthetics.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-3" : { + "variants" : [ { + "hostname" : "synthetics.ap-southeast-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-4" : { + "variants" : [ { + "hostname" : "synthetics.ap-southeast-4.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-5" : { + "variants" : [ { + "hostname" : "synthetics.ap-southeast-5.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "variants" : [ { + "hostname" : "synthetics.ap-southeast-7.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "synthetics-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "synthetics-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "synthetics.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "synthetics-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "synthetics-fips.ca-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "synthetics.ca-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "synthetics.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-2" : { + "variants" : [ { + "hostname" : "synthetics.eu-central-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "synthetics.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-1" : { + "variants" : [ { + "hostname" : "synthetics.eu-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "synthetics.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "synthetics.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "synthetics.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "synthetics.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "synthetics-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "synthetics-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "synthetics-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "synthetics-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "synthetics-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "synthetics-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "variants" : [ { + "hostname" : "synthetics.il-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-central-1" : { + "variants" : [ { + "hostname" : "synthetics.me-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "synthetics.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "mx-central-1" : { + "variants" : [ { + "hostname" : "synthetics.mx-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "synthetics.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "synthetics-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "synthetics-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "synthetics.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "synthetics-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "synthetics-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "synthetics.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "synthetics-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "synthetics-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "synthetics.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "synthetics-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "synthetics-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "synthetics.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "tagging" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "tax" : { + "endpoints" : { + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "tax.us-east-1.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "textract" : { + "endpoints" : { + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "textract.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "textract.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "textract.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "textract.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "textract-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "textract-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "textract.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "textract.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-south-2" : { + "variants" : [ { + "hostname" : "textract.eu-south-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "textract.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "textract.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "textract.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "textract-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "textract-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "textract-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "textract-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "textract-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "textract-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "textract-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "textract.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "textract-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "textract-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "textract.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "textract-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "textract-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "textract.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "textract-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "textract-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "textract.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "thinclient" : { + "endpoints" : { + "ap-south-1" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "tnb" : { + "endpoints" : { + "ap-northeast-2" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-south-2" : { }, + "eu-west-3" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "transcribe" : { + "defaults" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "fips.transcribe.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "transcribe.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-east-1" : { + "variants" : [ { + "hostname" : "transcribe.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "transcribe.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "transcribe.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "transcribe.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "transcribe.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "transcribe.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "fips.transcribe.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "transcribe-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "transcribe.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "transcribe.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "transcribe.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "transcribe.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "transcribe.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "transcribe.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "fips.transcribe.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "fips.transcribe.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "fips.transcribe.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "fips.transcribe.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "fips.transcribe.us-west-2.amazonaws.com" + }, + "me-south-1" : { + "variants" : [ { + "hostname" : "transcribe.me-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "transcribe.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "fips.transcribe.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "transcribe-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "transcribe.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "fips.transcribe.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "transcribe-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "transcribe.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "fips.transcribe.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "transcribe-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "transcribe.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "fips.transcribe.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "transcribe-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "transcribe.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "transcribestreaming" : { + "endpoints" : { + "af-south-1" : { + "variants" : [ { + "hostname" : "transcribestreaming.af-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "transcribestreaming.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "transcribestreaming.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "transcribestreaming.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "transcribestreaming.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "transcribestreaming.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "transcribestreaming-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "transcribestreaming-fips.ca-central-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "transcribestreaming.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "transcribestreaming.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "transcribestreaming.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "transcribestreaming.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "transcribestreaming-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "transcribestreaming-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "transcribestreaming-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "transcribestreaming-fips.us-west-2.amazonaws.com" + }, + "sa-east-1" : { + "variants" : [ { + "hostname" : "transcribestreaming.sa-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "transcribestreaming-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "transcribestreaming-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "transcribestreaming.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "transcribestreaming-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "transcribestreaming-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "transcribestreaming.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "transcribestreaming-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "transcribestreaming-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "transcribestreaming.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "transfer" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "transfer-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "transfer-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "transfer-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "transfer-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "transfer-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "transfer-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "transfer-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "transfer-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "transfer-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "transfer-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "transfer-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "transfer-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "translate" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "ap-east-1" : { + "variants" : [ { + "hostname" : "translate.ap-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-1" : { + "variants" : [ { + "hostname" : "translate.ap-northeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-northeast-2" : { + "variants" : [ { + "hostname" : "translate.ap-northeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-south-1" : { + "variants" : [ { + "hostname" : "translate.ap-south-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-1" : { + "variants" : [ { + "hostname" : "translate.ap-southeast-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ap-southeast-2" : { + "variants" : [ { + "hostname" : "translate.ap-southeast-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "translate.ca-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-central-1" : { + "variants" : [ { + "hostname" : "translate.eu-central-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-north-1" : { + "variants" : [ { + "hostname" : "translate.eu-north-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-1" : { + "variants" : [ { + "hostname" : "translate.eu-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-2" : { + "variants" : [ { + "hostname" : "translate.eu-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "eu-west-3" : { + "variants" : [ { + "hostname" : "translate.eu-west-3.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "translate-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "translate-fips.us-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "translate.us-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "translate-fips.us-east-1.amazonaws.com" + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "translate-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "translate-fips.us-east-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "translate.us-east-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-east-2-fips" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "translate-fips.us-east-2.amazonaws.com" + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "translate-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "translate-fips.us-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "translate.us-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-1-fips" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "translate-fips.us-west-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "translate-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "translate-fips.us-west-2.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "translate.us-west-2.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "translate-fips.us-west-2.amazonaws.com" + } + } + }, + "trustedadvisor" : { + "endpoints" : { + "ap-northeast-2" : { }, + "ap-southeast-2" : { }, + "eu-west-1" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "trustedadvisor-fips.us-east-1.api.aws" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "trustedadvisor-fips.us-east-2.api.aws" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "trustedadvisor-fips.us-west-2.api.aws" + }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-2" : { } + } + }, + "verifiedpermissions" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "verifiedpermissions-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "variants" : [ { + "hostname" : "verifiedpermissions-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "verifiedpermissions-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "verifiedpermissions-fips.ca-west-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "verifiedpermissions-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "verifiedpermissions-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "verifiedpermissions-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "verifiedpermissions-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "verifiedpermissions-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "verifiedpermissions-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "verifiedpermissions-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "verifiedpermissions-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "voice-chime" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "voice-chime-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-central-1-fips" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "voice-chime-fips.ca-central-1.amazonaws.com" + }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "voice-chime-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "voice-chime-fips.us-east-1.amazonaws.com" + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "voice-chime-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2-fips" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "voice-chime-fips.us-west-2.amazonaws.com" + } + } + }, + "voiceid" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { + "variants" : [ { + "hostname" : "voiceid-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-west-2" : { }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "voiceid-fips.ca-central-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "voiceid-fips.us-east-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "voiceid-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "voiceid-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "voiceid-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "vpc-lattice" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "waf" : { + "endpoints" : { + "aws" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "waf-fips.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "aws-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "waf-fips.amazonaws.com" + }, + "aws-global" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "waf.amazonaws.com", + "variants" : [ { + "hostname" : "waf-fips.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "aws-global-fips" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "waf-fips.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-global" + }, + "waf-regional" : { + "endpoints" : { + "af-south-1" : { + "credentialScope" : { + "region" : "af-south-1" + }, + "hostname" : "waf-regional.af-south-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.af-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-east-1" : { + "credentialScope" : { + "region" : "ap-east-1" + }, + "hostname" : "waf-regional.ap-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.ap-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "waf-regional.ap-northeast-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.ap-northeast-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "hostname" : "waf-regional.ap-northeast-2.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.ap-northeast-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-northeast-3" : { + "credentialScope" : { + "region" : "ap-northeast-3" + }, + "hostname" : "waf-regional.ap-northeast-3.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.ap-northeast-3.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "hostname" : "waf-regional.ap-south-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.ap-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-south-2" : { + "credentialScope" : { + "region" : "ap-south-2" + }, + "hostname" : "waf-regional.ap-south-2.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.ap-south-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "waf-regional.ap-southeast-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.ap-southeast-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "waf-regional.ap-southeast-2.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.ap-southeast-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-3" : { + "credentialScope" : { + "region" : "ap-southeast-3" + }, + "hostname" : "waf-regional.ap-southeast-3.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.ap-southeast-3.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-4" : { + "credentialScope" : { + "region" : "ap-southeast-4" + }, + "hostname" : "waf-regional.ap-southeast-4.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.ap-southeast-4.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "hostname" : "waf-regional.ca-central-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "waf-regional.eu-central-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.eu-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-2" : { + "credentialScope" : { + "region" : "eu-central-2" + }, + "hostname" : "waf-regional.eu-central-2.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.eu-central-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-north-1" : { + "credentialScope" : { + "region" : "eu-north-1" + }, + "hostname" : "waf-regional.eu-north-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.eu-north-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-south-1" : { + "credentialScope" : { + "region" : "eu-south-1" + }, + "hostname" : "waf-regional.eu-south-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.eu-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-south-2" : { + "credentialScope" : { + "region" : "eu-south-2" + }, + "hostname" : "waf-regional.eu-south-2.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.eu-south-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "waf-regional.eu-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.eu-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "hostname" : "waf-regional.eu-west-2.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.eu-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "hostname" : "waf-regional.eu-west-3.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.eu-west-3.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "fips-af-south-1" : { + "credentialScope" : { + "region" : "af-south-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.af-south-1.amazonaws.com" + }, + "fips-ap-east-1" : { + "credentialScope" : { + "region" : "ap-east-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.ap-east-1.amazonaws.com" + }, + "fips-ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.ap-northeast-1.amazonaws.com" + }, + "fips-ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.ap-northeast-2.amazonaws.com" + }, + "fips-ap-northeast-3" : { + "credentialScope" : { + "region" : "ap-northeast-3" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.ap-northeast-3.amazonaws.com" + }, + "fips-ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.ap-south-1.amazonaws.com" + }, + "fips-ap-south-2" : { + "credentialScope" : { + "region" : "ap-south-2" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.ap-south-2.amazonaws.com" + }, + "fips-ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.ap-southeast-1.amazonaws.com" + }, + "fips-ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.ap-southeast-2.amazonaws.com" + }, + "fips-ap-southeast-3" : { + "credentialScope" : { + "region" : "ap-southeast-3" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.ap-southeast-3.amazonaws.com" + }, + "fips-ap-southeast-4" : { + "credentialScope" : { + "region" : "ap-southeast-4" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.ap-southeast-4.amazonaws.com" + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.ca-central-1.amazonaws.com" + }, + "fips-eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.eu-central-1.amazonaws.com" + }, + "fips-eu-central-2" : { + "credentialScope" : { + "region" : "eu-central-2" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.eu-central-2.amazonaws.com" + }, + "fips-eu-north-1" : { + "credentialScope" : { + "region" : "eu-north-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.eu-north-1.amazonaws.com" + }, + "fips-eu-south-1" : { + "credentialScope" : { + "region" : "eu-south-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.eu-south-1.amazonaws.com" + }, + "fips-eu-south-2" : { + "credentialScope" : { + "region" : "eu-south-2" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.eu-south-2.amazonaws.com" + }, + "fips-eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.eu-west-1.amazonaws.com" + }, + "fips-eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.eu-west-2.amazonaws.com" + }, + "fips-eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.eu-west-3.amazonaws.com" + }, + "fips-il-central-1" : { + "credentialScope" : { + "region" : "il-central-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.il-central-1.amazonaws.com" + }, + "fips-me-central-1" : { + "credentialScope" : { + "region" : "me-central-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.me-central-1.amazonaws.com" + }, + "fips-me-south-1" : { + "credentialScope" : { + "region" : "me-south-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.me-south-1.amazonaws.com" + }, + "fips-sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.sa-east-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "credentialScope" : { + "region" : "il-central-1" + }, + "hostname" : "waf-regional.il-central-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.il-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "me-central-1" : { + "credentialScope" : { + "region" : "me-central-1" + }, + "hostname" : "waf-regional.me-central-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.me-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "me-south-1" : { + "credentialScope" : { + "region" : "me-south-1" + }, + "hostname" : "waf-regional.me-south-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.me-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "hostname" : "waf-regional.sa-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.sa-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "waf-regional.us-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "waf-regional.us-east-2.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "hostname" : "waf-regional.us-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "waf-regional.us-west-2.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "wafv2" : { + "endpoints" : { + "af-south-1" : { + "credentialScope" : { + "region" : "af-south-1" + }, + "hostname" : "wafv2.af-south-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.af-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-east-1" : { + "credentialScope" : { + "region" : "ap-east-1" + }, + "hostname" : "wafv2.ap-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.ap-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-east-2" : { }, + "ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "hostname" : "wafv2.ap-northeast-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.ap-northeast-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "hostname" : "wafv2.ap-northeast-2.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.ap-northeast-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-northeast-3" : { + "credentialScope" : { + "region" : "ap-northeast-3" + }, + "hostname" : "wafv2.ap-northeast-3.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.ap-northeast-3.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "hostname" : "wafv2.ap-south-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.ap-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-south-2" : { + "credentialScope" : { + "region" : "ap-south-2" + }, + "hostname" : "wafv2.ap-south-2.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.ap-south-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "hostname" : "wafv2.ap-southeast-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.ap-southeast-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "hostname" : "wafv2.ap-southeast-2.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.ap-southeast-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-3" : { + "credentialScope" : { + "region" : "ap-southeast-3" + }, + "hostname" : "wafv2.ap-southeast-3.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.ap-southeast-3.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-4" : { + "credentialScope" : { + "region" : "ap-southeast-4" + }, + "hostname" : "wafv2.ap-southeast-4.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.ap-southeast-4.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-5" : { + "credentialScope" : { + "region" : "ap-southeast-5" + }, + "hostname" : "wafv2.ap-southeast-5.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.ap-southeast-5.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { + "credentialScope" : { + "region" : "ap-southeast-7" + }, + "hostname" : "wafv2.ap-southeast-7.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.ap-southeast-7.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "hostname" : "wafv2.ca-central-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.ca-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "hostname" : "wafv2.ca-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.ca-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "hostname" : "wafv2.eu-central-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.eu-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-central-2" : { + "credentialScope" : { + "region" : "eu-central-2" + }, + "hostname" : "wafv2.eu-central-2.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.eu-central-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-north-1" : { + "credentialScope" : { + "region" : "eu-north-1" + }, + "hostname" : "wafv2.eu-north-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.eu-north-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-south-1" : { + "credentialScope" : { + "region" : "eu-south-1" + }, + "hostname" : "wafv2.eu-south-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.eu-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-south-2" : { + "credentialScope" : { + "region" : "eu-south-2" + }, + "hostname" : "wafv2.eu-south-2.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.eu-south-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "hostname" : "wafv2.eu-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.eu-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "hostname" : "wafv2.eu-west-2.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.eu-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "hostname" : "wafv2.eu-west-3.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.eu-west-3.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "fips-af-south-1" : { + "credentialScope" : { + "region" : "af-south-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.af-south-1.amazonaws.com" + }, + "fips-ap-east-1" : { + "credentialScope" : { + "region" : "ap-east-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.ap-east-1.amazonaws.com" + }, + "fips-ap-northeast-1" : { + "credentialScope" : { + "region" : "ap-northeast-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.ap-northeast-1.amazonaws.com" + }, + "fips-ap-northeast-2" : { + "credentialScope" : { + "region" : "ap-northeast-2" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.ap-northeast-2.amazonaws.com" + }, + "fips-ap-northeast-3" : { + "credentialScope" : { + "region" : "ap-northeast-3" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.ap-northeast-3.amazonaws.com" + }, + "fips-ap-south-1" : { + "credentialScope" : { + "region" : "ap-south-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.ap-south-1.amazonaws.com" + }, + "fips-ap-south-2" : { + "credentialScope" : { + "region" : "ap-south-2" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.ap-south-2.amazonaws.com" + }, + "fips-ap-southeast-1" : { + "credentialScope" : { + "region" : "ap-southeast-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.ap-southeast-1.amazonaws.com" + }, + "fips-ap-southeast-2" : { + "credentialScope" : { + "region" : "ap-southeast-2" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.ap-southeast-2.amazonaws.com" + }, + "fips-ap-southeast-3" : { + "credentialScope" : { + "region" : "ap-southeast-3" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.ap-southeast-3.amazonaws.com" + }, + "fips-ap-southeast-4" : { + "credentialScope" : { + "region" : "ap-southeast-4" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.ap-southeast-4.amazonaws.com" + }, + "fips-ap-southeast-5" : { + "credentialScope" : { + "region" : "ap-southeast-5" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.ap-southeast-5.amazonaws.com" + }, + "fips-ap-southeast-7" : { + "credentialScope" : { + "region" : "ap-southeast-7" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.ap-southeast-7.amazonaws.com" + }, + "fips-ca-central-1" : { + "credentialScope" : { + "region" : "ca-central-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.ca-central-1.amazonaws.com" + }, + "fips-ca-west-1" : { + "credentialScope" : { + "region" : "ca-west-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.ca-west-1.amazonaws.com" + }, + "fips-eu-central-1" : { + "credentialScope" : { + "region" : "eu-central-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.eu-central-1.amazonaws.com" + }, + "fips-eu-central-2" : { + "credentialScope" : { + "region" : "eu-central-2" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.eu-central-2.amazonaws.com" + }, + "fips-eu-north-1" : { + "credentialScope" : { + "region" : "eu-north-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.eu-north-1.amazonaws.com" + }, + "fips-eu-south-1" : { + "credentialScope" : { + "region" : "eu-south-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.eu-south-1.amazonaws.com" + }, + "fips-eu-south-2" : { + "credentialScope" : { + "region" : "eu-south-2" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.eu-south-2.amazonaws.com" + }, + "fips-eu-west-1" : { + "credentialScope" : { + "region" : "eu-west-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.eu-west-1.amazonaws.com" + }, + "fips-eu-west-2" : { + "credentialScope" : { + "region" : "eu-west-2" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.eu-west-2.amazonaws.com" + }, + "fips-eu-west-3" : { + "credentialScope" : { + "region" : "eu-west-3" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.eu-west-3.amazonaws.com" + }, + "fips-il-central-1" : { + "credentialScope" : { + "region" : "il-central-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.il-central-1.amazonaws.com" + }, + "fips-me-central-1" : { + "credentialScope" : { + "region" : "me-central-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.me-central-1.amazonaws.com" + }, + "fips-me-south-1" : { + "credentialScope" : { + "region" : "me-south-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.me-south-1.amazonaws.com" + }, + "fips-mx-central-1" : { + "credentialScope" : { + "region" : "mx-central-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.mx-central-1.amazonaws.com" + }, + "fips-sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.sa-east-1.amazonaws.com" + }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { + "credentialScope" : { + "region" : "il-central-1" + }, + "hostname" : "wafv2.il-central-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.il-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "me-central-1" : { + "credentialScope" : { + "region" : "me-central-1" + }, + "hostname" : "wafv2.me-central-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.me-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "me-south-1" : { + "credentialScope" : { + "region" : "me-south-1" + }, + "hostname" : "wafv2.me-south-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.me-south-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "mx-central-1" : { + "credentialScope" : { + "region" : "mx-central-1" + }, + "hostname" : "wafv2.mx-central-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.mx-central-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "sa-east-1" : { + "credentialScope" : { + "region" : "sa-east-1" + }, + "hostname" : "wafv2.sa-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.sa-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "hostname" : "wafv2.us-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "hostname" : "wafv2.us-east-2.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "hostname" : "wafv2.us-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "hostname" : "wafv2.us-west-2.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "wellarchitected" : { + "endpoints" : { + "ap-east-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-north-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "me-south-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { }, + "us-east-2" : { }, + "us-west-1" : { }, + "us-west-2" : { } + } + }, + "wisdom" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + }, + "eu-central-1" : { }, + "eu-west-2" : { }, + "fips-ca-central-1" : { + "deprecated" : true + }, + "fips-us-east-1" : { + "deprecated" : true + }, + "fips-us-west-2" : { + "deprecated" : true + }, + "ui-ap-northeast-1" : { }, + "ui-ap-northeast-2" : { }, + "ui-ap-southeast-1" : { }, + "ui-ap-southeast-2" : { }, + "ui-ca-central-1" : { }, + "ui-eu-central-1" : { }, + "ui-eu-west-2" : { }, + "ui-us-east-1" : { }, + "ui-us-west-2" : { }, + "us-east-1" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + } + } + }, + "workdocs" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "eu-west-1" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "workdocs-fips.us-east-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "workdocs-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "workdocs-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "workdocs-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "workmail" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "eu-west-1" : { }, + "us-east-1" : { }, + "us-west-2" : { } + } + }, + "workspaces" : { + "endpoints" : { + "af-south-1" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "workspaces-fips.us-east-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "workspaces-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "workspaces-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "workspaces-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "workspaces-web" : { + "endpoints" : { + "ap-northeast-1" : { }, + "ap-south-1" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ca-central-1" : { }, + "eu-central-1" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "workspaces-web-fips.us-east-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "workspaces-web-fips.us-west-2.amazonaws.com" + }, + "us-east-1" : { + "variants" : [ { + "hostname" : "workspaces-web-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "workspaces-web-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "xray" : { + "endpoints" : { + "af-south-1" : { }, + "ap-east-1" : { }, + "ap-east-2" : { }, + "ap-northeast-1" : { }, + "ap-northeast-2" : { }, + "ap-northeast-3" : { }, + "ap-south-1" : { }, + "ap-south-2" : { }, + "ap-southeast-1" : { }, + "ap-southeast-2" : { }, + "ap-southeast-3" : { }, + "ap-southeast-4" : { }, + "ap-southeast-5" : { }, + "ap-southeast-6" : { }, + "ap-southeast-7" : { }, + "ca-central-1" : { }, + "ca-west-1" : { }, + "eu-central-1" : { }, + "eu-central-2" : { }, + "eu-north-1" : { }, + "eu-south-1" : { }, + "eu-south-2" : { }, + "eu-west-1" : { }, + "eu-west-2" : { }, + "eu-west-3" : { }, + "fips-us-east-1" : { + "credentialScope" : { + "region" : "us-east-1" + }, + "deprecated" : true, + "hostname" : "xray-fips.us-east-1.amazonaws.com" + }, + "fips-us-east-2" : { + "credentialScope" : { + "region" : "us-east-2" + }, + "deprecated" : true, + "hostname" : "xray-fips.us-east-2.amazonaws.com" + }, + "fips-us-west-1" : { + "credentialScope" : { + "region" : "us-west-1" + }, + "deprecated" : true, + "hostname" : "xray-fips.us-west-1.amazonaws.com" + }, + "fips-us-west-2" : { + "credentialScope" : { + "region" : "us-west-2" + }, + "deprecated" : true, + "hostname" : "xray-fips.us-west-2.amazonaws.com" + }, + "il-central-1" : { }, + "me-central-1" : { }, + "me-south-1" : { }, + "mx-central-1" : { }, + "sa-east-1" : { }, + "us-east-1" : { + "variants" : [ { + "hostname" : "xray-fips.us-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-east-2" : { + "variants" : [ { + "hostname" : "xray-fips.us-east-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-1" : { + "variants" : [ { + "hostname" : "xray-fips.us-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-west-2" : { + "variants" : [ { + "hostname" : "xray-fips.us-west-2.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + } + } + }, { + "defaults" : { + "hostname" : "{service}.{region}.{dnsSuffix}", + "protocols" : [ "https" ], + "signatureVersions" : [ "v4" ], + "variants" : [ { + "dnsSuffix" : "amazonaws.com.cn", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + }, { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "dualstack", "fips" ] + }, { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "hostname" : "{service}.{region}.{dnsSuffix}", + "tags" : [ "dualstack" ] + } ] + }, + "dnsSuffix" : "amazonaws.com.cn", + "partition" : "aws-cn", + "partitionName" : "AWS China", + "regionRegex" : "^cn\\-\\w+\\-\\d+$", + "regions" : { + "cn-north-1" : { + "description" : "China (Beijing)" + }, + "cn-northwest-1" : { + "description" : "China (Ningxia)" + } + }, + "services" : { + "access-analyzer" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "access-analyzer.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "access-analyzer.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "account" : { + "endpoints" : { + "aws-cn-global" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "account.cn-northwest-1.amazonaws.com.cn" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-cn-global" + }, + "acm" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "acm-pca" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "airflow" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "api.ecr" : { + "endpoints" : { + "cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "api.ecr.cn-north-1.amazonaws.com.cn", + "variants" : [ { + "hostname" : "ecr.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "api.ecr.cn-northwest-1.amazonaws.com.cn", + "variants" : [ { + "hostname" : "ecr.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "api.pricing" : { + "defaults" : { + "credentialScope" : { + "service" : "pricing" + } + }, + "endpoints" : { + "cn-northwest-1" : { } + } + }, + "api.sagemaker" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "api.tunneling.iot" : { + "defaults" : { + "variants" : [ { + "dnsSuffix" : "amazonaws.com.cn", + "hostname" : "api.tunneling.iot-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + }, { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "hostname" : "api.iot-tunneling-fips.{region}.{dnsSuffix}", + "tags" : [ "dualstack", "fips" ] + }, { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "hostname" : "api.iot-tunneling.{region}.{dnsSuffix}", + "tags" : [ "dualstack" ] + } ] + }, + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "apigateway" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "appconfig" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "appconfigdata" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "application-autoscaling" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "applicationinsights" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "applicationinsights.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "applicationinsights.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "appmesh" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "appmesh.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "appmesh.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "appsync" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "appsync.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "appsync.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "arc-zonal-shift" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "athena" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "athena.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "athena.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "autoscaling" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "autoscaling-plans" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "backup" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "batch" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "budgets" : { + "endpoints" : { + "aws-cn-global" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "budgets.amazonaws.com.cn" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-cn-global" + }, + "cassandra" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "ce" : { + "endpoints" : { + "aws-cn-global" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "ce.cn-northwest-1.amazonaws.com.cn" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-cn-global" + }, + "cloudcontrolapi" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "cloudformation" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "cloudfront" : { + "endpoints" : { + "aws-cn-global" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "cloudfront.cn-northwest-1.amazonaws.com.cn", + "protocols" : [ "http", "https" ] + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-cn-global" + }, + "cloudtrail" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "codebuild" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "codecommit" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "codedeploy" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "codepipeline" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "cognito-identity" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "cognito-identity.cn-north-1.amazonaws.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "compute-optimizer" : { + "endpoints" : { + "cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "compute-optimizer.cn-north-1.amazonaws.com.cn" + }, + "cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "compute-optimizer.cn-northwest-1.amazonaws.com.cn" + } + } + }, + "config" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "cur" : { + "endpoints" : { + "cn-northwest-1" : { } + } + }, + "data-ats.iot" : { + "defaults" : { + "credentialScope" : { + "service" : "iotdata" + }, + "protocols" : [ "https" ] + }, + "endpoints" : { + "cn-north-1" : { + "hostname" : "data.ats.iot.cn-north-1.amazonaws.com.cn", + "protocols" : [ "https" ] + }, + "cn-northwest-1" : { } + } + }, + "data.iot" : { + "defaults" : { + "credentialScope" : { + "service" : "iotdata" + }, + "protocols" : [ "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "data.jobs.iot" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "databrew" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "datasync" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "datasync.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "datasync.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "datazone" : { + "defaults" : { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "variants" : [ { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "cn-north-1" : { + "hostname" : "datazone.cn-north-1.api.amazonwebservices.com.cn" + }, + "cn-northwest-1" : { + "hostname" : "datazone.cn-northwest-1.api.amazonwebservices.com.cn" + } + } + }, + "dax" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "directconnect" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "dlm" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "dlm.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "dlm.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "dms" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "docdb" : { + "endpoints" : { + "cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "rds.cn-northwest-1.amazonaws.com.cn" + } + } + }, + "ds" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "dynamodb" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "ebs" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "ec2" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "ecs" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "eks" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "eks-auth" : { + "defaults" : { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "variants" : [ { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "cn-north-1" : { + "hostname" : "eks-auth.cn-north-1.api.amazonwebservices.com.cn" + }, + "cn-northwest-1" : { + "hostname" : "eks-auth.cn-northwest-1.api.amazonwebservices.com.cn" + } + } + }, + "elasticache" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "elasticbeanstalk" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "elasticbeanstalk.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "elasticfilesystem" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.cn-north-1.amazonaws.com.cn", + "tags" : [ "fips" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.cn-northwest-1.amazonaws.com.cn", + "tags" : [ "fips" ] + } ] + }, + "fips-cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.cn-north-1.amazonaws.com.cn" + }, + "fips-cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.cn-northwest-1.amazonaws.com.cn" + } + } + }, + "elasticloadbalancing" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "elasticmapreduce" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "elasticmapreduce.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "elasticmapreduce.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "emr-containers" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "emr-serverless" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "entitlement.marketplace" : { + "endpoints" : { + "cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "entitlement-marketplace.cn-northwest-1.amazonaws.com.cn", + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "entitlement-marketplace.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "es" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "aos.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "aos.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "events" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "events.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "events.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "firehose" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "firehose.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "firehose.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "fms" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "fsx" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "gamelift" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "gameliftstreams" : { + "defaults" : { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "variants" : [ { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "cn-north-1" : { + "hostname" : "gameliftstreams.cn-north-1.api.amazonwebservices.com.cn" + }, + "cn-northwest-1" : { + "hostname" : "gameliftstreams.cn-northwest-1.api.amazonwebservices.com.cn" + } + } + }, + "glacier" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "glue" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "glue.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "glue.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "greengrass" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "cn-north-1" : { } + }, + "isRegionalized" : true + }, + "guardduty" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + }, + "isRegionalized" : true + }, + "health" : { + "defaults" : { + "protocols" : [ "https" ], + "sslCommonName" : "health.cn-northwest-1.amazonaws.com.cn" + }, + "endpoints" : { + "aws-cn-global" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "global.health.amazonaws.com.cn" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-cn-global" + }, + "iam" : { + "endpoints" : { + "aws-cn-global" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "iam.cn-north-1.amazonaws.com.cn" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-cn-global" + }, + "identitystore" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "inspector2" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "internetmonitor" : { + "defaults" : { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "variants" : [ { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "cn-north-1" : { + "hostname" : "internetmonitor.cn-north-1.api.amazonwebservices.com.cn" + }, + "cn-northwest-1" : { + "hostname" : "internetmonitor.cn-northwest-1.api.amazonwebservices.com.cn" + } + } + }, + "iot" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "iotanalytics" : { + "endpoints" : { + "cn-north-1" : { } + } + }, + "iotevents" : { + "endpoints" : { + "cn-north-1" : { } + } + }, + "ioteventsdata" : { + "endpoints" : { + "cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "data.iotevents.cn-north-1.amazonaws.com.cn" + } + } + }, + "iotsecuredtunneling" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "iotsitewise" : { + "endpoints" : { + "cn-north-1" : { } + } + }, + "iottwinmaker" : { + "endpoints" : { + "api-cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "api.iottwinmaker.cn-north-1.amazonaws.com.cn" + }, + "cn-north-1" : { }, + "data-cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "data.iottwinmaker.cn-north-1.amazonaws.com.cn" + } + } + }, + "kafka" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "kafkaconnect" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "kendra-ranking" : { + "defaults" : { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "variants" : [ { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "cn-north-1" : { + "hostname" : "kendra-ranking.cn-north-1.api.amazonwebservices.com.cn" + }, + "cn-northwest-1" : { + "hostname" : "kendra-ranking.cn-northwest-1.api.amazonwebservices.com.cn" + } + } + }, + "kinesis" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "kinesisanalytics" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "kinesisvideo" : { + "endpoints" : { + "cn-north-1" : { } + } + }, + "kms" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "lakeformation" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "lakeformation.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "lakeformation.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "lambda" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "lambda.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "lambda.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "license-manager" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "license-manager-linux-subscriptions" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "logs" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "logs.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "logs.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "mediaconvert" : { + "endpoints" : { + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "mediaconvert.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "memory-db" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "metering.marketplace" : { + "defaults" : { + "credentialScope" : { + "service" : "aws-marketplace" + } + }, + "endpoints" : { + "cn-northwest-1" : { } + } + }, + "metrics.sagemaker" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "monitoring" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "mq" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "neptune" : { + "endpoints" : { + "cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "rds.cn-north-1.amazonaws.com.cn" + }, + "cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "rds.cn-northwest-1.amazonaws.com.cn" + } + } + }, + "network-firewall" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "notifications" : { + "defaults" : { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "variants" : [ { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "cn-north-1" : { + "hostname" : "notifications.cn-north-1.api.amazonwebservices.com.cn" + }, + "cn-northwest-1" : { + "hostname" : "notifications.cn-northwest-1.api.amazonwebservices.com.cn" + } + } + }, + "oam" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "oidc" : { + "endpoints" : { + "cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "oidc.cn-north-1.amazonaws.com.cn" + }, + "cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "oidc.cn-northwest-1.amazonaws.com.cn" + } + } + }, + "organizations" : { + "endpoints" : { + "aws-cn-global" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "organizations.cn-northwest-1.amazonaws.com.cn" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-cn-global" + }, + "personalize" : { + "endpoints" : { + "cn-north-1" : { } + } + }, + "pi" : { + "endpoints" : { + "cn-north-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "pipes" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "polly" : { + "endpoints" : { + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "polly.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "portal.sso" : { + "endpoints" : { + "cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "portal.sso.cn-north-1.amazonaws.com.cn" + }, + "cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "portal.sso.cn-northwest-1.amazonaws.com.cn" + } + } + }, + "qbusiness" : { + "defaults" : { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "variants" : [ { + "dnsSuffix" : "api.amazonwebservices.com.cn", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "cn-north-1" : { + "hostname" : "qbusiness.cn-north-1.api.amazonwebservices.com.cn" + }, + "cn-northwest-1" : { + "hostname" : "qbusiness.cn-northwest-1.api.amazonwebservices.com.cn" + } + } + }, + "quicksight" : { + "endpoints" : { + "cn-north-1" : { } + } + }, + "ram" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + } + } + }, + "rbin" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "rbin.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "rbin.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "rds" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "redshift" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "redshift-serverless" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "resource-groups" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "rolesanywhere" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "route53" : { + "endpoints" : { + "aws-cn-global" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "route53.amazonaws.com.cn" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-cn-global" + }, + "route53profiles" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "route53resolver" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "route53resolver.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "route53resolver.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "runtime.sagemaker" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "s3" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "dnsSuffix" : "amazonaws.com.cn", + "hostname" : "{service}.dualstack.{region}.{dnsSuffix}", + "tags" : [ "dualstack" ] + } ] + }, + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "s3.dualstack.cn-north-1.amazonaws.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "s3.dualstack.cn-northwest-1.amazonaws.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "s3-control" : { + "defaults" : { + "protocols" : [ "https" ], + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "dnsSuffix" : "amazonaws.com.cn", + "hostname" : "{service}.dualstack.{region}.{dnsSuffix}", + "tags" : [ "dualstack" ] + } ] + }, + "endpoints" : { + "cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "s3-control.cn-north-1.amazonaws.com.cn", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.cn-north-1.amazonaws.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "s3-control.cn-northwest-1.amazonaws.com.cn", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control.dualstack.cn-northwest-1.amazonaws.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "savingsplans" : { + "endpoints" : { + "cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "savingsplans.cn-north-1.amazonaws.com.cn" + }, + "cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "savingsplans.cn-northwest-1.amazonaws.com.cn" + } + }, + "isRegionalized" : true + }, + "scheduler" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "schemas" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "secretsmanager" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + } ] + } + } + }, + "securityhub" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "serverlessrepo" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "cn-north-1" : { + "protocols" : [ "https" ] + }, + "cn-northwest-1" : { + "protocols" : [ "https" ] + } + } + }, + "servicecatalog" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "servicediscovery" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "servicediscovery.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "servicediscovery.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "servicequotas" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "signer" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { }, + "verification-cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "verification.signer.cn-north-1.amazonaws.com.cn" + }, + "verification-cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "verification.signer.cn-northwest-1.amazonaws.com.cn" + } + } + }, + "snowball" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "snowball-fips.cn-north-1.amazonaws.com.cn", + "tags" : [ "fips" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "snowball-fips.cn-northwest-1.amazonaws.com.cn", + "tags" : [ "fips" ] + } ] + }, + "fips-cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.cn-north-1.amazonaws.com.cn" + }, + "fips-cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.cn-northwest-1.amazonaws.com.cn" + } + } + }, + "sns" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "sns.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "sns.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "sqs" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "sslCommonName" : "{region}.queue.{dnsSuffix}" + }, + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "sqs.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "sqs.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "ssm" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "sso" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "states" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "states.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "states.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "storagegateway" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "streams.dynamodb" : { + "defaults" : { + "credentialScope" : { + "service" : "dynamodb" + }, + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "sts" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "support" : { + "endpoints" : { + "aws-cn-global" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "support.cn-north-1.amazonaws.com.cn" + } + }, + "partitionEndpoint" : "aws-cn-global" + }, + "swf" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "synthetics" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "synthetics.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "synthetics.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "tagging" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "transcribe" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "cn.transcribe.cn-north-1.amazonaws.com.cn", + "variants" : [ { + "hostname" : "transcribe.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "cn.transcribe.cn-northwest-1.amazonaws.com.cn", + "variants" : [ { + "hostname" : "transcribe.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "transcribestreaming" : { + "endpoints" : { + "cn-north-1" : { + "variants" : [ { + "hostname" : "transcribestreaming.cn-north-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + }, + "cn-northwest-1" : { + "variants" : [ { + "hostname" : "transcribestreaming.cn-northwest-1.api.amazonwebservices.com.cn", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "transfer" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "verifiedpermissions" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + }, + "waf-regional" : { + "endpoints" : { + "cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "waf-regional.cn-north-1.amazonaws.com.cn", + "variants" : [ { + "hostname" : "waf-regional-fips.cn-north-1.amazonaws.com.cn", + "tags" : [ "fips" ] + } ] + }, + "cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "waf-regional.cn-northwest-1.amazonaws.com.cn", + "variants" : [ { + "hostname" : "waf-regional-fips.cn-northwest-1.amazonaws.com.cn", + "tags" : [ "fips" ] + } ] + }, + "fips-cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.cn-north-1.amazonaws.com.cn" + }, + "fips-cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.cn-northwest-1.amazonaws.com.cn" + } + } + }, + "wafv2" : { + "endpoints" : { + "cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "hostname" : "wafv2.cn-north-1.amazonaws.com.cn", + "variants" : [ { + "hostname" : "wafv2-fips.cn-north-1.amazonaws.com.cn", + "tags" : [ "fips" ] + } ] + }, + "cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "hostname" : "wafv2.cn-northwest-1.amazonaws.com.cn", + "variants" : [ { + "hostname" : "wafv2-fips.cn-northwest-1.amazonaws.com.cn", + "tags" : [ "fips" ] + } ] + }, + "fips-cn-north-1" : { + "credentialScope" : { + "region" : "cn-north-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.cn-north-1.amazonaws.com.cn" + }, + "fips-cn-northwest-1" : { + "credentialScope" : { + "region" : "cn-northwest-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.cn-northwest-1.amazonaws.com.cn" + } + } + }, + "workspaces" : { + "endpoints" : { + "cn-northwest-1" : { } + } + }, + "xray" : { + "endpoints" : { + "cn-north-1" : { }, + "cn-northwest-1" : { } + } + } + } + }, { + "defaults" : { + "hostname" : "{service}.{region}.{dnsSuffix}", + "protocols" : [ "https" ], + "signatureVersions" : [ "v4" ], + "variants" : [ { + "dnsSuffix" : "amazonaws.com", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + }, { + "dnsSuffix" : "api.aws", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "dualstack", "fips" ] + }, { + "dnsSuffix" : "api.aws", + "hostname" : "{service}.{region}.{dnsSuffix}", + "tags" : [ "dualstack" ] + } ] + }, + "dnsSuffix" : "amazonaws.com", + "partition" : "aws-us-gov", + "partitionName" : "AWS GovCloud (US)", + "regionRegex" : "^us\\-gov\\-\\w+\\-\\d+$", + "regions" : { + "us-gov-east-1" : { + "description" : "AWS GovCloud (US-East)" + }, + "us-gov-west-1" : { + "description" : "AWS GovCloud (US-West)" + } + }, + "services" : { + "access-analyzer" : { + "endpoints" : { + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "access-analyzer.us-gov-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "access-analyzer.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "access-analyzer.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "access-analyzer.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "access-analyzer.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "access-analyzer.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "access-analyzer.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "access-analyzer.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "access-analyzer.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "access-analyzer.us-gov-west-1.amazonaws.com" + } + } + }, + "acm" : { + "defaults" : { + "variants" : [ { + "hostname" : "acm.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "acm.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "acm.us-gov-west-1.amazonaws.com" + } + } + }, + "acm-pca" : { + "defaults" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "acm-pca.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "acm-pca.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "acm-pca.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "acm-pca.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "acm-pca.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "aoss" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "api.detective" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "api.detective-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "detective-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "detective.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "api.detective-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "api.detective-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "detective-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "detective.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "api.detective-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "api.ecr" : { + "defaults" : { + "variants" : [ { + "hostname" : "ecr-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "dkr-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "ecr-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "dkr-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "ecr-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "fips-dkr-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "ecr-fips.us-gov-east-1.amazonaws.com" + }, + "fips-dkr-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "ecr-fips.us-gov-west-1.amazonaws.com" + }, + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "ecr-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "ecr-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "api.ecr.us-gov-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ecr-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "ecr.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "api.ecr.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "ecr-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ecr-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "ecr.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "api.sagemaker" : { + "defaults" : { + "variants" : [ { + "hostname" : "api-fips.sagemaker.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "api-fips.sagemaker.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "api-fips.sagemaker.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "api-fips.sagemaker.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "api-fips.sagemaker.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1-fips-secondary" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "api.sagemaker.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1-secondary" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "api.sagemaker.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "api.tunneling.iot" : { + "defaults" : { + "variants" : [ { + "dnsSuffix" : "amazonaws.com", + "hostname" : "api.tunneling.iot-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + }, { + "dnsSuffix" : "api.aws", + "hostname" : "api.iot-tunneling-fips.{region}.{dnsSuffix}", + "tags" : [ "dualstack", "fips" ] + }, { + "dnsSuffix" : "api.aws", + "hostname" : "api.iot-tunneling.{region}.{dnsSuffix}", + "tags" : [ "dualstack" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "api.tunneling.iot-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "api.tunneling.iot-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "api.iot-tunneling.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "api.tunneling.iot-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "api.iot-tunneling-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "api.iot-tunneling.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "api.tunneling.iot-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "apigateway" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "appconfig" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "appconfig.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "appconfig.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "appconfig.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "appconfig.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "appconfigdata" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "appconfigdata.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "appconfigdata.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "appconfigdata.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "appconfigdata.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "application-autoscaling" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-gov-east-1" : { + "hostname" : "application-autoscaling.us-gov-east-1.amazonaws.com", + "protocols" : [ "http", "https" ], + "variants" : [ { + "hostname" : "application-autoscaling.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "deprecated" : true, + "hostname" : "application-autoscaling.us-gov-east-1.amazonaws.com", + "protocols" : [ "http", "https" ] + }, + "us-gov-west-1" : { + "hostname" : "application-autoscaling.us-gov-west-1.amazonaws.com", + "protocols" : [ "http", "https" ], + "variants" : [ { + "hostname" : "application-autoscaling.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "deprecated" : true, + "hostname" : "application-autoscaling.us-gov-west-1.amazonaws.com", + "protocols" : [ "http", "https" ] + } + } + }, + "applicationinsights" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "applicationinsights-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "applicationinsights-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "applicationinsights-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "applicationinsights-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "applicationinsights.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "applicationinsights-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "applicationinsights-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "applicationinsights.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "appstream2" : { + "defaults" : { + "credentialScope" : { + "service" : "appstream" + }, + "protocols" : [ "https" ] + }, + "endpoints" : { + "fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "appstream2-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "appstream2-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "appstream2-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "appstream2-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "appstream2-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "aps" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "arc-zonal-shift" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "athena" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "athena-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "athena-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "athena-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "athena-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "athena.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "athena-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "athena-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "athena.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "autoscaling" : { + "defaults" : { + "variants" : [ { + "hostname" : "autoscaling.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { + "protocols" : [ "http", "https" ] + }, + "us-gov-west-1" : { + "protocols" : [ "http", "https" ] + } + } + }, + "autoscaling-plans" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "autoscaling-plans.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "deprecated" : true, + "hostname" : "autoscaling-plans.us-gov-east-1.amazonaws.com", + "protocols" : [ "http", "https" ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "autoscaling-plans.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "deprecated" : true, + "hostname" : "autoscaling-plans.us-gov-west-1.amazonaws.com", + "protocols" : [ "http", "https" ] + } + } + }, + "backup" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "backup-gateway" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "batch" : { + "defaults" : { + "variants" : [ { + "hostname" : "batch.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "batch.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "batch.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "batch.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "batch.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "bedrock" : { + "endpoints" : { + "bedrock-fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "bedrock-fips.us-gov-east-1.amazonaws.com" + }, + "bedrock-fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "bedrock-fips.us-gov-west-1.amazonaws.com" + }, + "bedrock-runtime-fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "bedrock-runtime-fips.us-gov-east-1.amazonaws.com" + }, + "bedrock-runtime-fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "bedrock-runtime-fips.us-gov-west-1.amazonaws.com" + }, + "bedrock-runtime-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "bedrock-runtime.us-gov-east-1.amazonaws.com" + }, + "bedrock-runtime-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "bedrock-runtime.us-gov-west-1.amazonaws.com" + }, + "bedrock-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "bedrock.us-gov-east-1.amazonaws.com" + }, + "bedrock-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "bedrock.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "cassandra" : { + "endpoints" : { + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "cassandra.us-gov-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "cassandra.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "cassandra.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "cassandra.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "cassandra.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "cassandra.us-gov-west-1.amazonaws.com" + } + } + }, + "cloudcontrolapi" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "cloudcontrolapi-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "cloudcontrolapi-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cloudcontrolapi-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cloudcontrolapi.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "cloudcontrolapi-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cloudcontrolapi-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cloudcontrolapi.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "clouddirectory" : { + "endpoints" : { + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "clouddirectory.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "clouddirectory.us-gov-west-1.amazonaws.com" + } + } + }, + "cloudformation" : { + "endpoints" : { + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "cloudformation.us-gov-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "cloudformation.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "cloudformation.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "cloudformation.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "cloudformation.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "cloudformation.us-gov-west-1.amazonaws.com" + } + } + }, + "cloudhsm" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "cloudhsmv2" : { + "defaults" : { + "credentialScope" : { + "service" : "cloudhsm" + } + }, + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "cloudhsmv2.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "cloudtrail" : { + "defaults" : { + "variants" : [ { + "hostname" : "cloudtrail.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "cloudtrail.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "cloudtrail.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "cloudtrail.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "cloudtrail.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "codebuild" : { + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "codebuild-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "codebuild-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "codebuild-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "codebuild-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "codecommit" : { + "endpoints" : { + "fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "codecommit-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "codecommit-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "codecommit-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "codecommit-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "codecommit-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "codedeploy" : { + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "codedeploy-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "codedeploy-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "codedeploy-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "codedeploy-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "codepipeline" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "codepipeline-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "codepipeline-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "codepipeline-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "codepipeline-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "codestar-connections" : { + "endpoints" : { + "us-gov-east-1" : { } + } + }, + "cognito-identity" : { + "endpoints" : { + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "cognito-identity-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "cognito-identity.us-gov-east-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "cognito-identity-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cognito-identity-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cognito-identity.us-gov-west-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "cognito-idp" : { + "endpoints" : { + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "cognito-idp-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "cognito-idp.us-gov-east-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "cognito-idp-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "cognito-idp-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "cognito-idp.us-gov-west-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "comprehend" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "comprehend-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "comprehend-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "comprehend-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "comprehend.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "comprehendmedical" : { + "endpoints" : { + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "comprehendmedical-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "comprehendmedical-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "compute-optimizer" : { + "endpoints" : { + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "compute-optimizer-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "compute-optimizer-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "config" : { + "defaults" : { + "variants" : [ { + "hostname" : "config.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "config.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "config.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "config.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "config.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "connect" : { + "endpoints" : { + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "connect.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "connect.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "controltower" : { + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "controltower-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "controltower-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "controltower-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "controltower-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "data-ats.iot" : { + "defaults" : { + "credentialScope" : { + "service" : "iotdata" + }, + "protocols" : [ "https" ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "service" : "iotdata" + }, + "deprecated" : true, + "hostname" : "data.iot-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "service" : "iotdata" + }, + "deprecated" : true, + "hostname" : "data.iot-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "data.iot-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "data.iot-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "data.iot" : { + "defaults" : { + "credentialScope" : { + "service" : "iotdata" + }, + "protocols" : [ "https" ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "service" : "iotdata" + }, + "deprecated" : true, + "hostname" : "data.iot-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "service" : "iotdata" + }, + "deprecated" : true, + "hostname" : "data.iot-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "data.iot-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "data.iot-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "data.jobs.iot" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "data.jobs.iot-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "data.jobs.iot-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "data.jobs.iot-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "data.jobs.iot-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "databrew" : { + "endpoints" : { + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "databrew.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "databrew.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "datasync" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "datasync-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "datasync-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "datasync-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "datasync-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "datasync.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "datasync-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "datasync-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "datasync.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "datazone" : { + "defaults" : { + "dnsSuffix" : "api.aws", + "variants" : [ { + "dnsSuffix" : "api.aws", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { + "hostname" : "datazone.us-gov-east-1.api.aws" + }, + "us-gov-west-1" : { + "hostname" : "datazone.us-gov-west-1.api.aws" + } + } + }, + "directconnect" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "directconnect-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "directconnect-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "directconnect-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "directconnect-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "dlm" : { + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "dlm-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "dlm.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "dlm.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "dlm.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "dlm-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "dlm.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "dlm.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "dlm.us-gov-west-1.amazonaws.com" + } + } + }, + "dms" : { + "defaults" : { + "variants" : [ { + "hostname" : "dms.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "dms" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "dms.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "dms-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "dms.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "dms.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "dms.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "dms.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "dms.us-gov-west-1.amazonaws.com" + } + } + }, + "docdb" : { + "endpoints" : { + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "rds.us-gov-west-1.amazonaws.com" + } + } + }, + "drs" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "drs-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "drs-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "drs-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "drs-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "ds" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "ds-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "ds-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "ds-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "ds-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "dynamodb" : { + "defaults" : { + "variants" : [ { + "hostname" : "dynamodb.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "dynamodb-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "dynamodb-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "dynamodb-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "dynamodb-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "ebs" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "ec2" : { + "defaults" : { + "variants" : [ { + "hostname" : "ec2.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "ec2.us-gov-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "ec2.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "ec2.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "ec2.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "ecs" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "ecs-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "ecs-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "ecs-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "ecs-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "eks" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "variants" : [ { + "hostname" : "eks.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "eks.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "eks.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "eks.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "eks.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "eks-auth" : { + "defaults" : { + "dnsSuffix" : "api.aws", + "variants" : [ { + "dnsSuffix" : "api.aws", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { + "hostname" : "eks-auth.us-gov-east-1.api.aws" + }, + "us-gov-west-1" : { + "hostname" : "eks-auth.us-gov-west-1.api.aws" + } + } + }, + "elasticache" : { + "defaults" : { + "variants" : [ { + "hostname" : "elasticache.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "elasticache.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "elasticache.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "elasticache.us-gov-west-1.amazonaws.com" + } + } + }, + "elasticbeanstalk" : { + "endpoints" : { + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "elasticbeanstalk.us-gov-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "elasticbeanstalk.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "elasticbeanstalk.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "elasticbeanstalk.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "elasticbeanstalk.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "elasticbeanstalk.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "elasticbeanstalk.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "elasticbeanstalk.us-gov-west-1.amazonaws.com" + } + } + }, + "elasticfilesystem" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "elasticloadbalancing" : { + "defaults" : { + "variants" : [ { + "hostname" : "elasticloadbalancing.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "elasticloadbalancing.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "elasticloadbalancing.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "elasticloadbalancing.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "protocols" : [ "http", "https" ], + "variants" : [ { + "hostname" : "elasticloadbalancing.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "elasticmapreduce" : { + "defaults" : { + "variants" : [ { + "hostname" : "elasticmapreduce.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "elasticmapreduce.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "elasticmapreduce.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "elasticmapreduce.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "elasticmapreduce.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "elasticmapreduce.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "elasticmapreduce.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "email" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "email-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "email-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "email-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "email-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "emr-containers" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "emr-containers.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "emr-containers.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "emr-containers.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "emr-containers.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "emr-serverless" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "emr-serverless.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "emr-serverless.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "emr-serverless.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "emr-serverless.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "es" : { + "endpoints" : { + "fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "es-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "aos.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "es-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "es-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "aos.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "es-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "es-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "events" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "events.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "events.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "events.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "events.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "firehose" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "firehose-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "firehose-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "firehose-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "firehose-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "fms" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "fms-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "fms-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "fms-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "fms-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "fsx" : { + "endpoints" : { + "fips-prod-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "fsx-fips.us-gov-east-1.amazonaws.com" + }, + "fips-prod-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "fsx-fips.us-gov-west-1.amazonaws.com" + }, + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "fsx-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "fsx-fips.us-gov-west-1.amazonaws.com" + }, + "prod-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "fsx-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "prod-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "fsx-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "fsx-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "fsx-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "gameliftstreams" : { + "defaults" : { + "dnsSuffix" : "api.aws", + "variants" : [ { + "dnsSuffix" : "api.aws", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { + "hostname" : "gameliftstreams.us-gov-east-1.api.aws" + }, + "us-gov-west-1" : { + "hostname" : "gameliftstreams.us-gov-west-1.api.aws" + } + } + }, + "geo" : { + "endpoints" : { + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "geo-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "geo-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "glacier" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "glacier.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "glacier.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "glacier.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "protocols" : [ "http", "https" ], + "variants" : [ { + "hostname" : "glacier.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "glue" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "glue-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "glue-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "glue-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "glue-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "glue.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "glue-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "glue-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "glue.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "greengrass" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "dataplane-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "greengrass-ats.iot.us-gov-east-1.amazonaws.com" + }, + "dataplane-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "greengrass-ats.iot.us-gov-west-1.amazonaws.com" + }, + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "greengrass.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "greengrass.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "greengrass.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "greengrass.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + }, + "isRegionalized" : true + }, + "guardduty" : { + "defaults" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "guardduty.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "guardduty.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "guardduty.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "guardduty.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "guardduty.us-gov-west-1.amazonaws.com" + } + }, + "isRegionalized" : true + }, + "health" : { + "defaults" : { + "protocols" : [ "https" ], + "sslCommonName" : "health.us-gov-west-1.amazonaws.com" + }, + "endpoints" : { + "aws-us-gov-global" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "global.health.us-gov.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "health-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "health-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "iam" : { + "endpoints" : { + "aws-us-gov-global" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "iam.us-gov.amazonaws.com", + "variants" : [ { + "hostname" : "iam.us-gov.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "aws-us-gov-global-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "iam.us-gov.amazonaws.com" + }, + "iam-govcloud" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "iam.us-gov.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "iam-govcloud-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "iam.us-gov.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-us-gov-global" + }, + "identitystore" : { + "defaults" : { + "variants" : [ { + "hostname" : "identitystore.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "identitystore.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "identitystore.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "identitystore.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "identitystore.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "ingest.timestream" : { + "endpoints" : { + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "ingest.timestream.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "ingest.timestream.us-gov-west-1.amazonaws.com" + } + } + }, + "inspector" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "inspector-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "inspector-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "inspector-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "inspector-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "inspector2" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "inspector2-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "inspector2-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "inspector2-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "inspector2-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "internetmonitor" : { + "defaults" : { + "dnsSuffix" : "api.aws", + "variants" : [ { + "dnsSuffix" : "api.aws", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { + "hostname" : "internetmonitor.us-gov-east-1.api.aws" + }, + "us-gov-west-1" : { + "hostname" : "internetmonitor.us-gov-west-1.api.aws" + } + } + }, + "iot" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "deprecated" : true, + "hostname" : "iot-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "deprecated" : true, + "hostname" : "iot-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "iot-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "iot-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "iotevents" : { + "endpoints" : { + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "iotevents-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "iotevents-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "ioteventsdata" : { + "endpoints" : { + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "data.iotevents-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "data.iotevents.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "data.iotevents-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "iotsecuredtunneling" : { + "defaults" : { + "variants" : [ { + "hostname" : "api.tunneling.iot-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "api.tunneling.iot-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "api.tunneling.iot-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "api.tunneling.iot-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "api.tunneling.iot-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "iotsitewise" : { + "endpoints" : { + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "iotsitewise-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "iotsitewise-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "iottwinmaker" : { + "endpoints" : { + "api-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "api.iottwinmaker.us-gov-west-1.amazonaws.com" + }, + "data-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "data.iottwinmaker.us-gov-west-1.amazonaws.com" + }, + "fips-api-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "api.iottwinmaker-fips.us-gov-west-1.amazonaws.com" + }, + "fips-data-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "data.iottwinmaker-fips.us-gov-west-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "iottwinmaker-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "iottwinmaker-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "kafka" : { + "endpoints" : { + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "kafka.us-gov-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "kafka.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "kafka.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "kafka.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "kafka.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "kafka.us-gov-west-1.amazonaws.com" + } + } + }, + "kafkaconnect" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "kendra" : { + "endpoints" : { + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "kendra-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "kendra-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "kendra-ranking" : { + "defaults" : { + "dnsSuffix" : "api.aws", + "variants" : [ { + "dnsSuffix" : "api.aws", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { + "hostname" : "kendra-ranking.us-gov-east-1.api.aws" + }, + "us-gov-west-1" : { + "hostname" : "kendra-ranking.us-gov-west-1.api.aws" + } + } + }, + "kinesis" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "kinesis.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "kinesis.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "kinesis.us-gov-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "kinesis.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "kinesis.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "kinesis.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "kinesisanalytics" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "kinesisanalytics-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "kinesisanalytics-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "kinesisanalytics-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "kinesisanalytics-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "kinesisvideo" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "kinesisvideo-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "kinesisvideo-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "kinesisvideo-fips.us-gov-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "kinesisvideo-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "kinesisvideo-fips.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "kinesisvideo-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "kms" : { + "endpoints" : { + "ProdFips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "kms-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "kms-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "lakeformation" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "lakeformation-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "lakeformation-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "lakeformation-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "lakeformation-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "lakeformation.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "lakeformation-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "lakeformation-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "lakeformation.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "lambda" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "lambda-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "lambda-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "lambda-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "lambda.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "lambda-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "lambda.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "license-manager" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "license-manager-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "license-manager-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "license-manager-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "license-manager-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "license-manager-linux-subscriptions" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "license-manager-user-subscriptions" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "logs" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "logs.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "logs.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "logs.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "logs.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "logs.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "logs.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "m2" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "deprecated" : true + }, + "fips-us-gov-west-1" : { + "deprecated" : true + }, + "us-gov-east-1" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + } + } + }, + "managedblockchain" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "mediaconvert" : { + "endpoints" : { + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "mediaconvert.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "mediaconvert.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "mediaconvert.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "mediaconvert.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + } + } + }, + "meetings-chime" : { + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "meetings-chime-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "meetings-chime-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "meetings-chime-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "meetings-chime-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "memory-db" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "metering.marketplace" : { + "defaults" : { + "credentialScope" : { + "service" : "aws-marketplace" + } + }, + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "metering-marketplace.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "metrics.sagemaker" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "mgn" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "mgn-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "mgn-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "mgn-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "mgn-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "models-v2-lex" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "models.lex" : { + "defaults" : { + "credentialScope" : { + "service" : "lex" + }, + "variants" : [ { + "hostname" : "models-fips.lex.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "models-fips.lex.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "models-fips.lex.us-gov-west-1.amazonaws.com" + } + } + }, + "monitoring" : { + "defaults" : { + "variants" : [ { + "hostname" : "monitoring.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "monitoring.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "monitoring.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "monitoring.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "monitoring.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "mq" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "mq-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "mq-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "mq-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "mq-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "neptune" : { + "endpoints" : { + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "rds.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "rds.us-gov-west-1.amazonaws.com" + } + } + }, + "network-firewall" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "network-firewall-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "network-firewall-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "network-firewall-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "network-firewall-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "networkmanager" : { + "endpoints" : { + "aws-us-gov-global" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "networkmanager.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "networkmanager.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "networkmanager.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "networkmanager.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "fips-aws-us-gov-global" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "networkmanager.us-gov-west-1.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-us-gov-global" + }, + "notifications" : { + "defaults" : { + "dnsSuffix" : "api.aws", + "variants" : [ { + "dnsSuffix" : "api.aws", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { + "hostname" : "notifications.us-gov-east-1.api.aws" + }, + "us-gov-west-1" : { + "hostname" : "notifications.us-gov-west-1.api.aws" + } + } + }, + "oam" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "oidc" : { + "endpoints" : { + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "oidc.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "oidc.us-gov-west-1.amazonaws.com" + } + } + }, + "organizations" : { + "endpoints" : { + "aws-us-gov-global" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "organizations.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "organizations.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "fips-aws-us-gov-global" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "organizations.us-gov-west-1.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-us-gov-global" + }, + "outposts" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "outposts.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "outposts.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "outposts.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "outposts.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "participant.connect" : { + "endpoints" : { + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "participant.connect.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "participant.connect.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "pi" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "pi-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "pi-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "pi-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "pi.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "pi-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "pi-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "pi.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "pinpoint" : { + "defaults" : { + "credentialScope" : { + "service" : "mobiletargeting" + } + }, + "endpoints" : { + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "pinpoint-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "pinpoint.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "pinpoint-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "polly" : { + "endpoints" : { + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "polly-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "polly-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "polly-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "polly.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "portal.sso" : { + "endpoints" : { + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "portal.sso.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "portal.sso.us-gov-west-1.amazonaws.com" + } + } + }, + "qbusiness" : { + "defaults" : { + "dnsSuffix" : "api.aws", + "variants" : [ { + "dnsSuffix" : "api.aws", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { + "hostname" : "qbusiness.us-gov-east-1.api.aws" + }, + "us-gov-west-1" : { + "hostname" : "qbusiness.us-gov-west-1.api.aws" + } + } + }, + "query.timestream" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "quicksight" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "ram" : { + "endpoints" : { + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "ram.us-gov-east-1.amazonaws.com", + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "hostname" : "ram.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ramus-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "ram.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "ram.us-gov-west-1.amazonaws.com", + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "hostname" : "ram.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "ramus-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "ram.us-gov-west-1.amazonaws.com" + } + } + }, + "rbin" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "rbin-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "rbin-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "rbin-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "rbin-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "rbin.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "rbin-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "rbin-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "rbin.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "rds" : { + "defaults" : { + "variants" : [ { + "hostname" : "rds.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "rds.us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "rds.us-gov-east-1.amazonaws.com" + }, + "rds.us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "rds.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "rds.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "rds.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "rds.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "rds.us-gov-west-1.amazonaws.com" + } + } + }, + "redshift" : { + "endpoints" : { + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "redshift.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "redshift.us-gov-west-1.amazonaws.com" + } + } + }, + "redshift-serverless" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "redshift-serverless-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "redshift-serverless-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "redshift-serverless-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "redshift-serverless-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "rekognition" : { + "endpoints" : { + "rekognition-fips.us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "rekognition-fips.us-gov-west-1.amazonaws.com" + }, + "rekognition.us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "rekognition-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "rekognition-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "rekognition-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "rekognition.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "rekognition-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "resiliencehub" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "resiliencehub-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "resiliencehub-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "resiliencehub-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "resiliencehub-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "resiliencehub.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "resiliencehub-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "resiliencehub-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "resiliencehub.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "resource-groups" : { + "defaults" : { + "variants" : [ { + "hostname" : "resource-groups.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "resource-groups.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "resource-groups.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "resource-groups.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "resource-groups.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "rolesanywhere" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "rolesanywhere-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "rolesanywhere-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "rolesanywhere-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "rolesanywhere-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "route53" : { + "endpoints" : { + "aws-us-gov-global" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "route53.us-gov.amazonaws.com", + "variants" : [ { + "hostname" : "route53.us-gov.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "fips-aws-us-gov-global" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "route53.us-gov.amazonaws.com" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-us-gov-global" + }, + "route53profiles" : { + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "route53profiles-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "route53profiles.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "route53profiles-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "route53profiles.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "route53resolver" : { + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "route53resolver.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "route53resolver.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "route53resolver.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "deprecated" : true, + "hostname" : "route53resolver.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "route53resolver.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "route53resolver.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + }, { + "hostname" : "route53resolver.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "deprecated" : true, + "hostname" : "route53resolver.us-gov-west-1.amazonaws.com" + } + } + }, + "rum" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "runtime-v2-lex" : { + "endpoints" : { + "us-gov-west-1" : { } + } + }, + "runtime.lex" : { + "defaults" : { + "credentialScope" : { + "service" : "lex" + }, + "variants" : [ { + "hostname" : "runtime-fips.lex.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "runtime-fips.lex.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "runtime-fips.lex.us-gov-west-1.amazonaws.com" + } + } + }, + "runtime.sagemaker" : { + "defaults" : { + "variants" : [ { + "hostname" : "runtime.sagemaker.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "runtime.sagemaker.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "runtime.sagemaker.us-gov-west-1.amazonaws.com" + } + } + }, + "s3" : { + "defaults" : { + "signatureVersions" : [ "s3", "s3v4" ], + "variants" : [ { + "dnsSuffix" : "amazonaws.com", + "hostname" : "{service}-fips.dualstack.{region}.{dnsSuffix}", + "tags" : [ "dualstack", "fips" ] + }, { + "dnsSuffix" : "amazonaws.com", + "hostname" : "{service}.dualstack.{region}.{dnsSuffix}", + "tags" : [ "dualstack" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "s3-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "s3-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "hostname" : "s3.us-gov-east-1.amazonaws.com", + "protocols" : [ "http", "https" ], + "variants" : [ { + "hostname" : "s3-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "s3.dualstack.us-gov-east-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "hostname" : "s3.us-gov-west-1.amazonaws.com", + "protocols" : [ "http", "https" ], + "variants" : [ { + "hostname" : "s3-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "s3.dualstack.us-gov-west-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "s3-control" : { + "defaults" : { + "protocols" : [ "https" ], + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "dnsSuffix" : "amazonaws.com", + "hostname" : "{service}-fips.dualstack.{region}.{dnsSuffix}", + "tags" : [ "dualstack", "fips" ] + }, { + "dnsSuffix" : "amazonaws.com", + "hostname" : "{service}.dualstack.{region}.{dnsSuffix}", + "tags" : [ "dualstack" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "s3-control.us-gov-east-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control-fips.dualstack.us-gov-east-1.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-control-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "s3-control.dualstack.us-gov-east-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "s3-control-fips.us-gov-east-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ] + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "s3-control.us-gov-west-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control-fips.dualstack.us-gov-west-1.amazonaws.com", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-control-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "s3-control.dualstack.us-gov-west-1.amazonaws.com", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "s3-control-fips.us-gov-west-1.amazonaws.com", + "signatureVersions" : [ "s3v4" ] + } + } + }, + "s3-outposts" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "deprecated" : true + }, + "fips-us-gov-west-1" : { + "deprecated" : true + }, + "us-gov-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + } + } + }, + "scheduler" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "schemas" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "secretsmanager" : { + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "deprecated" : true + }, + "us-gov-west-1" : { + "variants" : [ { + "tags" : [ "dualstack" ] + }, { + "tags" : [ "dualstack", "fips" ] + }, { + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "deprecated" : true + } + } + }, + "securityhub" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "securityhub-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "securityhub-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "securityhub-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "securityhub.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "securityhub-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "securityhub.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "securitylake" : { + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "securitylake.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "securitylake.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "securitylake.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "securitylake.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "securitylake.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "securitylake.us-gov-west-1.amazonaws.com" + } + } + }, + "serverlessrepo" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "us-gov-east-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "serverlessrepo.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "serverlessrepo.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "serverlessrepo.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "serverlessrepo.us-gov-west-1.amazonaws.com" + } + } + }, + "servicecatalog" : { + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "servicecatalog-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "servicecatalog-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "servicecatalog-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "servicecatalog-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "servicecatalog-appregistry" : { + "defaults" : { + "variants" : [ { + "hostname" : "servicecatalog-appregistry.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "servicediscovery" : { + "endpoints" : { + "servicediscovery" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "servicediscovery-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "servicediscovery-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "servicediscovery-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "servicediscovery-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "servicediscovery-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "servicediscovery.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "servicediscovery-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "servicediscovery-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "servicediscovery-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "servicediscovery.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "servicediscovery-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "servicequotas" : { + "defaults" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "servicequotas.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "servicequotas.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "servicequotas.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "servicequotas.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "servicequotas.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "signer" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "signer-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "signer-fips.us-gov-west-1.amazonaws.com" + }, + "fips-verification-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "verification.signer-fips.us-gov-east-1.amazonaws.com" + }, + "fips-verification-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "verification.signer-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "signer-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "signer-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "verification-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "verification.signer.us-gov-east-1.amazonaws.com" + }, + "verification-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "verification.signer.us-gov-west-1.amazonaws.com" + } + } + }, + "simspaceweaver" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "simspaceweaver.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "simspaceweaver.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "simspaceweaver.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "simspaceweaver.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "sms-voice" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "sms-voice-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "sms-voice-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "sms-voice-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sms-voice-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "sms-voice.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "sms-voice-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "sms-voice-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "sms-voice.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "snowball" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "snowball-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "snowball-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "snowball-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "snowball-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "snowball.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "sns" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "sns.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "sns.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "sns.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "sns.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "sqs" : { + "defaults" : { + "variants" : [ { + "hostname" : "sqs.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "sqs.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "sqs.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "sqs.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "protocols" : [ "http", "https" ], + "sslCommonName" : "{region}.queue.{dnsSuffix}", + "variants" : [ { + "hostname" : "sqs.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "ssm" : { + "defaults" : { + "variants" : [ { + "hostname" : "ssm.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "ssm.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "ssm.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "ssm.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "ssm.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "sso" : { + "endpoints" : { + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "sso.us-gov-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "sso.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "sso.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "sso.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "sso.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "sso.us-gov-west-1.amazonaws.com" + } + } + }, + "states" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "states-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "states.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "states-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "states.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "storagegateway" : { + "endpoints" : { + "fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "storagegateway-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "storagegateway-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "storagegateway-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "storagegateway-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "storagegateway-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "streams.dynamodb" : { + "defaults" : { + "credentialScope" : { + "service" : "dynamodb" + }, + "variants" : [ { + "hostname" : "streams.dynamodb.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "sts" : { + "defaults" : { + "variants" : [ { + "hostname" : "sts.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "sts.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "sts.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "sts.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "sts.us-gov-west-1.amazonaws.com" + } + } + }, + "support" : { + "endpoints" : { + "aws-us-gov-global" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "support.us-gov-west-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "support.us-gov-west-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "support.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + }, + "partitionEndpoint" : "aws-us-gov-global" + }, + "swf" : { + "endpoints" : { + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "swf.us-gov-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "swf.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-east-1-fips" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "swf.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "swf.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "swf.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "swf.us-gov-west-1.amazonaws.com" + } + } + }, + "synthetics" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "synthetics-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "synthetics-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "synthetics-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "synthetics-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "synthetics.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "synthetics-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "synthetics-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "synthetics.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "tagging" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "textract" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "textract-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "textract-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "textract-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "textract-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "textract.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "textract-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "textract-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "textract.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "transcribe" : { + "defaults" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "fips.transcribe.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "fips.transcribe.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "fips.transcribe.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "fips.transcribe.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "transcribe-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "transcribe.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "fips.transcribe.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "transcribe-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "transcribe.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "transcribestreaming" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "transcribestreaming-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "transcribestreaming-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "transcribestreaming-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "transcribestreaming-fips.us-gov-east-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "transcribestreaming.us-gov-east-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "transcribestreaming-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "transcribestreaming-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "transcribestreaming.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "transfer" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "transfer-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "transfer-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "transfer-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "transfer-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "translate" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "translate-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + }, { + "hostname" : "translate-fips.us-gov-west-1.api.aws", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "translate.us-gov-west-1.api.aws", + "tags" : [ "dualstack" ] + } ] + }, + "us-gov-west-1-fips" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "translate-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "verifiedpermissions" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "verifiedpermissions-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "verifiedpermissions-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "verifiedpermissions-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "verifiedpermissions-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "waf-regional" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "waf-regional-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "waf-regional.us-gov-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "waf-regional.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "waf-regional-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "wafv2" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "wafv2-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "hostname" : "wafv2.us-gov-east-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "hostname" : "wafv2.us-gov-west-1.amazonaws.com", + "variants" : [ { + "hostname" : "wafv2-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "wellarchitected" : { + "endpoints" : { + "us-gov-east-1" : { }, + "us-gov-west-1" : { } + } + }, + "workspaces" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "workspaces-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "workspaces-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "workspaces-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "workspaces-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + }, + "xray" : { + "endpoints" : { + "fips-us-gov-east-1" : { + "credentialScope" : { + "region" : "us-gov-east-1" + }, + "deprecated" : true, + "hostname" : "xray-fips.us-gov-east-1.amazonaws.com" + }, + "fips-us-gov-west-1" : { + "credentialScope" : { + "region" : "us-gov-west-1" + }, + "deprecated" : true, + "hostname" : "xray-fips.us-gov-west-1.amazonaws.com" + }, + "us-gov-east-1" : { + "variants" : [ { + "hostname" : "xray-fips.us-gov-east-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + }, + "us-gov-west-1" : { + "variants" : [ { + "hostname" : "xray-fips.us-gov-west-1.amazonaws.com", + "tags" : [ "fips" ] + } ] + } + } + } + } + }, { + "defaults" : { + "hostname" : "{service}.{region}.{dnsSuffix}", + "protocols" : [ "https" ], + "signatureVersions" : [ "v4" ], + "variants" : [ { + "dnsSuffix" : "c2s.ic.gov", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "dnsSuffix" : "c2s.ic.gov", + "partition" : "aws-iso", + "partitionName" : "AWS ISO (US)", + "regionRegex" : "^us\\-iso\\-\\w+\\-\\d+$", + "regions" : { + "us-iso-east-1" : { + "description" : "US ISO East" + }, + "us-iso-west-1" : { + "description" : "US ISO WEST" + } + }, + "services" : { + "acm" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "agreement-marketplace" : { + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "agreement-marketplace-fips.us-iso-east-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "agreement-marketplace-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "api.ecr" : { + "endpoints" : { + "us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "hostname" : "api.ecr.us-iso-east-1.c2s.ic.gov" + }, + "us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "hostname" : "api.ecr.us-iso-west-1.c2s.ic.gov" + } + } + }, + "api.pricing" : { + "defaults" : { + "credentialScope" : { + "service" : "pricing" + } + }, + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "api.sagemaker" : { + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "apigateway" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "appconfig" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "appconfigdata" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "application-autoscaling" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "arc-zonal-shift" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "athena" : { + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "autoscaling" : { + "endpoints" : { + "us-iso-east-1" : { + "protocols" : [ "http", "https" ] + }, + "us-iso-west-1" : { } + } + }, + "backup" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "batch" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "bedrock" : { + "endpoints" : { + "bedrock-runtime-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "hostname" : "bedrock-runtime.us-iso-east-1.c2s.ic.gov" + }, + "bedrock-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "hostname" : "bedrock.us-iso-east-1.c2s.ic.gov" + }, + "us-iso-east-1" : { } + } + }, + "budgets" : { + "endpoints" : { + "aws-iso-global" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "hostname" : "budgets.c2s.ic.gov" + }, + "us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "hostname" : "budgets.c2s.ic.gov" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-global" + }, + "ce" : { + "endpoints" : { + "aws-iso-global" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "hostname" : "ce.us-iso-east-1.c2s.ic.gov" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-global" + }, + "cloudcontrolapi" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "cloudformation" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "cloudtrail" : { + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "cloudtrail-fips.us-iso-east-1.c2s.ic.gov" + }, + "fips-us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "cloudtrail-fips.us-iso-west-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "cloudtrail-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1" : { + "variants" : [ { + "hostname" : "cloudtrail-fips.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "codebuild" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "codedeploy" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "comprehend" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "comprehend-fips.us-iso-east-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "comprehend-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "config" : { + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "config-fips.us-iso-east-1.c2s.ic.gov" + }, + "fips-us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "config-fips.us-iso-west-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "config-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1" : { + "variants" : [ { + "hostname" : "config-fips.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "datapipeline" : { + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "datasync" : { + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "datasync-fips.us-iso-east-1.c2s.ic.gov" + }, + "fips-us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "datasync-fips.us-iso-west-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "datasync-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1" : { + "variants" : [ { + "hostname" : "datasync-fips.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "directconnect" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "dlm" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "dms" : { + "defaults" : { + "variants" : [ { + "hostname" : "dms.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "dms" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "dms.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "dms-fips" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "dms.us-iso-east-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "dms.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-east-1-fips" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "dms.us-iso-east-1.c2s.ic.gov" + }, + "us-iso-west-1" : { + "variants" : [ { + "hostname" : "dms.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1-fips" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "dms.us-iso-west-1.c2s.ic.gov" + } + } + }, + "ds" : { + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "ds-fips.us-iso-east-1.c2s.ic.gov" + }, + "fips-us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "ds-fips.us-iso-west-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "ds-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1" : { + "variants" : [ { + "hostname" : "ds-fips.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "dynamodb" : { + "endpoints" : { + "us-iso-east-1" : { + "protocols" : [ "http", "https" ] + }, + "us-iso-west-1" : { } + } + }, + "ebs" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "ec2" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "ecs" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "eks" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "elasticache" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "elasticfilesystem" : { + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.us-iso-east-1.c2s.ic.gov" + }, + "fips-us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.us-iso-west-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "elasticloadbalancing" : { + "endpoints" : { + "us-iso-east-1" : { + "protocols" : [ "http", "https" ] + }, + "us-iso-west-1" : { } + } + }, + "elasticmapreduce" : { + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "elasticmapreduce.us-iso-east-1.c2s.ic.gov" + }, + "fips-us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "elasticmapreduce.us-iso-west-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "protocols" : [ "https" ], + "variants" : [ { + "hostname" : "elasticmapreduce.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1" : { + "variants" : [ { + "hostname" : "elasticmapreduce.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "es" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "events" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "firehose" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "fsx" : { + "endpoints" : { + "fips-prod-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "fsx-fips.us-iso-east-1.c2s.ic.gov" + }, + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "fsx-fips.us-iso-east-1.c2s.ic.gov" + }, + "prod-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "fsx-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "fsx-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1" : { } + } + }, + "glacier" : { + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "glacier-fips.us-iso-east-1.c2s.ic.gov" + }, + "fips-us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "glacier-fips.us-iso-west-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "protocols" : [ "http", "https" ], + "variants" : [ { + "hostname" : "glacier-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1" : { + "variants" : [ { + "hostname" : "glacier-fips.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "glue" : { + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "guardduty" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "us-iso-east-1" : { } + }, + "isRegionalized" : true + }, + "health" : { + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "iam" : { + "endpoints" : { + "aws-iso-global" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "hostname" : "iam.us-iso-east-1.c2s.ic.gov" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-global" + }, + "kinesis" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "kinesisanalytics" : { + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "kinesisvideo" : { + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "kms" : { + "endpoints" : { + "ProdFips" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.us-iso-east-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "kms-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-east-1-fips" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.us-iso-east-1.c2s.ic.gov" + }, + "us-iso-west-1" : { + "variants" : [ { + "hostname" : "kms-fips.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1-fips" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.us-iso-west-1.c2s.ic.gov" + } + } + }, + "lakeformation" : { + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "lambda" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "license-manager" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "logs" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "medialive" : { + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "medialive-fips.us-iso-east-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "medialive-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "mediapackage" : { + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "metrics.sagemaker" : { + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "monitoring" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "network-firewall" : { + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "oam" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "organizations" : { + "endpoints" : { + "aws-iso-global" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "hostname" : "organizations.us-iso-east-1.c2s.ic.gov" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-global" + }, + "outposts" : { + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "pi" : { + "endpoints" : { + "us-iso-east-1" : { + "protocols" : [ "https" ] + }, + "us-iso-west-1" : { + "protocols" : [ "https" ] + } + } + }, + "ram" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "rbin" : { + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "rbin-fips.us-iso-east-1.c2s.ic.gov" + }, + "fips-us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "rbin-fips.us-iso-west-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "rbin-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1" : { + "variants" : [ { + "hostname" : "rbin-fips.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "rds" : { + "endpoints" : { + "rds.us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "rds.us-iso-east-1.c2s.ic.gov" + }, + "rds.us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "rds.us-iso-west-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "rds.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-east-1-fips" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "rds.us-iso-east-1.c2s.ic.gov" + }, + "us-iso-west-1" : { + "variants" : [ { + "hostname" : "rds.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1-fips" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "rds.us-iso-west-1.c2s.ic.gov" + } + } + }, + "redshift" : { + "endpoints" : { + "us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "hostname" : "redshift.us-iso-east-1.c2s.ic.gov" + }, + "us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "hostname" : "redshift.us-iso-west-1.c2s.ic.gov" + } + } + }, + "resource-groups" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "route53" : { + "endpoints" : { + "aws-iso-global" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "hostname" : "route53.c2s.ic.gov" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-global" + }, + "route53resolver" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "runtime.sagemaker" : { + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "s3" : { + "defaults" : { + "signatureVersions" : [ "s3v4" ] + }, + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "s3-fips.us-iso-east-1.c2s.ic.gov" + }, + "fips-us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "s3-fips.us-iso-west-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "protocols" : [ "http", "https" ], + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-fips.dualstack.us-iso-east-1.c2s.ic.gov", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1" : { + "variants" : [ { + "hostname" : "s3-fips.dualstack.us-iso-west-1.c2s.ic.gov", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-fips.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "s3-control" : { + "defaults" : { + "protocols" : [ "https" ], + "signatureVersions" : [ "s3v4" ] + }, + "endpoints" : { + "us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "hostname" : "s3-control.us-iso-east-1.c2s.ic.gov", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control-fips.dualstack.us-iso-east-1.c2s.ic.gov", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-control-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + }, { + "hostname" : "s3-control.dualstack.us-iso-east-1.c2s.ic.gov", + "tags" : [ "dualstack" ] + } ] + }, + "us-iso-east-1-fips" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "s3-control-fips.us-iso-east-1.c2s.ic.gov", + "signatureVersions" : [ "s3v4" ] + }, + "us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "hostname" : "s3-control.us-iso-west-1.c2s.ic.gov", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control-fips.dualstack.us-iso-west-1.c2s.ic.gov", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-control-fips.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + }, { + "hostname" : "s3-control.dualstack.us-iso-west-1.c2s.ic.gov", + "tags" : [ "dualstack" ] + } ] + }, + "us-iso-west-1-fips" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "s3-control-fips.us-iso-west-1.c2s.ic.gov", + "signatureVersions" : [ "s3v4" ] + } + } + }, + "s3-outposts" : { + "endpoints" : { + "fips-us-iso-east-1" : { + "deprecated" : true + }, + "us-iso-east-1" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + } + } + }, + "scheduler" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "secretsmanager" : { + "endpoints" : { + "us-iso-east-1" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + }, + "us-iso-east-1-fips" : { + "deprecated" : true + }, + "us-iso-west-1" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1-fips" : { + "deprecated" : true + } + } + }, + "securityhub" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "servicediscovery" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "servicequotas" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "snowball" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "sns" : { + "endpoints" : { + "us-iso-east-1" : { + "protocols" : [ "http", "https" ] + }, + "us-iso-west-1" : { } + } + }, + "sqs" : { + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "sqs.us-iso-east-1.c2s.ic.gov" + }, + "fips-us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "sqs.us-iso-west-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "protocols" : [ "http", "https" ], + "variants" : [ { + "hostname" : "sqs.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1" : { + "variants" : [ { + "hostname" : "sqs.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "ssm" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "states" : { + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "states-fips.us-iso-east-1.c2s.ic.gov" + }, + "fips-us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "states-fips.us-iso-west-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "states-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1" : { + "variants" : [ { + "hostname" : "states-fips.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "storagegateway" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "streams.dynamodb" : { + "defaults" : { + "credentialScope" : { + "service" : "dynamodb" + } + }, + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "sts" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "support" : { + "endpoints" : { + "aws-iso-global" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "hostname" : "support.us-iso-east-1.c2s.ic.gov" + } + }, + "partitionEndpoint" : "aws-iso-global" + }, + "swf" : { + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "swf-fips.us-iso-east-1.c2s.ic.gov" + }, + "fips-us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "swf-fips.us-iso-west-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "swf-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1" : { + "variants" : [ { + "hostname" : "swf-fips.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "synthetics" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "tagging" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + }, + "textract" : { + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "transcribe" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "fips.transcribe.us-iso-east-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "fips.transcribe.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "transcribestreaming" : { + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "translate" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "translate-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-east-1-fips" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "translate-fips.us-iso-east-1.c2s.ic.gov" + } + } + }, + "wafv2" : { + "endpoints" : { + "us-iso-east-1" : { } + } + }, + "workspaces" : { + "endpoints" : { + "fips-us-iso-east-1" : { + "credentialScope" : { + "region" : "us-iso-east-1" + }, + "deprecated" : true, + "hostname" : "workspaces-fips.us-iso-east-1.c2s.ic.gov" + }, + "fips-us-iso-west-1" : { + "credentialScope" : { + "region" : "us-iso-west-1" + }, + "deprecated" : true, + "hostname" : "workspaces-fips.us-iso-west-1.c2s.ic.gov" + }, + "us-iso-east-1" : { + "variants" : [ { + "hostname" : "workspaces-fips.us-iso-east-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-iso-west-1" : { + "variants" : [ { + "hostname" : "workspaces-fips.us-iso-west-1.c2s.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "xray" : { + "endpoints" : { + "us-iso-east-1" : { }, + "us-iso-west-1" : { } + } + } + } + }, { + "defaults" : { + "hostname" : "{service}.{region}.{dnsSuffix}", + "protocols" : [ "https" ], + "signatureVersions" : [ "v4" ], + "variants" : [ { + "dnsSuffix" : "sc2s.sgov.gov", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "dnsSuffix" : "sc2s.sgov.gov", + "partition" : "aws-iso-b", + "partitionName" : "AWS ISOB (US)", + "regionRegex" : "^us\\-isob\\-\\w+\\-\\d+$", + "regions" : { + "us-isob-east-1" : { + "description" : "US ISOB East (Ohio)" + }, + "us-isob-west-1" : { + "description" : "US ISOB West" + } + }, + "services" : { + "agreement-marketplace" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "api.ecr" : { + "endpoints" : { + "us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "hostname" : "api.ecr.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-west-1" : { } + } + }, + "api.pricing" : { + "defaults" : { + "credentialScope" : { + "service" : "pricing" + } + }, + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "api.sagemaker" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "apigateway" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "appconfig" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "appconfigdata" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "application-autoscaling" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "arc-zonal-shift" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "athena" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "autoscaling" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "backup" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "batch" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "bedrock" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "budgets" : { + "endpoints" : { + "aws-iso-b-global" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "hostname" : "budgets.global.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "hostname" : "budgets.global.sc2s.sgov.gov" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-b-global" + }, + "ce" : { + "endpoints" : { + "aws-iso-b-global" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "hostname" : "ce.us-isob-east-1.sc2s.sgov.gov" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-b-global" + }, + "cloudcontrolapi" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "cloudformation" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "cloudtrail" : { + "endpoints" : { + "fips-us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "cloudtrail-fips.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "cloudtrail-fips.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isob-west-1" : { } + } + }, + "codebuild" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "codedeploy" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "config" : { + "endpoints" : { + "fips-us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "config-fips.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "config-fips.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isob-west-1" : { } + } + }, + "datasync" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "directconnect" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "dlm" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "dms" : { + "defaults" : { + "variants" : [ { + "hostname" : "dms.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "endpoints" : { + "dms" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "dms.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + }, + "dms-fips" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "dms.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "dms.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isob-east-1-fips" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "dms.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-west-1" : { } + } + }, + "ds" : { + "endpoints" : { + "fips-us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "ds-fips.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "ds-fips.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "dynamodb" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "ebs" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "ec2" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "ecs" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "eks" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "elasticache" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "elasticfilesystem" : { + "endpoints" : { + "fips-us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "elasticloadbalancing" : { + "endpoints" : { + "us-isob-east-1" : { + "protocols" : [ "https" ] + }, + "us-isob-west-1" : { } + } + }, + "elasticmapreduce" : { + "endpoints" : { + "fips-us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "elasticmapreduce.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "elasticmapreduce.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isob-west-1" : { } + } + }, + "es" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "events" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "firehose" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "fsx" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "glacier" : { + "endpoints" : { + "fips-us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "glacier-fips.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "glacier-fips.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "glue" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "guardduty" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "health" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "iam" : { + "endpoints" : { + "aws-iso-b-global" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "hostname" : "iam.us-isob-east-1.sc2s.sgov.gov" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-b-global" + }, + "kinesis" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "kinesisanalytics" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "kms" : { + "endpoints" : { + "ProdFips" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "kms-fips.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isob-east-1-fips" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-west-1" : { } + } + }, + "lakeformation" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "lambda" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "license-manager" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "logs" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "medialive" : { + "endpoints" : { + "fips-us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "medialive-fips.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "medialive-fips.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "mediapackage" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "metering.marketplace" : { + "defaults" : { + "credentialScope" : { + "service" : "aws-marketplace" + } + }, + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "metrics.sagemaker" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "monitoring" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "network-firewall" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "oam" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "organizations" : { + "endpoints" : { + "aws-iso-b-global" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "hostname" : "organizations.us-isob-east-1.sc2s.sgov.gov" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-b-global" + }, + "outposts" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "pi" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "ram" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "rbin" : { + "endpoints" : { + "fips-us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "rbin-fips.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "rbin-fips.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isob-west-1" : { } + } + }, + "rds" : { + "endpoints" : { + "rds.us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "rds.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "rds.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isob-east-1-fips" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "rds.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-west-1" : { } + } + }, + "redshift" : { + "endpoints" : { + "us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "hostname" : "redshift.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-west-1" : { } + } + }, + "resource-groups" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "route53" : { + "endpoints" : { + "aws-iso-b-global" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "hostname" : "route53.sc2s.sgov.gov" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-b-global" + }, + "route53resolver" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "runtime.sagemaker" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "s3" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "signatureVersions" : [ "s3v4" ] + }, + "endpoints" : { + "fips-us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "s3-fips.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "s3-fips.dualstack.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-fips.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isob-west-1" : { } + } + }, + "s3-control" : { + "defaults" : { + "protocols" : [ "https" ], + "signatureVersions" : [ "s3v4" ] + }, + "endpoints" : { + "us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "hostname" : "s3-control.us-isob-east-1.sc2s.sgov.gov", + "signatureVersions" : [ "s3v4" ], + "variants" : [ { + "hostname" : "s3-control-fips.dualstack.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "dualstack", "fips" ] + }, { + "hostname" : "s3-control-fips.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + }, { + "hostname" : "s3-control.dualstack.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "dualstack" ] + } ] + }, + "us-isob-east-1-fips" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "s3-control-fips.us-isob-east-1.sc2s.sgov.gov", + "signatureVersions" : [ "s3v4" ] + } + } + }, + "s3-outposts" : { + "endpoints" : { + "fips-us-isob-east-1" : { + "deprecated" : true + }, + "us-isob-east-1" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + } + } + }, + "scheduler" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "secretsmanager" : { + "endpoints" : { + "us-isob-east-1" : { + "variants" : [ { + "tags" : [ "fips" ] + } ] + }, + "us-isob-east-1-fips" : { + "deprecated" : true + }, + "us-isob-west-1" : { } + } + }, + "securityhub" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "servicediscovery" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "servicequotas" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "snowball" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "sns" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "sqs" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "sslCommonName" : "{region}.queue.{dnsSuffix}" + }, + "endpoints" : { + "fips-us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "sqs.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "sqs.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isob-west-1" : { } + } + }, + "ssm" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "states" : { + "endpoints" : { + "fips-us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "states-fips.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "states-fips.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isob-west-1" : { } + } + }, + "storagegateway" : { + "endpoints" : { + "fips" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "storagegateway-fips.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "storagegateway-fips.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isob-east-1-fips" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "storagegateway-fips.us-isob-east-1.sc2s.sgov.gov" + } + } + }, + "streams.dynamodb" : { + "defaults" : { + "credentialScope" : { + "service" : "dynamodb" + }, + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "sts" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "support" : { + "endpoints" : { + "aws-iso-b-global" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "hostname" : "support.us-isob-east-1.sc2s.sgov.gov" + } + }, + "partitionEndpoint" : "aws-iso-b-global" + }, + "swf" : { + "endpoints" : { + "fips-us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "swf-fips.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "swf-fips.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isob-west-1" : { } + } + }, + "synthetics" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "tagging" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + }, + "wafv2" : { + "endpoints" : { + "us-isob-east-1" : { } + } + }, + "workspaces" : { + "endpoints" : { + "fips-us-isob-east-1" : { + "credentialScope" : { + "region" : "us-isob-east-1" + }, + "deprecated" : true, + "hostname" : "workspaces-fips.us-isob-east-1.sc2s.sgov.gov" + }, + "us-isob-east-1" : { + "variants" : [ { + "hostname" : "workspaces-fips.us-isob-east-1.sc2s.sgov.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "xray" : { + "endpoints" : { + "us-isob-east-1" : { }, + "us-isob-west-1" : { } + } + } + } + }, { + "defaults" : { + "hostname" : "{service}.{region}.{dnsSuffix}", + "protocols" : [ "https" ], + "signatureVersions" : [ "v4" ], + "variants" : [ { + "dnsSuffix" : "cloud.adc-e.uk", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "dnsSuffix" : "cloud.adc-e.uk", + "partition" : "aws-iso-e", + "partitionName" : "AWS ISOE (Europe)", + "regionRegex" : "^eu\\-isoe\\-\\w+\\-\\d+$", + "regions" : { + "eu-isoe-west-1" : { + "description" : "EU ISOE West" + } + }, + "services" : { + "access-analyzer" : { + "endpoints" : { + "eu-isoe-west-1" : { + "variants" : [ { + "hostname" : "access-analyzer.eu-isoe-west-1.api.cloud-aws.adc-e.uk", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "acm" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "acm-pca" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "api.ecr" : { + "endpoints" : { + "eu-isoe-west-1" : { + "credentialScope" : { + "region" : "eu-isoe-west-1" + }, + "hostname" : "api.ecr.eu-isoe-west-1.cloud.adc-e.uk" + } + } + }, + "api.pricing" : { + "defaults" : { + "credentialScope" : { + "service" : "pricing" + } + }, + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "apigateway" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "appconfig" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "appconfigdata" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "application-autoscaling" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "arc-zonal-shift" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "athena" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "autoscaling" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "batch" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "budgets" : { + "endpoints" : { + "aws-iso-e-global" : { + "credentialScope" : { + "region" : "eu-isoe-west-1" + }, + "hostname" : "budgets.global.cloud.adc-e.uk" + }, + "eu-isoe-west-1" : { + "credentialScope" : { + "region" : "eu-isoe-west-1" + }, + "hostname" : "budgets.global.cloud.adc-e.uk" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-e-global" + }, + "cloudcontrolapi" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "cloudformation" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "cloudtrail" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "cloudtrail-data" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "codedeploy" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "compute-optimizer" : { + "endpoints" : { + "eu-isoe-west-1" : { + "credentialScope" : { + "region" : "eu-isoe-west-1" + }, + "hostname" : "compute-optimizer.eu-isoe-west-1.cloud.adc-e.uk" + } + } + }, + "config" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "cost-optimization-hub" : { + "endpoints" : { + "eu-isoe-west-1" : { + "credentialScope" : { + "region" : "eu-isoe-west-1" + }, + "hostname" : "cost-optimization-hub.eu-isoe-west-1.cloud.adc-e.uk" + } + } + }, + "directconnect" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "dlm" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "dms" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "ds" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "dynamodb" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "ebs" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "ec2" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "ecs" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "eks" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "elasticache" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "elasticfilesystem" : { + "endpoints" : { + "eu-isoe-west-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.eu-isoe-west-1.cloud.adc-e.uk", + "tags" : [ "fips" ] + } ] + }, + "fips-eu-isoe-west-1" : { + "credentialScope" : { + "region" : "eu-isoe-west-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.eu-isoe-west-1.cloud.adc-e.uk" + } + } + }, + "elasticloadbalancing" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "elasticmapreduce" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "emr-serverless" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "es" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "events" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "firehose" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "glue" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "kinesis" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "kms" : { + "endpoints" : { + "ProdFips" : { + "credentialScope" : { + "region" : "eu-isoe-west-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.eu-isoe-west-1.cloud.adc-e.uk" + }, + "eu-isoe-west-1" : { + "variants" : [ { + "hostname" : "kms-fips.eu-isoe-west-1.cloud.adc-e.uk", + "tags" : [ "fips" ] + } ] + }, + "eu-isoe-west-1-fips" : { + "credentialScope" : { + "region" : "eu-isoe-west-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.eu-isoe-west-1.cloud.adc-e.uk" + } + } + }, + "lakeformation" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "lambda" : { + "endpoints" : { + "eu-isoe-west-1" : { + "variants" : [ { + "hostname" : "lambda.eu-isoe-west-1.api.cloud-aws.adc-e.uk", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "license-manager" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "logs" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "monitoring" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "oam" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "organizations" : { + "endpoints" : { + "aws-iso-e-global" : { + "credentialScope" : { + "region" : "eu-isoe-west-1" + }, + "hostname" : "organizations.eu-isoe-west-1.cloud.adc-e.uk" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-e-global" + }, + "pi" : { + "endpoints" : { + "eu-isoe-west-1" : { + "protocols" : [ "https" ] + } + } + }, + "pipes" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "ram" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "rbin" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "rds" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "redshift" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "redshift-serverless" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "resource-groups" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "route53" : { + "endpoints" : { + "aws-iso-e-global" : { + "credentialScope" : { + "region" : "eu-isoe-west-1" + }, + "hostname" : "route53.cloud.adc-e.uk" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-e-global" + }, + "route53profiles" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "route53resolver" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "s3" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "signatureVersions" : [ "s3v4" ] + }, + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "savingsplans" : { + "endpoints" : { + "aws-iso-e-global" : { + "credentialScope" : { + "region" : "eu-isoe-west-1" + }, + "hostname" : "savingsplans.cloud.adc-e.uk" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-e-global" + }, + "scheduler" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "schemas" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "secretsmanager" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "servicecatalog" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "servicediscovery" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "servicequotas" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "sns" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "sqs" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "sslCommonName" : "{region}.queue.{dnsSuffix}" + }, + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "ssm" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "states" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "streams.dynamodb" : { + "defaults" : { + "credentialScope" : { + "service" : "dynamodb" + }, + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "sts" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "swf" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "synthetics" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "tagging" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "trustedadvisor" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + }, + "xray" : { + "endpoints" : { + "eu-isoe-west-1" : { } + } + } + } + }, { + "defaults" : { + "hostname" : "{service}.{region}.{dnsSuffix}", + "protocols" : [ "https" ], + "signatureVersions" : [ "v4" ], + "variants" : [ { + "dnsSuffix" : "csp.hci.ic.gov", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + } ] + }, + "dnsSuffix" : "csp.hci.ic.gov", + "partition" : "aws-iso-f", + "partitionName" : "AWS ISOF", + "regionRegex" : "^us\\-isof\\-\\w+\\-\\d+$", + "regions" : { + "us-isof-east-1" : { + "description" : "US ISOF EAST" + }, + "us-isof-south-1" : { + "description" : "US ISOF SOUTH" + } + }, + "services" : { + "access-analyzer" : { + "endpoints" : { + "us-isof-east-1" : { + "variants" : [ { + "hostname" : "access-analyzer.us-isof-east-1.api.aws.hci.ic.gov", + "tags" : [ "dualstack" ] + } ] + }, + "us-isof-south-1" : { + "variants" : [ { + "hostname" : "access-analyzer.us-isof-south-1.api.aws.hci.ic.gov", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "acm" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "acm-pca" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "api.ecr" : { + "endpoints" : { + "us-isof-east-1" : { + "credentialScope" : { + "region" : "us-isof-east-1" + }, + "hostname" : "api.ecr.us-isof-east-1.csp.hci.ic.gov" + }, + "us-isof-south-1" : { + "credentialScope" : { + "region" : "us-isof-south-1" + }, + "hostname" : "api.ecr.us-isof-south-1.csp.hci.ic.gov" + } + } + }, + "api.pricing" : { + "defaults" : { + "credentialScope" : { + "service" : "pricing" + } + }, + "endpoints" : { + "us-isof-south-1" : { } + } + }, + "api.sagemaker" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "appconfig" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "appconfigdata" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "application-autoscaling" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "arc-zonal-shift" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "athena" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "autoscaling" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "backup" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "batch" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "budgets" : { + "endpoints" : { + "aws-iso-f-global" : { + "credentialScope" : { + "region" : "us-isof-south-1" + }, + "hostname" : "budgets.global.csp.hci.ic.gov" + }, + "us-isof-south-1" : { + "credentialScope" : { + "region" : "us-isof-south-1" + }, + "hostname" : "budgets.global.csp.hci.ic.gov" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-f-global" + }, + "ce" : { + "endpoints" : { + "aws-iso-f-global" : { + "credentialScope" : { + "region" : "us-isof-south-1" + }, + "hostname" : "ce.us-isof-south-1.csp.hci.ic.gov" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-f-global" + }, + "cloudcontrolapi" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "cloudformation" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "cloudtrail" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "cloudtrail-data" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "codebuild" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "codedeploy" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "codepipeline" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "comprehend" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "compute-optimizer" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { + "credentialScope" : { + "region" : "us-isof-south-1" + }, + "hostname" : "compute-optimizer.us-isof-south-1.csp.hci.ic.gov" + } + } + }, + "config" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "cost-optimization-hub" : { + "endpoints" : { + "us-isof-south-1" : { + "credentialScope" : { + "region" : "us-isof-south-1" + }, + "hostname" : "cost-optimization-hub.us-isof-south-1.csp.hci.ic.gov" + } + } + }, + "directconnect" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "dlm" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "dms" : { + "endpoints" : { + "dms" : { + "credentialScope" : { + "region" : "us-isof-east-1" + }, + "deprecated" : true, + "variants" : [ { + "hostname" : "dms.us-isof-east-1.csp.hci.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "dms-fips" : { + "credentialScope" : { + "region" : "us-isof-east-1" + }, + "deprecated" : true, + "hostname" : "dms.us-isof-east-1.csp.hci.ic.gov" + }, + "us-isof-east-1" : { + "variants" : [ { + "hostname" : "dms.us-isof-east-1.csp.hci.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isof-east-1-fips" : { + "credentialScope" : { + "region" : "us-isof-east-1" + }, + "deprecated" : true, + "hostname" : "dms.us-isof-east-1.csp.hci.ic.gov" + }, + "us-isof-south-1" : { + "variants" : [ { + "hostname" : "dms.us-isof-south-1.csp.hci.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isof-south-1-fips" : { + "credentialScope" : { + "region" : "us-isof-south-1" + }, + "deprecated" : true, + "hostname" : "dms.us-isof-south-1.csp.hci.ic.gov" + } + } + }, + "ds" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "dynamodb" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "ebs" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "ec2" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "ecs" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "eks" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "elasticache" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "elasticfilesystem" : { + "endpoints" : { + "fips-us-isof-east-1" : { + "credentialScope" : { + "region" : "us-isof-east-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.us-isof-east-1.csp.hci.ic.gov" + }, + "fips-us-isof-south-1" : { + "credentialScope" : { + "region" : "us-isof-south-1" + }, + "deprecated" : true, + "hostname" : "elasticfilesystem-fips.us-isof-south-1.csp.hci.ic.gov" + }, + "us-isof-east-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.us-isof-east-1.csp.hci.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isof-south-1" : { + "variants" : [ { + "hostname" : "elasticfilesystem-fips.us-isof-south-1.csp.hci.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "elasticloadbalancing" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "elasticmapreduce" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "es" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "events" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "firehose" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "fsx" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "glue" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "guardduty" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + }, + "isRegionalized" : true + }, + "iam" : { + "endpoints" : { + "aws-iso-f-global" : { + "credentialScope" : { + "region" : "us-isof-south-1" + }, + "hostname" : "iam.us-isof-south-1.csp.hci.ic.gov" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-f-global" + }, + "identitystore" : { + "endpoints" : { + "us-isof-east-1" : { } + } + }, + "kinesis" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "kms" : { + "endpoints" : { + "ProdFips" : { + "credentialScope" : { + "region" : "us-isof-east-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.us-isof-east-1.csp.hci.ic.gov" + }, + "us-isof-east-1" : { + "variants" : [ { + "hostname" : "kms-fips.us-isof-east-1.csp.hci.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isof-east-1-fips" : { + "credentialScope" : { + "region" : "us-isof-east-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.us-isof-east-1.csp.hci.ic.gov" + }, + "us-isof-south-1" : { + "variants" : [ { + "hostname" : "kms-fips.us-isof-south-1.csp.hci.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isof-south-1-fips" : { + "credentialScope" : { + "region" : "us-isof-south-1" + }, + "deprecated" : true, + "hostname" : "kms-fips.us-isof-south-1.csp.hci.ic.gov" + } + } + }, + "lakeformation" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "lambda" : { + "endpoints" : { + "us-isof-east-1" : { + "variants" : [ { + "hostname" : "lambda.us-isof-east-1.api.aws.hci.ic.gov", + "tags" : [ "dualstack" ] + } ] + }, + "us-isof-south-1" : { + "variants" : [ { + "hostname" : "lambda.us-isof-south-1.api.aws.hci.ic.gov", + "tags" : [ "dualstack" ] + } ] + } + } + }, + "license-manager" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "logs" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "metrics.sagemaker" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "monitoring" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "oam" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "organizations" : { + "endpoints" : { + "aws-iso-f-global" : { + "credentialScope" : { + "region" : "us-isof-south-1" + }, + "hostname" : "organizations.us-isof-south-1.csp.hci.ic.gov" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-f-global" + }, + "pi" : { + "endpoints" : { + "us-isof-east-1" : { + "protocols" : [ "https" ] + }, + "us-isof-south-1" : { + "protocols" : [ "https" ] + } + } + }, + "pipes" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "quicksight" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "ram" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "rbin" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "rds" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "redshift" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "redshift-serverless" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "rekognition" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "resource-groups" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "rolesanywhere" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "route53" : { + "endpoints" : { + "aws-iso-f-global" : { + "credentialScope" : { + "region" : "us-isof-south-1" + }, + "hostname" : "route53.csp.hci.ic.gov" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-f-global" + }, + "route53profiles" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "route53resolver" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "runtime.sagemaker" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "s3" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "signatureVersions" : [ "s3v4" ] + }, + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "savingsplans" : { + "endpoints" : { + "aws-iso-f-global" : { + "credentialScope" : { + "region" : "us-isof-south-1" + }, + "hostname" : "savingsplans.csp.hci.ic.gov" + } + }, + "isRegionalized" : false, + "partitionEndpoint" : "aws-iso-f-global" + }, + "scheduler" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "schemas" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "secretsmanager" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "servicediscovery" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "servicequotas" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "sns" : { + "defaults" : { + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "sqs" : { + "defaults" : { + "protocols" : [ "http", "https" ], + "sslCommonName" : "{region}.queue.{dnsSuffix}" + }, + "endpoints" : { + "fips-us-isof-east-1" : { + "credentialScope" : { + "region" : "us-isof-east-1" + }, + "deprecated" : true, + "hostname" : "sqs.us-isof-east-1.csp.hci.ic.gov" + }, + "fips-us-isof-south-1" : { + "credentialScope" : { + "region" : "us-isof-south-1" + }, + "deprecated" : true, + "hostname" : "sqs.us-isof-south-1.csp.hci.ic.gov" + }, + "us-isof-east-1" : { + "variants" : [ { + "hostname" : "sqs.us-isof-east-1.csp.hci.ic.gov", + "tags" : [ "fips" ] + } ] + }, + "us-isof-south-1" : { + "variants" : [ { + "hostname" : "sqs.us-isof-south-1.csp.hci.ic.gov", + "tags" : [ "fips" ] + } ] + } + } + }, + "ssm" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "states" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "streams.dynamodb" : { + "defaults" : { + "credentialScope" : { + "service" : "dynamodb" + }, + "protocols" : [ "http", "https" ] + }, + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "sts" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "swf" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "synthetics" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "tagging" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "textract" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "transcribe" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "transcribestreaming" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "translate" : { + "defaults" : { + "protocols" : [ "https" ] + }, + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + }, + "trustedadvisor" : { + "endpoints" : { + "us-isof-south-1" : { } + } + }, + "xray" : { + "endpoints" : { + "us-isof-east-1" : { }, + "us-isof-south-1" : { } + } + } + } + }, { + "defaults" : { + "hostname" : "{service}.{region}.{dnsSuffix}", + "protocols" : [ "https" ], + "signatureVersions" : [ "v4" ], + "variants" : [ { + "dnsSuffix" : "amazonaws.eu", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "fips" ] + }, { + "dnsSuffix" : "api.amazonwebservices.eu", + "hostname" : "{service}-fips.{region}.{dnsSuffix}", + "tags" : [ "dualstack", "fips" ] + }, { + "dnsSuffix" : "api.amazonwebservices.eu", + "hostname" : "{service}.{region}.{dnsSuffix}", + "tags" : [ "dualstack" ] + } ] + }, + "dnsSuffix" : "amazonaws.eu", + "partition" : "aws-eusc", + "partitionName" : "AWS EUSC", + "regionRegex" : "^eusc\\-(de)\\-\\w+\\-\\d+$", + "regions" : { + "eusc-de-east-1" : { + "description" : "AWS European Sovereign Cloud (Germany)" + } + }, + "services" : { + "access-analyzer" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "acm" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "acm-pca" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "agreement-marketplace" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "api.ecr" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "api.pricing" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "api.sagemaker" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "appconfig" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "appconfigdata" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "application-autoscaling" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "arc-zonal-shift" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "athena" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "autoscaling" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "backup" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "batch" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "bedrock" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "cloudcontrolapi" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "cloudformation" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "cloudtrail" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "codedeploy" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "compute-optimizer" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "config" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "cost-optimization-hub" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "datasync" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "datazone" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "directconnect" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "dlm" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "dms" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "ds" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "dynamodb" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "ebs" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "ec2" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "ecs" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "eks" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "eks-auth" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "elasticache" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "elasticfilesystem" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "elasticloadbalancing" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "elasticmapreduce" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "email" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "entitlement.marketplace" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "es" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "events" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "firehose" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "fsx" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "gameliftstreams" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "glue" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "guardduty" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "health" : { + "endpoints" : { + "eusc-de-east-1" : { + "deprecated" : true + } + } + }, + "identitystore" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "internetmonitor" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "kafka" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "kendra-ranking" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "kinesis" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "kinesisanalytics" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "kms" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "lakeformation" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "lambda" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "license-manager" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "logs" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "metering.marketplace" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "metrics.sagemaker" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "monitoring" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "notifications" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "oam" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "pi" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "qbusiness" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "ram" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "rbin" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "rds" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "redshift" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "resource-groups" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "rolesanywhere" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "route53resolver" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "s3" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "s3-control" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "scheduler" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "secretsmanager" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "securityhub" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "servicediscovery" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "servicequotas" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "signer" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "sms-voice" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "sns" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "sqs" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "ssm" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "states" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "storagegateway" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "streams.dynamodb" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "sts" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "swf" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "synthetics" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "tagging" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "transfer" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "trustedadvisor" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "wafv2" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + }, + "xray" : { + "endpoints" : { + "eusc-de-east-1" : { } + } + } + } + } ], + "version" : 3 +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/entityresolution/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/entityresolution/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..b34d38295b2ca69d2b386892f64c0afbd800b9d7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/entityresolution/2018-05-10/paginators-1.json @@ -0,0 +1,46 @@ +{ + "pagination": { + "ListMatchingJobs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "jobs" + }, + "ListMatchingWorkflows": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "workflowSummaries" + }, + "ListSchemaMappings": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "schemaList" + }, + "ListIdMappingJobs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "jobs" + }, + "ListIdMappingWorkflows": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "workflowSummaries" + }, + "ListProviderServices": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "providerServiceSummaries" + }, + "ListIdNamespaces": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "idNamespaceSummaries" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/events/2015-10-07/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/events/2015-10-07/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/events/2015-10-07/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/events/2015-10-07/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/events/2015-10-07/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..501a3229a9f6e51841055c1e251685c072b63c31 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/events/2015-10-07/paginators-1.json @@ -0,0 +1,22 @@ +{ + "pagination": { + "ListRuleNamesByTarget": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "Limit", + "result_key": "RuleNames" + }, + "ListRules": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "Limit", + "result_key": "Rules" + }, + "ListTargetsByRule": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "Limit", + "result_key": "Targets" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/evidently/2021-02-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/evidently/2021-02-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/evidently/2021-02-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/evidently/2021-02-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/evidently/2021-02-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..c72d3cbae36f5503dfc95584ac0ea59360b4ab8e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/evidently/2021-02-01/paginators-1.json @@ -0,0 +1,40 @@ +{ + "pagination": { + "ListExperiments": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "experiments" + }, + "ListFeatures": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "features" + }, + "ListLaunches": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "launches" + }, + "ListProjects": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "projects" + }, + "ListSegmentReferences": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "referencedBy" + }, + "ListSegments": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "segments" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/evs/2023-07-27/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/evs/2023-07-27/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..c5e0850aedbf44abf494dd7afbf5d608c18fbf56 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/evs/2023-07-27/paginators-1.json @@ -0,0 +1,22 @@ +{ + "pagination": { + "ListEnvironmentHosts": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "environmentHosts" + }, + "ListEnvironmentVlans": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "environmentVlans" + }, + "ListEnvironments": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "environmentSummaries" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/evs/2023-07-27/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/evs/2023-07-27/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/evs/2023-07-27/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/finspace/2021-03-12/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/finspace/2021-03-12/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/finspace/2021-03-12/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/finspace/2021-03-12/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/finspace/2021-03-12/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..741ca7985eacfa2964a42b8f75423c4416a66773 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/finspace/2021-03-12/paginators-1.json @@ -0,0 +1,10 @@ +{ + "pagination": { + "ListKxEnvironments": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "environments" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/firehose/2015-08-04/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/firehose/2015-08-04/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/firehose/2015-08-04/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/firehose/2015-08-04/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/firehose/2015-08-04/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/firehose/2015-08-04/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/fis/2020-12-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/fis/2020-12-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/fis/2020-12-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/fis/2020-12-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/fis/2020-12-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..740e56e299a47a2ccb8539babe6d65d031c54835 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/fis/2020-12-01/paginators-1.json @@ -0,0 +1,40 @@ +{ + "pagination": { + "ListActions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "actions" + }, + "ListExperimentResolvedTargets": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "resolvedTargets" + }, + "ListExperimentTemplates": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "experimentTemplates" + }, + "ListExperiments": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "experiments" + }, + "ListTargetAccountConfigurations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "targetAccountConfigurations" + }, + "ListTargetResourceTypes": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "targetResourceTypes" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/fms/2018-01-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/fms/2018-01-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/fms/2018-01-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/fms/2018-01-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/fms/2018-01-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..730571d14558a5cd1322a5029a412500188c9d05 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/fms/2018-01-01/paginators-1.json @@ -0,0 +1,52 @@ +{ + "pagination": { + "ListComplianceStatus": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "PolicyComplianceStatusList" + }, + "ListMemberAccounts": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "MemberAccounts" + }, + "ListPolicies": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "PolicyList" + }, + "ListAppsLists": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "AppsLists" + }, + "ListProtocolsLists": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ProtocolsLists" + }, + "ListThirdPartyFirewallFirewallPolicies": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ThirdPartyFirewallFirewallPolicies" + }, + "ListAdminAccountsForOrganization": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "AdminAccounts" + }, + "ListAdminsManagingAccount": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "AdminAccounts" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/forecast/2018-06-26/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/forecast/2018-06-26/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/forecast/2018-06-26/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/forecast/2018-06-26/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/forecast/2018-06-26/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..853dee41459fd276ebe629df193f6ceda8b76398 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/forecast/2018-06-26/paginators-1.json @@ -0,0 +1,88 @@ +{ + "pagination": { + "ListDatasetGroups": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "DatasetGroups" + }, + "ListDatasetImportJobs": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "DatasetImportJobs" + }, + "ListDatasets": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Datasets" + }, + "ListForecastExportJobs": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ForecastExportJobs" + }, + "ListForecasts": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Forecasts" + }, + "ListPredictors": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Predictors" + }, + "ListPredictorBacktestExportJobs": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "PredictorBacktestExportJobs" + }, + "ListExplainabilities": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Explainabilities" + }, + "ListExplainabilityExports": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ExplainabilityExports" + }, + "ListMonitorEvaluations": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "PredictorMonitorEvaluations" + }, + "ListMonitors": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Monitors" + }, + "ListWhatIfAnalyses": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "WhatIfAnalyses" + }, + "ListWhatIfForecastExports": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "WhatIfForecastExports" + }, + "ListWhatIfForecasts": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "WhatIfForecasts" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/frauddetector/2019-11-15/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/frauddetector/2019-11-15/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/frauddetector/2019-11-15/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/frauddetector/2019-11-15/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/frauddetector/2019-11-15/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/frauddetector/2019-11-15/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/gameliftstreams/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/gameliftstreams/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..a396ef461b74de7090fda188be07fcaeb9dd5428 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/gameliftstreams/2018-05-10/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "ListApplications": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListStreamGroups": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListStreamSessions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListStreamSessionsByAccount": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/gameliftstreams/2018-05-10/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/gameliftstreams/2018-05-10/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..2c064b00ac3d88cb8844a93f166089217d5698ee --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/gameliftstreams/2018-05-10/waiters-2.json @@ -0,0 +1,88 @@ +{ + "version" : 2, + "waiters" : { + "ApplicationDeleted" : { + "description" : "Waits until an application is deleted", + "delay" : 2, + "maxAttempts" : 60, + "operation" : "GetApplication", + "acceptors" : [ { + "matcher" : "error", + "state" : "success", + "expected" : "ResourceNotFoundException" + } ] + }, + "ApplicationReady" : { + "description" : "Waits until an application is ready", + "delay" : 2, + "maxAttempts" : 60, + "operation" : "GetApplication", + "acceptors" : [ { + "matcher" : "path", + "argument" : "Status", + "state" : "success", + "expected" : "READY" + }, { + "matcher" : "path", + "argument" : "Status", + "state" : "failure", + "expected" : "ERROR" + } ] + }, + "StreamGroupActive" : { + "description" : "Waits until a stream group is active", + "delay" : 30, + "maxAttempts" : 120, + "operation" : "GetStreamGroup", + "acceptors" : [ { + "matcher" : "path", + "argument" : "Status", + "state" : "success", + "expected" : "ACTIVE" + }, { + "matcher" : "path", + "argument" : "Status", + "state" : "failure", + "expected" : "ERROR" + }, { + "matcher" : "path", + "argument" : "Status", + "state" : "failure", + "expected" : "ACTIVE_WITH_ERRORS" + }, { + "matcher" : "path", + "argument" : "Status", + "state" : "failure", + "expected" : "DELETING" + } ] + }, + "StreamGroupDeleted" : { + "description" : "Waits until a stream group is deleted", + "delay" : 30, + "maxAttempts" : 60, + "operation" : "GetStreamGroup", + "acceptors" : [ { + "matcher" : "error", + "state" : "success", + "expected" : "ResourceNotFoundException" + } ] + }, + "StreamSessionActive" : { + "description" : "Waits until a stream session is active", + "delay" : 2, + "maxAttempts" : 60, + "operation" : "GetStreamSession", + "acceptors" : [ { + "matcher" : "path", + "argument" : "Status", + "state" : "success", + "expected" : "ACTIVE" + }, { + "matcher" : "path", + "argument" : "Status", + "state" : "failure", + "expected" : "ERROR" + } ] + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/glue/2017-03-31/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/glue/2017-03-31/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/glue/2017-03-31/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/glue/2017-03-31/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/glue/2017-03-31/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..54d4f8e8457b9ee7a24a42e5a8c3a6cb4084634c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/glue/2017-03-31/paginators-1.json @@ -0,0 +1,181 @@ +{ + "pagination": { + "GetJobs": { + "result_key": "Jobs", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "GetPartitions": { + "result_key": "Partitions", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "GetDatabases": { + "result_key": "DatabaseList", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "GetClassifiers": { + "result_key": "Classifiers", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "GetTableVersions": { + "result_key": "TableVersions", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "GetCrawlers": { + "result_key": "Crawlers", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "GetDevEndpoints": { + "result_key": "DevEndpoints", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "GetJobRuns": { + "result_key": "JobRuns", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "GetTriggers": { + "result_key": "Triggers", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "GetTables": { + "result_key": "TableList", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "GetUserDefinedFunctions": { + "result_key": "UserDefinedFunctions", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "GetCrawlerMetrics": { + "result_key": "CrawlerMetricsList", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "GetConnections": { + "result_key": "ConnectionList", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "GetSecurityConfigurations": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "SecurityConfigurations" + }, + "GetPartitionIndexes": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "PartitionIndexDescriptorList" + }, + "GetResourcePolicies": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "GetResourcePoliciesResponseList" + }, + "ListRegistries": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Registries" + }, + "ListSchemaVersions": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Schemas" + }, + "ListSchemas": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Schemas" + }, + "ListUsageProfiles": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Profiles" + }, + "GetWorkflowRuns": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Runs" + }, + "ListBlueprints": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Blueprints" + }, + "ListJobs": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "JobNames" + }, + "ListTriggers": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "TriggerNames" + }, + "ListWorkflows": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Workflows" + }, + "ListTableOptimizerRuns": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "TableOptimizerRuns" + }, + "DescribeEntity": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Fields" + }, + "ListConnectionTypes": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ConnectionTypes" + }, + "ListEntities": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Entities" + }, + "ListMaterializedViewRefreshTaskRuns": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "MaterializedViewRefreshTaskRuns" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/glue/2017-03-31/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/glue/2017-03-31/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..4d788b16110432cfbd948923e59e5c8caa7eb244 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/glue/2017-03-31/paginators-1.sdk-extras.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "merge": { + "pagination": { + "ListTableOptimizerRuns": { + "non_aggregate_keys": [ + "CatalogId", + "DatabaseName", + "TableName" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/grafana/2020-08-18/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/grafana/2020-08-18/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/grafana/2020-08-18/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/grafana/2020-08-18/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/grafana/2020-08-18/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..55d05f29964c3e752600cbd6ae35e92bb2b00a3c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/grafana/2020-08-18/paginators-1.json @@ -0,0 +1,34 @@ +{ + "pagination": { + "ListPermissions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "permissions" + }, + "ListWorkspaces": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "workspaces" + }, + "ListVersions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "grafanaVersions" + }, + "ListWorkspaceServiceAccountTokens": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "serviceAccountTokens" + }, + "ListWorkspaceServiceAccounts": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "serviceAccounts" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/grafana/2020-08-18/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/grafana/2020-08-18/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..421e2f65a8caae38a5e88df64cef558ac664ade7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/grafana/2020-08-18/paginators-1.sdk-extras.json @@ -0,0 +1,18 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "ListWorkspaceServiceAccounts": { + "non_aggregate_keys": [ + "workspaceId" + ] + }, + "ListWorkspaceServiceAccountTokens": { + "non_aggregate_keys": [ + "serviceAccountId", + "workspaceId" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/greengrassv2/2020-11-30/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/greengrassv2/2020-11-30/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/greengrassv2/2020-11-30/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/greengrassv2/2020-11-30/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/greengrassv2/2020-11-30/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..2e2af05dd9069eb7ef4f7fc616faa1b64d631b8b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/greengrassv2/2020-11-30/paginators-1.json @@ -0,0 +1,46 @@ +{ + "pagination": { + "ListComponentVersions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "componentVersions" + }, + "ListComponents": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "components" + }, + "ListCoreDevices": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "coreDevices" + }, + "ListDeployments": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "deployments" + }, + "ListEffectiveDeployments": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "effectiveDeployments" + }, + "ListInstalledComponents": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "installedComponents" + }, + "ListClientDevicesAssociatedWithCoreDevice": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "associatedClientDevices" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/healthlake/2017-07-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/healthlake/2017-07-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/healthlake/2017-07-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/healthlake/2017-07-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/healthlake/2017-07-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/healthlake/2017-07-01/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/healthlake/2017-07-01/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/healthlake/2017-07-01/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..ba6478fa841e6bf6f89fa85072e517557825e141 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/healthlake/2017-07-01/waiters-2.json @@ -0,0 +1,105 @@ +{ + "version": 2, + "waiters": { + "FHIRDatastoreActive": { + "operation": "DescribeFHIRDatastore", + "delay": 60, + "maxAttempts": 360, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "DatastoreProperties.DatastoreStatus", + "expected": "ACTIVE" + }, + { + "state": "failure", + "matcher": "path", + "argument": "DatastoreProperties.DatastoreStatus", + "expected": "CREATE_FAILED" + }, + { + "state": "failure", + "matcher": "path", + "argument": "DatastoreProperties.DatastoreStatus", + "expected": "DELETED" + } + ] + }, + "FHIRDatastoreDeleted": { + "operation": "DescribeFHIRDatastore", + "delay": 120, + "maxAttempts": 360, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "DatastoreProperties.DatastoreStatus", + "expected": "DELETED" + } + ] + }, + "FHIRExportJobCompleted": { + "operation": "DescribeFHIRExportJob", + "delay": 120, + "maxAttempts": 360, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "ExportJobProperties.JobStatus", + "expected": "COMPLETED" + }, + { + "state": "success", + "matcher": "path", + "argument": "ExportJobProperties.JobStatus", + "expected": "COMPLETED_WITH_ERRORS" + }, + { + "state": "failure", + "matcher": "path", + "argument": "ExportJobProperties.JobStatus", + "expected": "CANCEL_COMPLETED" + }, + { + "state": "failure", + "matcher": "path", + "argument": "ExportJobProperties.JobStatus", + "expected": "FAILED" + }, + { + "state": "failure", + "matcher": "path", + "argument": "ExportJobProperties.JobStatus", + "expected": "CANCEL_FAILED" + } + ] + }, + "FHIRImportJobCompleted": { + "operation": "DescribeFHIRImportJob", + "delay": 120, + "maxAttempts": 720, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "ImportJobProperties.JobStatus", + "expected": "COMPLETED" + }, + { + "state": "success", + "matcher": "path", + "argument": "ImportJobProperties.JobStatus", + "expected": "COMPLETED_WITH_ERRORS" + }, + { + "state": "failure", + "matcher": "path", + "argument": "ImportJobProperties.JobStatus", + "expected": "FAILED" + } + ] + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iam/2010-05-08/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/iam/2010-05-08/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..cd3a94aa608b493d4f345b4adf73efafe074cdef --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iam/2010-05-08/examples-1.json @@ -0,0 +1,1577 @@ +{ + "version": "1.0", + "examples": { + "AddClientIDToOpenIDConnectProvider": [ + { + "input": { + "ClientID": "my-application-ID", + "OpenIDConnectProviderArn": "arn:aws:iam::123456789012:oidc-provider/server.example.com" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following add-client-id-to-open-id-connect-provider command adds the client ID my-application-ID to the OIDC provider named server.example.com:", + "id": "028e91f4-e2a6-4d59-9e3b-4965a3fb19be", + "title": "To add a client ID (audience) to an Open-ID Connect (OIDC) provider" + } + ], + "AddRoleToInstanceProfile": [ + { + "input": { + "InstanceProfileName": "Webserver", + "RoleName": "S3Access" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command adds the role named S3Access to the instance profile named Webserver:", + "id": "c107fac3-edb6-4827-8a71-8863ec91c81f", + "title": "To add a role to an instance profile" + } + ], + "AddUserToGroup": [ + { + "input": { + "GroupName": "Admins", + "UserName": "Bob" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command adds an IAM user named Bob to the IAM group named Admins:", + "id": "619c7e6b-09f8-4036-857b-51a6ea5027ca", + "title": "To add a user to an IAM group" + } + ], + "AttachGroupPolicy": [ + { + "input": { + "GroupName": "Finance", + "PolicyArn": "arn:aws:iam::aws:policy/ReadOnlyAccess" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command attaches the AWS managed policy named ReadOnlyAccess to the IAM group named Finance.", + "id": "87551489-86f0-45db-9889-759936778f2b", + "title": "To attach a managed policy to an IAM group" + } + ], + "AttachRolePolicy": [ + { + "input": { + "PolicyArn": "arn:aws:iam::aws:policy/ReadOnlyAccess", + "RoleName": "ReadOnlyRole" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command attaches the AWS managed policy named ReadOnlyAccess to the IAM role named ReadOnlyRole.", + "id": "3e1b8c7c-99c8-4fc4-a20c-131fe3f22c7e", + "title": "To attach a managed policy to an IAM role" + } + ], + "AttachUserPolicy": [ + { + "input": { + "PolicyArn": "arn:aws:iam::aws:policy/AdministratorAccess", + "UserName": "Alice" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command attaches the AWS managed policy named AdministratorAccess to the IAM user named Alice.", + "id": "1372ebd8-9475-4b1a-a479-23b6fd4b8b3e", + "title": "To attach a managed policy to an IAM user" + } + ], + "ChangePassword": [ + { + "input": { + "NewPassword": "]35d/{pB9Fo9wJ", + "OldPassword": "3s0K_;xh4~8XXI" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command changes the password for the current IAM user.", + "id": "3a80c66f-bffb-46df-947c-1e8fa583b470", + "title": "To change the password for your IAM user" + } + ], + "CreateAccessKey": [ + { + "input": { + "UserName": "Bob" + }, + "output": { + "AccessKey": { + "AccessKeyId": "AKIAIOSFODNN7EXAMPLE", + "CreateDate": "2015-03-09T18:39:23.411Z", + "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY", + "Status": "Active", + "UserName": "Bob" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command creates an access key (access key ID and secret access key) for the IAM user named Bob.", + "id": "1fbb3211-4cf2-41db-8c20-ba58d9f5802d", + "title": "To create an access key for an IAM user" + } + ], + "CreateAccountAlias": [ + { + "input": { + "AccountAlias": "examplecorp" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command associates the alias examplecorp to your AWS account.", + "id": "5adaf6fb-94fc-4ca2-b825-2fbc2062add1", + "title": "To create an account alias" + } + ], + "CreateGroup": [ + { + "input": { + "GroupName": "Admins" + }, + "output": { + "Group": { + "Arn": "arn:aws:iam::123456789012:group/Admins", + "CreateDate": "2015-03-09T20:30:24.940Z", + "GroupId": "AIDGPMS9RO4H3FEXAMPLE", + "GroupName": "Admins", + "Path": "/" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command creates an IAM group named Admins.", + "id": "d5da2a90-5e69-4ef7-8ae8-4c33dc21fd21", + "title": "To create an IAM group" + } + ], + "CreateInstanceProfile": [ + { + "input": { + "InstanceProfileName": "Webserver" + }, + "output": { + "InstanceProfile": { + "Arn": "arn:aws:iam::123456789012:instance-profile/Webserver", + "CreateDate": "2015-03-09T20:33:19.626Z", + "InstanceProfileId": "AIPAJMBYC7DLSPEXAMPLE", + "InstanceProfileName": "Webserver", + "Path": "/", + "Roles": [ + + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command creates an instance profile named Webserver that is ready to have a role attached and then be associated with an EC2 instance.", + "id": "5d84e6ae-5921-4e39-8454-10232cd9ff9a", + "title": "To create an instance profile" + } + ], + "CreateLoginProfile": [ + { + "input": { + "Password": "h]6EszR}vJ*m", + "PasswordResetRequired": true, + "UserName": "Bob" + }, + "output": { + "LoginProfile": { + "CreateDate": "2015-03-10T20:55:40.274Z", + "PasswordResetRequired": true, + "UserName": "Bob" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command changes IAM user Bob's password and sets the flag that required Bob to change the password the next time he signs in.", + "id": "c63795bc-3444-40b3-89df-83c474ef88be", + "title": "To create an instance profile" + } + ], + "CreateOpenIDConnectProvider": [ + { + "input": { + "ClientIDList": [ + "my-application-id" + ], + "ThumbprintList": [ + "3768084dfb3d2b68b7897bf5f565da8efEXAMPLE" + ], + "Url": "https://server.example.com" + }, + "output": { + "OpenIDConnectProviderArn": "arn:aws:iam::123456789012:oidc-provider/server.example.com" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example defines a new OIDC provider in IAM with a client ID of my-application-id and pointing at the server with a URL of https://server.example.com.", + "id": "4e4a6bff-cc97-4406-922e-0ab4a82cdb63", + "title": "To create an instance profile" + } + ], + "CreateRole": [ + { + "input": { + "AssumeRolePolicyDocument": "", + "Path": "/", + "RoleName": "Test-Role" + }, + "output": { + "Role": { + "Arn": "arn:aws:iam::123456789012:role/Test-Role", + "AssumeRolePolicyDocument": "", + "CreateDate": "2013-06-07T20:43:32.821Z", + "Path": "/", + "RoleId": "AKIAIOSFODNN7EXAMPLE", + "RoleName": "Test-Role" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command creates a role named Test-Role and attaches a trust policy that you must convert from JSON to a string. Upon success, the response includes the same policy as a URL-encoded JSON string.", + "id": "eaaa4b5f-51f1-4f73-b0d3-30127040eff8", + "title": "To create an IAM role" + } + ], + "CreateUser": [ + { + "input": { + "UserName": "Bob" + }, + "output": { + "User": { + "Arn": "arn:aws:iam::123456789012:user/Bob", + "CreateDate": "2013-06-08T03:20:41.270Z", + "Path": "/", + "UserId": "AKIAIOSFODNN7EXAMPLE", + "UserName": "Bob" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following create-user command creates an IAM user named Bob in the current account.", + "id": "eb15f90b-e5f5-4af8-a594-e4e82b181a62", + "title": "To create an IAM user" + } + ], + "DeleteAccessKey": [ + { + "input": { + "AccessKeyId": "AKIDPMS9RO4H3FEXAMPLE", + "UserName": "Bob" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command deletes one access key (access key ID and secret access key) assigned to the IAM user named Bob.", + "id": "61a785a7-d30a-415a-ae18-ab9236e56871", + "title": "To delete an access key for an IAM user" + } + ], + "DeleteAccountAlias": [ + { + "input": { + "AccountAlias": "mycompany" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command removes the alias mycompany from the current AWS account:", + "id": "7abeca65-04a8-4500-a890-47f1092bf766", + "title": "To delete an account alias" + } + ], + "DeleteAccountPasswordPolicy": [ + { + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command removes the password policy from the current AWS account:", + "id": "9ddf755e-495c-49bc-ae3b-ea6cc9b8ebcf", + "title": "To delete the current account password policy" + } + ], + "DeleteGroupPolicy": [ + { + "input": { + "GroupName": "Admins", + "PolicyName": "ExamplePolicy" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command deletes the policy named ExamplePolicy from the group named Admins:", + "id": "e683f2bd-98a4-4fe0-bb66-33169c692d4a", + "title": "To delete a policy from an IAM group" + } + ], + "DeleteInstanceProfile": [ + { + "input": { + "InstanceProfileName": "ExampleInstanceProfile" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command deletes the instance profile named ExampleInstanceProfile", + "id": "12d74fb8-3433-49db-8171-a1fc764e354d", + "title": "To delete an instance profile" + } + ], + "DeleteLoginProfile": [ + { + "input": { + "UserName": "Bob" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command deletes the password for the IAM user named Bob.", + "id": "1fe57059-fc73-42e2-b992-517b7d573b5c", + "title": "To delete a password for an IAM user" + } + ], + "DeleteRole": [ + { + "input": { + "RoleName": "Test-Role" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command removes the role named Test-Role.", + "id": "053cdf74-9bda-44b8-bdbb-140fd5a32603", + "title": "To delete an IAM role" + } + ], + "DeleteRolePolicy": [ + { + "input": { + "PolicyName": "ExamplePolicy", + "RoleName": "Test-Role" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command removes the policy named ExamplePolicy from the role named Test-Role.", + "id": "9c667336-fde3-462c-b8f3-950800821e27", + "title": "To remove a policy from an IAM role" + } + ], + "DeleteSigningCertificate": [ + { + "input": { + "CertificateId": "TA7SMP42TDN5Z26OBPJE7EXAMPLE", + "UserName": "Anika" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command deletes the specified signing certificate for the IAM user named Anika.", + "id": "e3357586-ba9c-4070-b35b-d1a899b71987", + "title": "To delete a signing certificate for an IAM user" + } + ], + "DeleteUser": [ + { + "input": { + "UserName": "Bob" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command removes the IAM user named Bob from the current account.", + "id": "a13dc3f9-59fe-42d9-abbb-fb98b204fdf0", + "title": "To delete an IAM user" + } + ], + "DeleteUserPolicy": [ + { + "input": { + "PolicyName": "ExamplePolicy", + "UserName": "Juan" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following delete-user-policy command removes the specified policy from the IAM user named Juan:", + "id": "34f07ddc-9bc1-4f52-bc59-cd0a3ccd06c8", + "title": "To remove a policy from an IAM user" + } + ], + "DeleteVirtualMFADevice": [ + { + "input": { + "SerialNumber": "arn:aws:iam::123456789012:mfa/ExampleName" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following delete-virtual-mfa-device command removes the specified MFA device from the current AWS account.", + "id": "2933b08b-dbe7-4b89-b8c1-fdf75feea1ee", + "title": "To remove a virtual MFA device" + } + ], + "GenerateOrganizationsAccessReport": [ + { + "input": { + "EntityPath": "o-a1b2c3d4e5/r-f6g7h8i9j0example/ou-1a2b3c-k9l8m7n6o5example" + }, + "output": { + "JobId": "examplea-1234-b567-cde8-90fg123abcd4" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation generates a report for the organizational unit ou-rge0-awexample", + "id": "generateorganizationsaccessreport-ou", + "title": "To generate a service last accessed data report for an organizational unit" + } + ], + "GenerateServiceLastAccessedDetails": [ + { + "input": { + "Arn": "arn:aws:iam::123456789012:policy/ExamplePolicy1" + }, + "output": { + "JobId": "examplef-1305-c245-eba4-71fe298bcda7" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation generates a report for the policy: ExamplePolicy1", + "id": "generateaccessdata-policy-1541695178514", + "title": "To generate a service last accessed data report for a policy" + } + ], + "GetAccountPasswordPolicy": [ + { + "output": { + "PasswordPolicy": { + "AllowUsersToChangePassword": false, + "ExpirePasswords": false, + "HardExpiry": false, + "MaxPasswordAge": 90, + "MinimumPasswordLength": 8, + "PasswordReusePrevention": 12, + "RequireLowercaseCharacters": false, + "RequireNumbers": true, + "RequireSymbols": true, + "RequireUppercaseCharacters": false + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command displays details about the password policy for the current AWS account.", + "id": "5e4598c7-c425-431f-8af1-19073b3c4a5f", + "title": "To see the current account password policy" + } + ], + "GetAccountSummary": [ + { + "output": { + "SummaryMap": { + "AccessKeysPerUserQuota": 2, + "AccountAccessKeysPresent": 1, + "AccountMFAEnabled": 0, + "AccountSigningCertificatesPresent": 0, + "AttachedPoliciesPerGroupQuota": 10, + "AttachedPoliciesPerRoleQuota": 10, + "AttachedPoliciesPerUserQuota": 10, + "GlobalEndpointTokenVersion": 2, + "GroupPolicySizeQuota": 5120, + "Groups": 15, + "GroupsPerUserQuota": 10, + "GroupsQuota": 100, + "MFADevices": 6, + "MFADevicesInUse": 3, + "Policies": 8, + "PoliciesQuota": 1000, + "PolicySizeQuota": 5120, + "PolicyVersionsInUse": 22, + "PolicyVersionsInUseQuota": 10000, + "ServerCertificates": 1, + "ServerCertificatesQuota": 20, + "SigningCertificatesPerUserQuota": 2, + "UserPolicySizeQuota": 2048, + "Users": 27, + "UsersQuota": 5000, + "VersionsPerPolicyQuota": 5 + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command returns information about the IAM entity quotas and usage in the current AWS account.", + "id": "9d8447af-f344-45de-8219-2cebc3cce7f2", + "title": "To get information about IAM entity quotas and usage in the current account" + } + ], + "GetInstanceProfile": [ + { + "input": { + "InstanceProfileName": "ExampleInstanceProfile" + }, + "output": { + "InstanceProfile": { + "Arn": "arn:aws:iam::336924118301:instance-profile/ExampleInstanceProfile", + "CreateDate": "2013-06-12T23:52:02Z", + "InstanceProfileId": "AID2MAB8DPLSRHEXAMPLE", + "InstanceProfileName": "ExampleInstanceProfile", + "Path": "/", + "Roles": [ + { + "Arn": "arn:aws:iam::336924118301:role/Test-Role", + "AssumeRolePolicyDocument": "", + "CreateDate": "2013-01-09T06:33:26Z", + "Path": "/", + "RoleId": "AIDGPMS9RO4H3FEXAMPLE", + "RoleName": "Test-Role" + } + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command gets information about the instance profile named ExampleInstanceProfile.", + "id": "463b9ba5-18cc-4608-9ccb-5a7c6b6e5fe7", + "title": "To get information about an instance profile" + } + ], + "GetLoginProfile": [ + { + "input": { + "UserName": "Anika" + }, + "output": { + "LoginProfile": { + "CreateDate": "2012-09-21T23:03:39Z", + "UserName": "Anika" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command gets information about the password for the IAM user named Anika.", + "id": "d6b580cc-909f-4925-9caa-d425cbc1ad47", + "title": "To get password information for an IAM user" + } + ], + "GetOrganizationsAccessReport": [ + { + "input": { + "JobId": "examplea-1234-b567-cde8-90fg123abcd4" + }, + "output": { + "AccessDetails": [ + { + "EntityPath": "o-a1b2c3d4e5/r-f6g7h8i9j0example/ou-1a2b3c-k9l8m7n6o5example/111122223333", + "LastAuthenticatedTime": "2019-05-25T16:29:52Z", + "Region": "us-east-1", + "ServiceName": "Amazon DynamoDB", + "ServiceNamespace": "dynamodb", + "TotalAuthenticatedEntities": 2 + }, + { + "EntityPath": "o-a1b2c3d4e5/r-f6g7h8i9j0example/ou-1a2b3c-k9l8m7n6o5example/123456789012", + "LastAuthenticatedTime": "2019-06-15T13:12:06Z", + "Region": "us-east-1", + "ServiceName": "AWS Identity and Access Management", + "ServiceNamespace": "iam", + "TotalAuthenticatedEntities": 4 + }, + { + "ServiceName": "Amazon Simple Storage Service", + "ServiceNamespace": "s3", + "TotalAuthenticatedEntities": 0 + } + ], + "IsTruncated": false, + "JobCompletionDate": "2019-06-18T19:47:35.241Z", + "JobCreationDate": "2019-06-18T19:47:31.466Z", + "JobStatus": "COMPLETED", + "NumberOfServicesAccessible": 3, + "NumberOfServicesNotAccessed": 1 + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation gets details about the report with the job ID: examplea-1234-b567-cde8-90fg123abcd4", + "id": "getorganizationsaccessreport-ou", + "title": "To get details from a previously generated organizational unit report" + } + ], + "GetRole": [ + { + "input": { + "RoleName": "Test-Role" + }, + "output": { + "Role": { + "Arn": "arn:aws:iam::123456789012:role/Test-Role", + "AssumeRolePolicyDocument": "", + "CreateDate": "2013-04-18T05:01:58Z", + "MaxSessionDuration": 3600, + "Path": "/", + "RoleId": "AROADBQP57FF2AEXAMPLE", + "RoleLastUsed": { + "LastUsedDate": "2019-11-18T05:01:58Z", + "Region": "us-east-1" + }, + "RoleName": "Test-Role" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command gets information about the role named Test-Role.", + "id": "5b7d03a6-340c-472d-aa77-56425950d8b0", + "title": "To get information about an IAM role" + } + ], + "GetServiceLastAccessedDetails": [ + { + "input": { + "JobId": "examplef-1305-c245-eba4-71fe298bcda7" + }, + "output": { + "IsTruncated": false, + "JobCompletionDate": "2018-10-24T19:47:35.241Z", + "JobCreationDate": "2018-10-24T19:47:31.466Z", + "JobStatus": "COMPLETED", + "ServicesLastAccessed": [ + { + "LastAuthenticated": "2018-10-24T19:11:00Z", + "LastAuthenticatedEntity": "arn:aws:iam::123456789012:user/AWSExampleUser01", + "ServiceName": "AWS Identity and Access Management", + "ServiceNamespace": "iam", + "TotalAuthenticatedEntities": 2 + }, + { + "ServiceName": "Amazon Simple Storage Service", + "ServiceNamespace": "s3", + "TotalAuthenticatedEntities": 0 + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation gets details about the report with the job ID: examplef-1305-c245-eba4-71fe298bcda7", + "id": "getserviceaccessdetails-policy-1541696298085", + "title": "To get details from a previously-generated report" + } + ], + "GetServiceLastAccessedDetailsWithEntities": [ + { + "input": { + "JobId": "examplef-1305-c245-eba4-71fe298bcda7", + "ServiceNamespace": "iam" + }, + "output": { + "EntityDetailsList": [ + { + "EntityInfo": { + "Arn": "arn:aws:iam::123456789012:user/AWSExampleUser01", + "Id": "AIDAEX2EXAMPLEB6IGCDC", + "Name": "AWSExampleUser01", + "Path": "/", + "Type": "USER" + }, + "LastAuthenticated": "2018-10-24T19:10:00Z" + }, + { + "EntityInfo": { + "Arn": "arn:aws:iam::123456789012:role/AWSExampleRole01", + "Id": "AROAEAEXAMPLEIANXSIU4", + "Name": "AWSExampleRole01", + "Path": "/", + "Type": "ROLE" + } + } + ], + "IsTruncated": false, + "JobCompletionDate": "2018-10-24T19:47:35.241Z", + "JobCreationDate": "2018-10-24T19:47:31.466Z", + "JobStatus": "COMPLETED" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation returns details about the entities that attempted to access the IAM service.", + "id": "getserviceaccessdetailsentity-policy-1541697621384", + "title": "To get sntity details from a previously-generated report" + } + ], + "GetUser": [ + { + "input": { + "UserName": "Bob" + }, + "output": { + "User": { + "Arn": "arn:aws:iam::123456789012:user/Bob", + "CreateDate": "2012-09-21T23:03:13Z", + "Path": "/", + "UserId": "AKIAIOSFODNN7EXAMPLE", + "UserName": "Bob" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command gets information about the IAM user named Bob.", + "id": "ede000a1-9e4c-40db-bd0a-d4f95e41a6ab", + "title": "To get information about an IAM user" + } + ], + "ListAccessKeys": [ + { + "input": { + "UserName": "Alice" + }, + "output": { + "AccessKeyMetadata": [ + { + "AccessKeyId": "AKIA111111111EXAMPLE", + "CreateDate": "2016-12-01T22:19:58Z", + "Status": "Active", + "UserName": "Alice" + }, + { + "AccessKeyId": "AKIA222222222EXAMPLE", + "CreateDate": "2016-12-01T22:20:01Z", + "Status": "Active", + "UserName": "Alice" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command lists the access keys IDs for the IAM user named Alice.", + "id": "15571463-ebea-411a-a021-1c76bd2a3625", + "title": "To list the access key IDs for an IAM user" + } + ], + "ListAccountAliases": [ + { + "input": { + }, + "output": { + "AccountAliases": [ + "exmaple-corporation" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command lists the aliases for the current account.", + "id": "e27b457a-16f9-4e05-a006-3df7b3472741", + "title": "To list account aliases" + } + ], + "ListGroupPolicies": [ + { + "input": { + "GroupName": "Admins" + }, + "output": { + "PolicyNames": [ + "AdminRoot", + "KeyPolicy" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command lists the names of in-line policies that are embedded in the IAM group named Admins.", + "id": "02de5095-2410-4d3a-ac1b-cc40234af68f", + "title": "To list the in-line policies for an IAM group" + } + ], + "ListGroups": [ + { + "input": { + }, + "output": { + "Groups": [ + { + "Arn": "arn:aws:iam::123456789012:group/Admins", + "CreateDate": "2016-12-15T21:40:08.121Z", + "GroupId": "AGPA1111111111EXAMPLE", + "GroupName": "Admins", + "Path": "/division_abc/subdivision_xyz/" + }, + { + "Arn": "arn:aws:iam::123456789012:group/division_abc/subdivision_xyz/product_1234/engineering/Test", + "CreateDate": "2016-11-30T14:10:01.156Z", + "GroupId": "AGP22222222222EXAMPLE", + "GroupName": "Test", + "Path": "/division_abc/subdivision_xyz/product_1234/engineering/" + }, + { + "Arn": "arn:aws:iam::123456789012:group/division_abc/subdivision_xyz/product_1234/Managers", + "CreateDate": "2016-06-12T20:14:52.032Z", + "GroupId": "AGPI3333333333EXAMPLE", + "GroupName": "Managers", + "Path": "/division_abc/subdivision_xyz/product_1234/" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command lists the IAM groups in the current account:", + "id": "b3ab1380-2a21-42fb-8e85-503f65512c66", + "title": "To list the IAM groups for the current account" + } + ], + "ListGroupsForUser": [ + { + "input": { + "UserName": "Bob" + }, + "output": { + "Groups": [ + { + "Arn": "arn:aws:iam::123456789012:group/division_abc/subdivision_xyz/product_1234/engineering/Test", + "CreateDate": "2016-11-30T14:10:01.156Z", + "GroupId": "AGP2111111111EXAMPLE", + "GroupName": "Test", + "Path": "/division_abc/subdivision_xyz/product_1234/engineering/" + }, + { + "Arn": "arn:aws:iam::123456789012:group/division_abc/subdivision_xyz/product_1234/Managers", + "CreateDate": "2016-06-12T20:14:52.032Z", + "GroupId": "AGPI222222222SEXAMPLE", + "GroupName": "Managers", + "Path": "/division_abc/subdivision_xyz/product_1234/" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command displays the groups that the IAM user named Bob belongs to.", + "id": "278ec2ee-fc28-4136-83fb-433af0ae46a2", + "title": "To list the groups that an IAM user belongs to" + } + ], + "ListPoliciesGrantingServiceAccess": [ + { + "input": { + "Arn": "arn:aws:iam::123456789012:user/ExampleUser01", + "ServiceNamespaces": [ + "iam", + "ec2" + ] + }, + "output": { + "IsTruncated": false, + "PoliciesGrantingServiceAccess": [ + { + "Policies": [ + { + "PolicyArn": "arn:aws:iam::123456789012:policy/ExampleIamPolicy", + "PolicyName": "ExampleIamPolicy", + "PolicyType": "MANAGED" + }, + { + "EntityName": "AWSExampleGroup1", + "EntityType": "GROUP", + "PolicyName": "ExampleGroup1Policy", + "PolicyType": "INLINE" + } + ], + "ServiceNamespace": "iam" + }, + { + "Policies": [ + { + "PolicyArn": "arn:aws:iam::123456789012:policy/ExampleEc2Policy", + "PolicyName": "ExampleEc2Policy", + "PolicyType": "MANAGED" + } + ], + "ServiceNamespace": "ec2" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following operation lists policies that allow ExampleUser01 to access IAM or EC2.", + "id": "listpoliciesaccess-user-1541698749508", + "title": "To list policies that allow access to a service" + } + ], + "ListRoleTags": [ + { + "input": { + "RoleName": "taggedrole1" + }, + "output": { + "IsTruncated": false, + "Tags": [ + { + "Key": "Dept", + "Value": "12345" + }, + { + "Key": "Team", + "Value": "Accounting" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to list the tags attached to a role.", + "id": "to-list-the-tags-attached-to-an-iam-role-1506719238376", + "title": "To list the tags attached to an IAM role" + } + ], + "ListSigningCertificates": [ + { + "input": { + "UserName": "Bob" + }, + "output": { + "Certificates": [ + { + "CertificateBody": "-----BEGIN CERTIFICATE----------END CERTIFICATE-----", + "CertificateId": "TA7SMP42TDN5Z26OBPJE7EXAMPLE", + "Status": "Active", + "UploadDate": "2013-06-06T21:40:08Z", + "UserName": "Bob" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command lists the signing certificates for the IAM user named Bob.", + "id": "b4c10256-4fc9-457e-b3fd-4a110d4d73dc", + "title": "To list the signing certificates for an IAM user" + } + ], + "ListUserTags": [ + { + "input": { + "UserName": "anika" + }, + "output": { + "IsTruncated": false, + "Tags": [ + { + "Key": "Dept", + "Value": "12345" + }, + { + "Key": "Team", + "Value": "Accounting" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to list the tags attached to a user.", + "id": "to-list-the-tags-attached-to-an-iam-user-1506719473186", + "title": "To list the tags attached to an IAM user" + } + ], + "ListUsers": [ + { + "input": { + }, + "output": { + "Users": [ + { + "Arn": "arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/engineering/Juan", + "CreateDate": "2012-09-05T19:38:48Z", + "PasswordLastUsed": "2016-09-08T21:47:36Z", + "Path": "/division_abc/subdivision_xyz/engineering/", + "UserId": "AID2MAB8DPLSRHEXAMPLE", + "UserName": "Juan" + }, + { + "Arn": "arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/engineering/Anika", + "CreateDate": "2014-04-09T15:43:45Z", + "PasswordLastUsed": "2016-09-24T16:18:07Z", + "Path": "/division_abc/subdivision_xyz/engineering/", + "UserId": "AIDIODR4TAW7CSEXAMPLE", + "UserName": "Anika" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command lists the IAM users in the current account.", + "id": "9edfbd73-03d8-4d8a-9a79-76c85e8c8298", + "title": "To list IAM users" + } + ], + "ListVirtualMFADevices": [ + { + "input": { + }, + "output": { + "VirtualMFADevices": [ + { + "SerialNumber": "arn:aws:iam::123456789012:mfa/ExampleMFADevice" + }, + { + "SerialNumber": "arn:aws:iam::123456789012:mfa/Juan" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command lists the virtual MFA devices that have been configured for the current account.", + "id": "54f9ac18-5100-4070-bec4-fe5f612710d5", + "title": "To list virtual MFA devices" + } + ], + "PutGroupPolicy": [ + { + "input": { + "GroupName": "Admins", + "PolicyDocument": "{\"Version\":\"2012-10-17\",\"Statement\":{\"Effect\":\"Allow\",\"Action\":\"*\",\"Resource\":\"*\"}}", + "PolicyName": "AllPerms" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command adds a policy named AllPerms to the IAM group named Admins.", + "id": "4bc17418-758f-4d0f-ab0c-4d00265fec2e", + "title": "To add a policy to a group" + } + ], + "PutRolePolicy": [ + { + "input": { + "PolicyDocument": "{\"Version\":\"2012-10-17\",\"Statement\":{\"Effect\":\"Allow\",\"Action\":\"s3:*\",\"Resource\":\"*\"}}", + "PolicyName": "S3AccessPolicy", + "RoleName": "S3Access" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command adds a permissions policy to the role named Test-Role.", + "id": "de62fd00-46c7-4601-9e0d-71d5fbb11ecb", + "title": "To attach a permissions policy to an IAM role" + } + ], + "PutUserPolicy": [ + { + "input": { + "PolicyDocument": "{\"Version\":\"2012-10-17\",\"Statement\":{\"Effect\":\"Allow\",\"Action\":\"*\",\"Resource\":\"*\"}}", + "PolicyName": "AllAccessPolicy", + "UserName": "Bob" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command attaches a policy to the IAM user named Bob.", + "id": "2551ffc6-3576-4d39-823f-30b60bffc2c7", + "title": "To attach a policy to an IAM user" + } + ], + "RemoveRoleFromInstanceProfile": [ + { + "input": { + "InstanceProfileName": "ExampleInstanceProfile", + "RoleName": "Test-Role" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command removes the role named Test-Role from the instance profile named ExampleInstanceProfile.", + "id": "6d9f46f1-9f4a-4873-b403-51a85c5c627c", + "title": "To remove a role from an instance profile" + } + ], + "RemoveUserFromGroup": [ + { + "input": { + "GroupName": "Admins", + "UserName": "Bob" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command removes the user named Bob from the IAM group named Admins.", + "id": "fb54d5b4-0caf-41d8-af0e-10a84413f174", + "title": "To remove a user from an IAM group" + } + ], + "SetSecurityTokenServicePreferences": [ + { + "input": { + "GlobalEndpointTokenVersion": "v2Token" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command sets the STS global endpoint token to version 2. Version 2 tokens are valid in all Regions.", + "id": "61a785a7-d30a-415a-ae18-ab9236e56871", + "title": "To delete an access key for an IAM user" + } + ], + "TagRole": [ + { + "input": { + "RoleName": "taggedrole", + "Tags": [ + { + "Key": "Dept", + "Value": "Accounting" + }, + { + "Key": "CostCenter", + "Value": "12345" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to add tags to an existing role.", + "id": "to-add-a-tag-key-and-value-to-an-iam-role-1506718791513", + "title": "To add a tag key and value to an IAM role" + } + ], + "TagUser": [ + { + "input": { + "Tags": [ + { + "Key": "Dept", + "Value": "Accounting" + }, + { + "Key": "CostCenter", + "Value": "12345" + } + ], + "UserName": "anika" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to add tags to an existing user.", + "id": "to-add-a-tag-key-and-value-to-an-iam-user-1506719044227", + "title": "To add a tag key and value to an IAM user" + } + ], + "UntagRole": [ + { + "input": { + "RoleName": "taggedrole", + "TagKeys": [ + "Dept" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to remove a tag with the key 'Dept' from a role named 'taggedrole'.", + "id": "to-remove-a-tag-from-an-iam-role-1506719589943", + "title": "To remove a tag from an IAM role" + } + ], + "UntagUser": [ + { + "input": { + "TagKeys": [ + "Dept" + ], + "UserName": "anika" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to remove tags that are attached to a user named 'anika'.", + "id": "to-remove-a-tag-from-an-iam-user-1506719725554", + "title": "To remove a tag from an IAM user" + } + ], + "UpdateAccessKey": [ + { + "input": { + "AccessKeyId": "AKIAIOSFODNN7EXAMPLE", + "Status": "Inactive", + "UserName": "Bob" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command deactivates the specified access key (access key ID and secret access key) for the IAM user named Bob.", + "id": "02b556fd-e673-49b7-ab6b-f2f9035967d0", + "title": "To activate or deactivate an access key for an IAM user" + } + ], + "UpdateAccountPasswordPolicy": [ + { + "input": { + "MinimumPasswordLength": 8, + "RequireNumbers": true + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command sets the password policy to require a minimum length of eight characters and to require one or more numbers in the password:", + "id": "c263a1af-37dc-4423-8dba-9790284ef5e0", + "title": "To set or change the current account password policy" + } + ], + "UpdateAssumeRolePolicy": [ + { + "input": { + "PolicyDocument": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"ec2.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}", + "RoleName": "S3AccessForEC2Instances" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command updates the role trust policy for the role named Test-Role:", + "id": "c9150063-d953-4e99-9576-9685872006c6", + "title": "To update the trust policy for an IAM role" + } + ], + "UpdateGroup": [ + { + "input": { + "GroupName": "Test", + "NewGroupName": "Test-1" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command changes the name of the IAM group Test to Test-1.", + "id": "f0cf1662-91ae-4278-a80e-7db54256ccba", + "title": "To rename an IAM group" + } + ], + "UpdateLoginProfile": [ + { + "input": { + "Password": "SomeKindOfPassword123!@#", + "UserName": "Bob" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command creates or changes the password for the IAM user named Bob.", + "id": "036d9498-ecdb-4ed6-a8d8-366c383d1487", + "title": "To change the password for an IAM user" + } + ], + "UpdateSigningCertificate": [ + { + "input": { + "CertificateId": "TA7SMP42TDN5Z26OBPJE7EXAMPLE", + "Status": "Inactive", + "UserName": "Bob" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command changes the status of a signing certificate for a user named Bob to Inactive.", + "id": "829aee7b-efc5-4b3b-84a5-7f899b38018d", + "title": "To change the active status of a signing certificate for an IAM user" + } + ], + "UpdateUser": [ + { + "input": { + "NewUserName": "Robert", + "UserName": "Bob" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command changes the name of the IAM user Bob to Robert. It does not change the user's path.", + "id": "275d53ed-347a-44e6-b7d0-a96276154352", + "title": "To change an IAM user's name" + } + ], + "UploadServerCertificate": [ + { + "input": { + "CertificateBody": "-----BEGIN CERTIFICATE----------END CERTIFICATE-----", + "Path": "/company/servercerts/", + "PrivateKey": "-----BEGIN DSA PRIVATE KEY----------END DSA PRIVATE KEY-----", + "ServerCertificateName": "ProdServerCert" + }, + "output": { + "ServerCertificateMetadata": { + "Arn": "arn:aws:iam::123456789012:server-certificate/company/servercerts/ProdServerCert", + "Expiration": "2012-05-08T01:02:03.004Z", + "Path": "/company/servercerts/", + "ServerCertificateId": "ASCA1111111111EXAMPLE", + "ServerCertificateName": "ProdServerCert", + "UploadDate": "2010-05-08T01:02:03.004Z" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following upload-server-certificate command uploads a server certificate to your AWS account:", + "id": "06eab6d1-ebf2-4bd9-839d-f7508b9a38b6", + "title": "To upload a server certificate to your AWS account" + } + ], + "UploadSigningCertificate": [ + { + "input": { + "CertificateBody": "-----BEGIN CERTIFICATE----------END CERTIFICATE-----", + "UserName": "Bob" + }, + "output": { + "Certificate": { + "CertificateBody": "-----BEGIN CERTIFICATE----------END CERTIFICATE-----", + "CertificateId": "ID123456789012345EXAMPLE", + "Status": "Active", + "UploadDate": "2015-06-06T21:40:08.121Z", + "UserName": "Bob" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following command uploads a signing certificate for the IAM user named Bob.", + "id": "e67489b6-7b73-4e30-9ed3-9a9e0231e458", + "title": "To upload a signing certificate for an IAM user" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iam/2010-05-08/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/iam/2010-05-08/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..91c09a217c93670e0a2413003f606560376ec1ac --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iam/2010-05-08/paginators-1.json @@ -0,0 +1,254 @@ +{ + "pagination": { + "GetAccountAuthorizationDetails": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": [ + "UserDetailList", + "GroupDetailList", + "RoleDetailList", + "Policies" + ] + }, + "GetGroup": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "Users", + "non_aggregate_keys": [ + "Group" + ] + }, + "ListAccessKeys": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "AccessKeyMetadata" + }, + "ListAccountAliases": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "AccountAliases" + }, + "ListAttachedGroupPolicies": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "AttachedPolicies" + }, + "ListAttachedRolePolicies": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "AttachedPolicies" + }, + "ListAttachedUserPolicies": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "AttachedPolicies" + }, + "ListEntitiesForPolicy": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": [ + "PolicyGroups", + "PolicyUsers", + "PolicyRoles" + ] + }, + "ListGroupPolicies": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "PolicyNames" + }, + "ListGroups": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "Groups" + }, + "ListGroupsForUser": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "Groups" + }, + "ListInstanceProfiles": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "InstanceProfiles" + }, + "ListInstanceProfilesForRole": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "InstanceProfiles" + }, + "ListMFADevices": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "MFADevices" + }, + "ListPolicies": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "Policies" + }, + "ListPolicyVersions": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "Versions" + }, + "ListRolePolicies": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "PolicyNames" + }, + "ListRoles": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "Roles" + }, + "ListServerCertificates": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "ServerCertificateMetadataList" + }, + "ListSigningCertificates": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "Certificates" + }, + "ListSSHPublicKeys": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "SSHPublicKeys" + }, + "ListUserPolicies": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "PolicyNames" + }, + "ListUsers": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "Users" + }, + "ListVirtualMFADevices": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "VirtualMFADevices" + }, + "SimulateCustomPolicy": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "EvaluationResults" + }, + "SimulatePrincipalPolicy": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "EvaluationResults" + }, + "ListUserTags": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "Tags" + }, + "ListInstanceProfileTags": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "Tags" + }, + "ListMFADeviceTags": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "Tags" + }, + "ListOpenIDConnectProviderTags": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "Tags" + }, + "ListPolicyTags": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "Tags" + }, + "ListRoleTags": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "Tags" + }, + "ListSAMLProviderTags": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "Tags" + }, + "ListServerCertificateTags": { + "input_token": "Marker", + "limit_key": "MaxItems", + "more_results": "IsTruncated", + "output_token": "Marker", + "result_key": "Tags" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iam/2010-05-08/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/iam/2010-05-08/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..6248041527d0efd3d62551bb067ab72406a561f7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iam/2010-05-08/waiters-2.json @@ -0,0 +1,73 @@ +{ + "version": 2, + "waiters": { + "InstanceProfileExists": { + "delay": 1, + "operation": "GetInstanceProfile", + "maxAttempts": 40, + "acceptors": [ + { + "expected": 200, + "matcher": "status", + "state": "success" + }, + { + "state": "retry", + "matcher": "status", + "expected": 404 + } + ] + }, + "UserExists": { + "delay": 1, + "operation": "GetUser", + "maxAttempts": 20, + "acceptors": [ + { + "state": "success", + "matcher": "status", + "expected": 200 + }, + { + "state": "retry", + "matcher": "error", + "expected": "NoSuchEntity" + } + ] + }, + "RoleExists": { + "delay": 1, + "operation": "GetRole", + "maxAttempts": 20, + "acceptors": [ + { + "state": "success", + "matcher": "status", + "expected": 200 + }, + { + "state": "retry", + "matcher": "error", + "expected": "NoSuchEntity" + } + ] + }, + "PolicyExists": { + "delay": 1, + "operation": "GetPolicy", + "maxAttempts": 20, + "acceptors": [ + { + "state": "success", + "matcher": "status", + "expected": 200 + }, + { + "state": "retry", + "matcher": "error", + "expected": "NoSuchEntity" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/imagebuilder/2019-12-02/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/imagebuilder/2019-12-02/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/imagebuilder/2019-12-02/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/imagebuilder/2019-12-02/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/imagebuilder/2019-12-02/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..f259294ddcf60aeff2adeeb2fd9fcdb18c115d74 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/imagebuilder/2019-12-02/paginators-1.json @@ -0,0 +1,129 @@ +{ + "pagination": { + "ListComponentBuildVersions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "componentSummaryList" + }, + "ListComponents": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "componentVersionList" + }, + "ListContainerRecipes": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "containerRecipeSummaryList" + }, + "ListDistributionConfigurations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "distributionConfigurationSummaryList" + }, + "ListImageBuildVersions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "imageSummaryList" + }, + "ListImagePackages": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "imagePackageList" + }, + "ListImagePipelineImages": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "imageSummaryList" + }, + "ListImagePipelines": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "imagePipelineList" + }, + "ListImageRecipes": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "imageRecipeSummaryList" + }, + "ListImageScanFindingAggregations": { + "input_token": "nextToken", + "output_token": "nextToken", + "result_key": "responses" + }, + "ListImageScanFindings": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "findings" + }, + "ListImages": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "imageVersionList" + }, + "ListInfrastructureConfigurations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "infrastructureConfigurationSummaryList" + }, + "ListLifecycleExecutionResources": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "resources" + }, + "ListLifecycleExecutions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "lifecycleExecutions" + }, + "ListLifecyclePolicies": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "lifecyclePolicySummaryList" + }, + "ListWaitingWorkflowSteps": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "steps" + }, + "ListWorkflowBuildVersions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "workflowSummaryList" + }, + "ListWorkflowExecutions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "workflowExecutions" + }, + "ListWorkflowStepExecutions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "steps" + }, + "ListWorkflows": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "workflowVersionList" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/imagebuilder/2019-12-02/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/imagebuilder/2019-12-02/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..41060605ea0d4011a5d73058af642d115f15c2f2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/imagebuilder/2019-12-02/paginators-1.sdk-extras.json @@ -0,0 +1,95 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "ListComponentBuildVersions": { + "non_aggregate_keys": [ + "requestId" + ] + }, + "ListComponents": { + "non_aggregate_keys": [ + "requestId" + ] + }, + "ListContainerRecipes": { + "non_aggregate_keys": [ + "requestId" + ] + }, + "ListDistributionConfigurations": { + "non_aggregate_keys": [ + "requestId" + ] + }, + "ListImageBuildVersions": { + "non_aggregate_keys": [ + "requestId" + ] + }, + "ListImagePackages": { + "non_aggregate_keys": [ + "requestId" + ] + }, + "ListImagePipelineImages": { + "non_aggregate_keys": [ + "requestId" + ] + }, + "ListImagePipelines": { + "non_aggregate_keys": [ + "requestId" + ] + }, + "ListImageRecipes": { + "non_aggregate_keys": [ + "requestId" + ] + }, + "ListImageScanFindingAggregations": { + "non_aggregate_keys": [ + "requestId", + "aggregationType" + ] + }, + "ListImageScanFindings": { + "non_aggregate_keys": [ + "requestId" + ] + }, + "ListImages": { + "non_aggregate_keys": [ + "requestId" + ] + }, + "ListInfrastructureConfigurations": { + "non_aggregate_keys": [ + "requestId" + ] + }, + "ListLifecycleExecutionResources": { + "non_aggregate_keys": [ + "lifecycleExecutionId", + "lifecycleExecutionState" + ] + }, + "ListWorkflowExecutions": { + "non_aggregate_keys": [ + "requestId", + "imageBuildVersionArn", + "message" + ] + }, + "ListWorkflowStepExecutions": { + "non_aggregate_keys": [ + "requestId", + "workflowBuildVersionArn", + "workflowExecutionId", + "imageBuildVersionArn", + "message" + ] + } + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/importexport/2010-06-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/importexport/2010-06-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..702385ea6f75964ebc5c7c48aa0b439d38827fcc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/importexport/2010-06-01/paginators-1.json @@ -0,0 +1,11 @@ +{ + "pagination": { + "ListJobs": { + "input_token": "Marker", + "output_token": "Jobs[-1].JobId", + "more_results": "IsTruncated", + "limit_key": "MaxJobs", + "result_key": "Jobs" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/inspector-scan/2023-08-08/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/inspector-scan/2023-08-08/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/inspector-scan/2023-08-08/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/inspector2/2020-06-08/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/inspector2/2020-06-08/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/inspector2/2020-06-08/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/inspector2/2020-06-08/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/inspector2/2020-06-08/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0df0287fe46b6680df8fdcab569b069b8b2e77d2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/inspector2/2020-06-08/paginators-1.json @@ -0,0 +1,98 @@ +{ + "pagination": { + "ListAccountPermissions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "permissions" + }, + "ListCoverage": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "coveredResources" + }, + "ListCoverageStatistics": { + "input_token": "nextToken", + "output_token": "nextToken", + "result_key": "countsByGroup" + }, + "ListDelegatedAdminAccounts": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "delegatedAdminAccounts" + }, + "ListFilters": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "filters" + }, + "ListFindingAggregations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "responses" + }, + "ListFindings": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "findings" + }, + "ListMembers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "members" + }, + "ListUsageTotals": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "totals" + }, + "SearchVulnerabilities": { + "input_token": "nextToken", + "output_token": "nextToken", + "result_key": "vulnerabilities" + }, + "GetCisScanResultDetails": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "scanResultDetails" + }, + "ListCisScanConfigurations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "scanConfigurations" + }, + "ListCisScanResultsAggregatedByChecks": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "checkAggregations" + }, + "ListCisScanResultsAggregatedByTargetResource": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "targetResourceAggregations" + }, + "ListCisScans": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "scans" + }, + "GetClustersForImage": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "cluster" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/inspector2/2020-06-08/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/inspector2/2020-06-08/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..b01a0bfcf34ec59e85bac60e7bee780d8f261438 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/inspector2/2020-06-08/paginators-1.sdk-extras.json @@ -0,0 +1,17 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "ListFindingAggregations": { + "non_aggregate_keys": [ + "aggregationType" + ] + }, + "ListCoverageStatistics": { + "non_aggregate_keys": [ + "totalCounts" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iot-data/2015-05-28/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/iot-data/2015-05-28/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iot-data/2015-05-28/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iot-data/2015-05-28/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/iot-data/2015-05-28/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..26d4a561ca3b1c5ce5aec7195a82654c84c71a17 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iot-data/2015-05-28/paginators-1.json @@ -0,0 +1,10 @@ +{ + "pagination": { + "ListRetainedMessages": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "retainedTopics" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iot-managed-integrations/2025-03-03/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/iot-managed-integrations/2025-03-03/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0815eadf91844c3a3027d72919abbd4957eeda46 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iot-managed-integrations/2025-03-03/paginators-1.json @@ -0,0 +1,106 @@ +{ + "pagination": { + "ListCredentialLockers": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListDestinations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "DestinationList" + }, + "ListEventLogConfigurations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "EventLogConfigurationList" + }, + "ListManagedThingSchemas": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListManagedThings": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListNotificationConfigurations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "NotificationConfigurationList" + }, + "ListOtaTaskConfigurations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListOtaTaskExecutions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ExecutionSummaries" + }, + "ListOtaTasks": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Tasks" + }, + "ListProvisioningProfiles": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListSchemaVersions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListAccountAssociations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListCloudConnectors": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListConnectorDestinations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ConnectorDestinationList" + }, + "ListDeviceDiscoveries": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListDiscoveredDevices": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListManagedThingAccountAssociations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iotanalytics/2017-11-27/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/iotanalytics/2017-11-27/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iotanalytics/2017-11-27/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iotanalytics/2017-11-27/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/iotanalytics/2017-11-27/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..d1bfaaaa0170b589d85f4ef354c36dde82691ece --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iotanalytics/2017-11-27/paginators-1.json @@ -0,0 +1,34 @@ +{ + "pagination": { + "ListChannels": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "channelSummaries" + }, + "ListDatasetContents": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "datasetContentSummaries" + }, + "ListDatasets": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "datasetSummaries" + }, + "ListDatastores": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "datastoreSummaries" + }, + "ListPipelines": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "pipelineSummaries" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iotdeviceadvisor/2020-09-18/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/iotdeviceadvisor/2020-09-18/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iotdeviceadvisor/2020-09-18/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iotdeviceadvisor/2020-09-18/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/iotdeviceadvisor/2020-09-18/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iotdeviceadvisor/2020-09-18/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iotevents/2018-07-27/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/iotevents/2018-07-27/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iotevents/2018-07-27/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iotevents/2018-07-27/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/iotevents/2018-07-27/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iotevents/2018-07-27/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iotthingsgraph/2018-09-06/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/iotthingsgraph/2018-09-06/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iotthingsgraph/2018-09-06/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iotthingsgraph/2018-09-06/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/iotthingsgraph/2018-09-06/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..bc92f846c4c6afc2f2bca823a4f2a16f53f5e31f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iotthingsgraph/2018-09-06/paginators-1.json @@ -0,0 +1,64 @@ +{ + "pagination": { + "GetFlowTemplateRevisions": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "summaries" + }, + "GetSystemTemplateRevisions": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "summaries" + }, + "ListFlowExecutionMessages": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "messages" + }, + "ListTagsForResource": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "tags" + }, + "SearchEntities": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "descriptions" + }, + "SearchFlowExecutions": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "summaries" + }, + "SearchFlowTemplates": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "summaries" + }, + "SearchSystemInstances": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "summaries" + }, + "SearchSystemTemplates": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "summaries" + }, + "SearchThings": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "things" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iottwinmaker/2021-11-29/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/iottwinmaker/2021-11-29/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iottwinmaker/2021-11-29/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iottwinmaker/2021-11-29/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/iottwinmaker/2021-11-29/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iottwinmaker/2021-11-29/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/iottwinmaker/2021-11-29/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/iottwinmaker/2021-11-29/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/iottwinmaker/2021-11-29/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ivs-realtime/2020-07-14/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/ivs-realtime/2020-07-14/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..8eb02086857c08b150a1cc29f33eae3f322f5db1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ivs-realtime/2020-07-14/paginators-1.json @@ -0,0 +1,22 @@ +{ + "pagination": { + "ListPublicKeys": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "publicKeys" + }, + "ListIngestConfigurations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "ingestConfigurations" + }, + "ListParticipantReplicas": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "replicas" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ivs-realtime/2020-07-14/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/ivs-realtime/2020-07-14/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ivs-realtime/2020-07-14/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ivs/2020-07-14/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/ivs/2020-07-14/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ivs/2020-07-14/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ivs/2020-07-14/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/ivs/2020-07-14/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..572d1c739b015bab0eb172f3f17bb3cfd6a52d50 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ivs/2020-07-14/paginators-1.json @@ -0,0 +1,34 @@ +{ + "pagination": { + "ListChannels": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "channels" + }, + "ListStreamKeys": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "streamKeys" + }, + "ListStreams": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "streams" + }, + "ListPlaybackKeyPairs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "keyPairs" + }, + "ListRecordingConfigurations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "recordingConfigurations" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ivschat/2020-07-14/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/ivschat/2020-07-14/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ivschat/2020-07-14/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ivschat/2020-07-14/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/ivschat/2020-07-14/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ivschat/2020-07-14/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ivschat/2020-07-14/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/ivschat/2020-07-14/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ivschat/2020-07-14/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/kafka/2018-11-14/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/kafka/2018-11-14/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..158c50c141c4ff539fca51c81b97510b2c3bdc9e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/kafka/2018-11-14/paginators-1.json @@ -0,0 +1,88 @@ +{ + "pagination": { + "ListClusters": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ClusterInfoList" + }, + "ListNodes": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "NodeInfoList" + }, + "ListConfigurations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Configurations" + }, + "ListClusterOperations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ClusterOperationInfoList" + }, + "ListConfigurationRevisions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Revisions" + }, + "ListKafkaVersions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "KafkaVersions" + }, + "ListScramSecrets": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "SecretArnList" + }, + "ListClustersV2": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ClusterInfoList" + }, + "ListVpcConnections": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "VpcConnections" + }, + "ListClientVpcConnections": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ClientVpcConnections" + }, + "ListClusterOperationsV2": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ClusterOperationInfoList" + }, + "ListReplicators": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Replicators" + }, + "ListTopics": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Topics" + }, + "DescribeTopicPartitions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Partitions" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/kendra/2019-02-03/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/kendra/2019-02-03/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/kendra/2019-02-03/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/kendra/2019-02-03/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/kendra/2019-02-03/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/kendra/2019-02-03/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/kinesis-video-webrtc-storage/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/kinesis-video-webrtc-storage/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/kinesis-video-webrtc-storage/2018-05-10/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/kinesisanalytics/2015-08-14/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/kinesisanalytics/2015-08-14/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/kinesisanalytics/2015-08-14/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/kinesisanalytics/2015-08-14/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/kinesisanalytics/2015-08-14/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/kinesisanalytics/2015-08-14/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/kinesisanalyticsv2/2018-05-23/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/kinesisanalyticsv2/2018-05-23/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/kinesisanalyticsv2/2018-05-23/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/kinesisanalyticsv2/2018-05-23/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/kinesisanalyticsv2/2018-05-23/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..eb315fdd2d6253036894d20063e3bf4db4a7baa7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/kinesisanalyticsv2/2018-05-23/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "ListApplicationSnapshots": { + "input_token": "NextToken", + "limit_key": "Limit", + "output_token": "NextToken", + "result_key": "SnapshotSummaries" + }, + "ListApplications": { + "input_token": "NextToken", + "limit_key": "Limit", + "output_token": "NextToken", + "result_key": "ApplicationSummaries" + }, + "ListApplicationOperations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "Limit", + "result_key": "ApplicationOperationInfoList" + }, + "ListApplicationVersions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "Limit", + "result_key": "ApplicationVersionSummaries" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/lakeformation/2017-03-31/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/lakeformation/2017-03-31/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/lakeformation/2017-03-31/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/lakeformation/2017-03-31/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/lakeformation/2017-03-31/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..5970057b914904070720f029d9dfcbbba87b8770 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/lakeformation/2017-03-31/paginators-1.json @@ -0,0 +1,40 @@ +{ + "pagination": { + "GetWorkUnits": { + "input_token": "NextToken", + "limit_key": "PageSize", + "output_token": "NextToken", + "result_key": "WorkUnitRanges" + }, + "ListDataCellsFilter": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "DataCellsFilters" + }, + "ListLFTags": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "LFTags" + }, + "SearchDatabasesByLFTags": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "DatabaseList" + }, + "SearchTablesByLFTags": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "TableList" + }, + "ListLFTagExpressions": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "LFTagExpressions" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/lakeformation/2017-03-31/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/lakeformation/2017-03-31/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..aea980d66c86f763091faf97cf19ccb51e127585 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/lakeformation/2017-03-31/paginators-1.sdk-extras.json @@ -0,0 +1,12 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "GetWorkUnits": { + "non_aggregate_keys": [ + "QueryId" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/launch-wizard/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/launch-wizard/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..7f6109538bc37c776f2fb4e7a4ddb531768f98c9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/launch-wizard/2018-05-10/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "ListDeploymentEvents": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "deploymentEvents" + }, + "ListDeployments": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "deployments" + }, + "ListWorkloadDeploymentPatterns": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "workloadDeploymentPatterns" + }, + "ListWorkloads": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "workloads" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/license-manager-user-subscriptions/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/license-manager-user-subscriptions/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..413006e544eba7a6adaeb6770af5adcaf4ab2e5a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/license-manager-user-subscriptions/2018-05-10/paginators-1.json @@ -0,0 +1,34 @@ +{ + "pagination": { + "ListIdentityProviders": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "IdentityProviderSummaries" + }, + "ListInstances": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "InstanceSummaries" + }, + "ListProductSubscriptions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ProductUserSummaries" + }, + "ListUserAssociations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "InstanceUserSummaries" + }, + "ListLicenseServerEndpoints": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "LicenseServerEndpoints" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/license-manager-user-subscriptions/2018-05-10/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/license-manager-user-subscriptions/2018-05-10/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/license-manager-user-subscriptions/2018-05-10/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/license-manager/2018-08-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/license-manager/2018-08-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/license-manager/2018-08-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/license-manager/2018-08-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/license-manager/2018-08-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..03a3ca4d58d588c5b29e24a6922e8b347f91ac7d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/license-manager/2018-08-01/paginators-1.json @@ -0,0 +1,34 @@ +{ + "pagination": { + "ListAssociationsForLicenseConfiguration": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "LicenseConfigurationAssociations" + }, + "ListLicenseConfigurations": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "LicenseConfigurations" + }, + "ListLicenseSpecificationsForResource": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "LicenseSpecifications" + }, + "ListResourceInventory": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ResourceInventoryList" + }, + "ListUsageForLicenseConfiguration": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "LicenseConfigurationUsageList" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/lightsail/2016-11-28/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/lightsail/2016-11-28/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/lightsail/2016-11-28/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/lightsail/2016-11-28/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/lightsail/2016-11-28/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..fbea9383a8467594f6d778abbb170ad16df17499 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/lightsail/2016-11-28/paginators-1.json @@ -0,0 +1,104 @@ +{ + "pagination": { + "GetActiveNames": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "activeNames" + }, + "GetBlueprints": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "blueprints" + }, + "GetBundles": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "bundles" + }, + "GetDomains": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "domains" + }, + "GetInstanceSnapshots": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "instanceSnapshots" + }, + "GetInstances": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "instances" + }, + "GetKeyPairs": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "keyPairs" + }, + "GetOperations": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "operations" + }, + "GetStaticIps": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "staticIps" + }, + "GetCloudFormationStackRecords": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "cloudFormationStackRecords" + }, + "GetDiskSnapshots": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "diskSnapshots" + }, + "GetDisks": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "disks" + }, + "GetExportSnapshotRecords": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "exportSnapshotRecords" + }, + "GetLoadBalancers": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "loadBalancers" + }, + "GetRelationalDatabaseBlueprints": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "blueprints" + }, + "GetRelationalDatabaseBundles": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "bundles" + }, + "GetRelationalDatabaseEvents": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "relationalDatabaseEvents" + }, + "GetRelationalDatabaseParameters": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "parameters" + }, + "GetRelationalDatabaseSnapshots": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "relationalDatabaseSnapshots" + }, + "GetRelationalDatabases": { + "input_token": "pageToken", + "output_token": "nextPageToken", + "result_key": "relationalDatabases" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/location/2020-11-19/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/location/2020-11-19/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/location/2020-11-19/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/location/2020-11-19/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/location/2020-11-19/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..55e77c9359f58c1d5718e81ec6a63629cbd912ea --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/location/2020-11-19/paginators-1.json @@ -0,0 +1,70 @@ +{ + "pagination": { + "GetDevicePositionHistory": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "DevicePositions", + "limit_key": "MaxResults" + }, + "ListGeofenceCollections": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Entries" + }, + "ListGeofences": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Entries", + "limit_key": "MaxResults" + }, + "ListMaps": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Entries" + }, + "ListPlaceIndexes": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Entries" + }, + "ListTrackerConsumers": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ConsumerArns" + }, + "ListTrackers": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Entries" + }, + "ListDevicePositions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Entries" + }, + "ListRouteCalculators": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Entries" + }, + "ListKeys": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Entries" + }, + "ForecastGeofenceEvents": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ForecastedEvents" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/location/2020-11-19/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/location/2020-11-19/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..2aba0bfb659776ad1b5e97cb040810f389657667 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/location/2020-11-19/paginators-1.sdk-extras.json @@ -0,0 +1,13 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "ForecastGeofenceEvents": { + "non_aggregate_keys": [ + "DistanceUnit", + "SpeedUnit" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/macie2/2020-01-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/macie2/2020-01-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..8037ac751eca73837229611c72b7bfa6a5cc239a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/macie2/2020-01-01/paginators-1.json @@ -0,0 +1,106 @@ +{ + "pagination": { + "DescribeBuckets": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "buckets" + }, + "GetUsageStatistics": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "records", + "non_aggregate_keys": [ + "timeRange" + ] + }, + "ListClassificationJobs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListCustomDataIdentifiers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListFindings": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "findingIds" + }, + "ListFindingsFilters": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "findingsFilterListItems" + }, + "ListInvitations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "invitations" + }, + "ListMembers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "members" + }, + "ListOrganizationAdminAccounts": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "adminAccounts" + }, + "SearchResources": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "matchingResources" + }, + "ListClassificationScopes": { + "input_token": "nextToken", + "output_token": "nextToken", + "result_key": "classificationScopes" + }, + "ListAllowLists": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "allowLists" + }, + "ListManagedDataIdentifiers": { + "input_token": "nextToken", + "output_token": "nextToken", + "result_key": "items" + }, + "ListResourceProfileDetections": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "detections" + }, + "ListSensitivityInspectionTemplates": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "sensitivityInspectionTemplates" + }, + "ListResourceProfileArtifacts": { + "input_token": "nextToken", + "output_token": "nextToken", + "result_key": "artifacts" + }, + "ListAutomatedDiscoveryAccounts": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/macie2/2020-01-01/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/macie2/2020-01-01/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..12c4a4a83dcf134c196b3f28cf1cf5d258a1b3b2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/macie2/2020-01-01/waiters-2.json @@ -0,0 +1,25 @@ +{ + "version": 2, + "waiters": { + "FindingRevealed": { + "description": "Wait until the sensitive data occurrences are ready.", + "delay": 2, + "maxAttempts": 60, + "operation": "GetSensitiveDataOccurrences", + "acceptors": [ + { + "matcher": "path", + "argument": "status", + "state": "success", + "expected": "SUCCESS" + }, + { + "matcher": "path", + "argument": "status", + "state": "success", + "expected": "ERROR" + } + ] + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/mailmanager/2023-10-17/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/mailmanager/2023-10-17/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..a87e9682926a2adde26fcf304591d153e68ff286 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/mailmanager/2023-10-17/paginators-1.json @@ -0,0 +1,76 @@ +{ + "pagination": { + "ListAddonInstances": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "AddonInstances" + }, + "ListAddonSubscriptions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "AddonSubscriptions" + }, + "ListArchiveExports": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "Exports" + }, + "ListArchiveSearches": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "Searches" + }, + "ListArchives": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "Archives" + }, + "ListIngressPoints": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "IngressPoints" + }, + "ListRelays": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "Relays" + }, + "ListRuleSets": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "RuleSets" + }, + "ListTrafficPolicies": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "TrafficPolicies" + }, + "ListAddressListImportJobs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "ImportJobs" + }, + "ListAddressLists": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "AddressLists" + }, + "ListMembersOfAddressList": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "Addresses" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/mailmanager/2023-10-17/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/mailmanager/2023-10-17/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/mailmanager/2023-10-17/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/managedblockchain/2018-09-24/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/managedblockchain/2018-09-24/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/managedblockchain/2018-09-24/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/managedblockchain/2018-09-24/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/managedblockchain/2018-09-24/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..8d30a03f857b42ad9ee17777140046a4b9b64005 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/managedblockchain/2018-09-24/paginators-1.json @@ -0,0 +1,10 @@ +{ + "pagination": { + "ListAccessors": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Accessors" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/marketplace-catalog/2018-09-17/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/marketplace-catalog/2018-09-17/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/marketplace-catalog/2018-09-17/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/marketplace-catalog/2018-09-17/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/marketplace-catalog/2018-09-17/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..8bbef9687db707add5191dc534eeeac8f855334a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/marketplace-catalog/2018-09-17/paginators-1.json @@ -0,0 +1,16 @@ +{ + "pagination": { + "ListChangeSets": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ChangeSetSummaryList" + }, + "ListEntities": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "EntitySummaryList" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/marketplace-deployment/2023-01-25/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/marketplace-deployment/2023-01-25/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/marketplace-deployment/2023-01-25/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/marketplace-entitlement/2017-01-11/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/marketplace-entitlement/2017-01-11/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/marketplace-entitlement/2017-01-11/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/marketplace-entitlement/2017-01-11/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/marketplace-entitlement/2017-01-11/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..8dbf525ed1f7c972fce43756635c5d9cf2b7afaa --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/marketplace-entitlement/2017-01-11/paginators-1.json @@ -0,0 +1,10 @@ +{ + "pagination": { + "GetEntitlements": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Entitlements" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/marketplace-reporting/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/marketplace-reporting/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/marketplace-reporting/2018-05-10/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/marketplace-reporting/2018-05-10/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/marketplace-reporting/2018-05-10/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/marketplace-reporting/2018-05-10/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/mediaconvert/2017-08-29/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/mediaconvert/2017-08-29/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..1f93efd8f9b11f375506f74c8e783a7d6ad1b9a9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/mediaconvert/2017-08-29/paginators-1.json @@ -0,0 +1,46 @@ +{ + "pagination": { + "DescribeEndpoints": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Endpoints" + }, + "ListJobs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Jobs" + }, + "ListPresets": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Presets" + }, + "ListJobTemplates": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "JobTemplates" + }, + "ListQueues": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Queues" + }, + "SearchJobs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Jobs" + }, + "ListVersions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Versions" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/mediaconvert/2017-08-29/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/mediaconvert/2017-08-29/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..c1219900be77ab120e4fcc56bc586fd4e21b9682 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/mediaconvert/2017-08-29/paginators-1.sdk-extras.json @@ -0,0 +1,13 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "ListQueues": { + "non_aggregate_keys": [ + "TotalConcurrentJobs", + "UnallocatedConcurrentJobs" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/medialive/2017-10-14/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/medialive/2017-10-14/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..2a60014ad926cb273bc76f3e29a5dabe3a329e7e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/medialive/2017-10-14/paginators-1.json @@ -0,0 +1,142 @@ +{ + "pagination": { + "ListInputs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Inputs" + }, + "ListChannels": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Channels" + }, + "ListInputSecurityGroups": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "InputSecurityGroups" + }, + "ListOfferings": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Offerings" + }, + "ListReservations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Reservations" + }, + "DescribeSchedule": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ScheduleActions" + }, + "ListMultiplexPrograms": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "MultiplexPrograms" + }, + "ListMultiplexes": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Multiplexes" + }, + "ListInputDevices": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "InputDevices" + }, + "ListInputDeviceTransfers": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "InputDeviceTransfers" + }, + "ListSignalMaps": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "SignalMaps" + }, + "ListCloudWatchAlarmTemplates": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "CloudWatchAlarmTemplates" + }, + "ListCloudWatchAlarmTemplateGroups": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "CloudWatchAlarmTemplateGroups" + }, + "ListEventBridgeRuleTemplates": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "EventBridgeRuleTemplates" + }, + "ListEventBridgeRuleTemplateGroups": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "EventBridgeRuleTemplateGroups" + }, + "ListNodes": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Nodes" + }, + "ListClusters": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Clusters" + }, + "ListChannelPlacementGroups": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ChannelPlacementGroups" + }, + "ListNetworks": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Networks" + }, + "ListSdiSources": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "SdiSources" + }, + "ListAlerts": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Alerts" + }, + "ListClusterAlerts": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Alerts" + }, + "ListMultiplexAlerts": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Alerts" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/medialive/2017-10-14/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/medialive/2017-10-14/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..d95e09abe9f25236430853f7eaaf11f9c1232e69 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/medialive/2017-10-14/waiters-2.json @@ -0,0 +1,624 @@ +{ + "version": 2, + "waiters": { + "ChannelCreated": { + "description": "Wait until a channel has been created", + "operation": "DescribeChannel", + "delay": 3, + "maxAttempts": 5, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "IDLE" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "CREATING" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + }, + { + "state": "failure", + "matcher": "path", + "argument": "State", + "expected": "CREATE_FAILED" + } + ] + }, + "ChannelRunning": { + "description": "Wait until a channel is running", + "operation": "DescribeChannel", + "delay": 5, + "maxAttempts": 120, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "RUNNING" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "STARTING" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + } + ] + }, + "ChannelStopped": { + "description": "Wait until a channel has is stopped", + "operation": "DescribeChannel", + "delay": 5, + "maxAttempts": 60, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "IDLE" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "STOPPING" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + } + ] + }, + "ChannelDeleted": { + "description": "Wait until a channel has been deleted", + "operation": "DescribeChannel", + "delay": 5, + "maxAttempts": 84, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "DELETED" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "DELETING" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + } + ] + }, + "InputAttached": { + "description": "Wait until an input has been attached", + "operation": "DescribeInput", + "delay": 5, + "maxAttempts": 20, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "ATTACHED" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "DETACHED" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + } + ] + }, + "InputDetached": { + "description": "Wait until an input has been detached", + "operation": "DescribeInput", + "delay": 5, + "maxAttempts": 84, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "DETACHED" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "CREATING" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "ATTACHED" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + } + ] + }, + "InputDeleted": { + "description": "Wait until an input has been deleted", + "operation": "DescribeInput", + "delay": 5, + "maxAttempts": 20, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "DELETED" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "DELETING" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + } + ] + }, + "MultiplexCreated": { + "description": "Wait until a multiplex has been created", + "operation": "DescribeMultiplex", + "delay": 3, + "maxAttempts": 5, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "IDLE" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "CREATING" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + }, + { + "state": "failure", + "matcher": "path", + "argument": "State", + "expected": "CREATE_FAILED" + } + ] + }, + "MultiplexRunning": { + "description": "Wait until a multiplex is running", + "operation": "DescribeMultiplex", + "delay": 5, + "maxAttempts": 120, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "RUNNING" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "STARTING" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + } + ] + }, + "MultiplexStopped": { + "description": "Wait until a multiplex has is stopped", + "operation": "DescribeMultiplex", + "delay": 5, + "maxAttempts": 28, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "IDLE" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "STOPPING" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + } + ] + }, + "MultiplexDeleted": { + "description": "Wait until a multiplex has been deleted", + "operation": "DescribeMultiplex", + "delay": 5, + "maxAttempts": 20, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "DELETED" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "DELETING" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + } + ] + }, + "SignalMapCreated": { + "description": "Wait until a signal map has been created", + "delay": 5, + "maxAttempts": 60, + "operation": "GetSignalMap", + "acceptors": [ + { + "matcher": "path", + "argument": "Status", + "state": "success", + "expected": "CREATE_COMPLETE" + }, + { + "matcher": "path", + "argument": "Status", + "state": "retry", + "expected": "CREATE_IN_PROGRESS" + }, + { + "matcher": "path", + "argument": "Status", + "state": "failure", + "expected": "CREATE_FAILED" + } + ] + }, + "SignalMapMonitorDeleted": { + "description": "Wait until a signal map's monitor has been deleted", + "delay": 5, + "maxAttempts": 120, + "operation": "GetSignalMap", + "acceptors": [ + { + "matcher": "path", + "argument": "MonitorDeployment.Status", + "state": "success", + "expected": "DELETE_COMPLETE" + }, + { + "matcher": "path", + "argument": "MonitorDeployment.Status", + "state": "retry", + "expected": "DELETE_IN_PROGRESS" + }, + { + "matcher": "path", + "argument": "MonitorDeployment.Status", + "state": "failure", + "expected": "DELETE_FAILED" + } + ] + }, + "SignalMapMonitorDeployed": { + "description": "Wait until a signal map's monitor has been deployed", + "delay": 5, + "maxAttempts": 120, + "operation": "GetSignalMap", + "acceptors": [ + { + "matcher": "path", + "argument": "MonitorDeployment.Status", + "state": "success", + "expected": "DRY_RUN_DEPLOYMENT_COMPLETE" + }, + { + "matcher": "path", + "argument": "MonitorDeployment.Status", + "state": "success", + "expected": "DEPLOYMENT_COMPLETE" + }, + { + "matcher": "path", + "argument": "MonitorDeployment.Status", + "state": "retry", + "expected": "DRY_RUN_DEPLOYMENT_IN_PROGRESS" + }, + { + "matcher": "path", + "argument": "MonitorDeployment.Status", + "state": "retry", + "expected": "DEPLOYMENT_IN_PROGRESS" + }, + { + "matcher": "path", + "argument": "MonitorDeployment.Status", + "state": "failure", + "expected": "DRY_RUN_DEPLOYMENT_FAILED" + }, + { + "matcher": "path", + "argument": "MonitorDeployment.Status", + "state": "failure", + "expected": "DEPLOYMENT_FAILED" + } + ] + }, + "SignalMapUpdated": { + "description": "Wait until a signal map has been updated", + "delay": 5, + "maxAttempts": 60, + "operation": "GetSignalMap", + "acceptors": [ + { + "matcher": "path", + "argument": "Status", + "state": "success", + "expected": "UPDATE_COMPLETE" + }, + { + "matcher": "path", + "argument": "Status", + "state": "retry", + "expected": "UPDATE_IN_PROGRESS" + }, + { + "matcher": "path", + "argument": "Status", + "state": "failure", + "expected": "UPDATE_FAILED" + }, + { + "matcher": "path", + "argument": "Status", + "state": "failure", + "expected": "UPDATE_REVERTED" + } + ] + }, + "ClusterCreated": { + "description": "Wait until a cluster has been created", + "operation": "DescribeCluster", + "delay": 3, + "maxAttempts": 5, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "ACTIVE" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "CREATING" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + }, + { + "state": "failure", + "matcher": "path", + "argument": "State", + "expected": "CREATE_FAILED" + } + ] + }, + "ClusterDeleted": { + "description": "Wait until a cluster has been deleted", + "operation": "DescribeCluster", + "delay": 5, + "maxAttempts": 20, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "DELETED" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "DELETING" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + } + ] + }, + "NodeRegistered": { + "description": "Wait until a node has been registered", + "operation": "DescribeNode", + "delay": 3, + "maxAttempts": 5, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "ACTIVE" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "REGISTERING" + }, + { + "state": "retry", + "matcher": "status", + "expected": 404 + }, + { + "state": "failure", + "matcher": "path", + "argument": "State", + "expected": "REGISTRATION_FAILED" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + } + ] + }, + "NodeDeregistered": { + "description": "Wait until a node has been deregistered", + "operation": "DescribeNode", + "delay": 5, + "maxAttempts": 20, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "DEREGISTERED" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "DEREGISTERING" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "DRAINING" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + } + ] + }, + "ChannelPlacementGroupAssigned": { + "description": "Wait until the channel placement group has been assigned", + "operation": "DescribeChannelPlacementGroup", + "delay": 3, + "maxAttempts": 5, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "ASSIGNED" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "ASSIGNING" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + } + ] + }, + "ChannelPlacementGroupUnassigned": { + "description": "Wait until the channel placement group has been unassigned", + "operation": "DescribeChannelPlacementGroup", + "delay": 5, + "maxAttempts": 20, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "UNASSIGNED" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "UNASSIGNING" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + } + ] + }, + "ChannelPlacementGroupDeleted": { + "description": "Wait until the channel placement group has been deleted", + "operation": "DescribeChannelPlacementGroup", + "delay": 5, + "maxAttempts": 20, + "acceptors": [ + { + "state": "success", + "matcher": "path", + "argument": "State", + "expected": "DELETED" + }, + { + "state": "retry", + "matcher": "path", + "argument": "State", + "expected": "DELETING" + }, + { + "state": "retry", + "matcher": "status", + "expected": 500 + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/mediastore/2017-09-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/mediastore/2017-09-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/mediastore/2017-09-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/mediastore/2017-09-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/mediastore/2017-09-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ed3ece022c416ed7bf13d4d975580c47c87c2b84 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/mediastore/2017-09-01/paginators-1.json @@ -0,0 +1,10 @@ +{ + "pagination": { + "ListContainers": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Containers" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/mediatailor/2018-04-23/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/mediatailor/2018-04-23/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..fe39ff81f7f97e42f910d5b5becd21447de3f581 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/mediatailor/2018-04-23/paginators-1.json @@ -0,0 +1,52 @@ +{ + "pagination": { + "ListPlaybackConfigurations": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Items" + }, + "GetChannelSchedule": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Items" + }, + "ListChannels": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Items" + }, + "ListSourceLocations": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Items" + }, + "ListVodSources": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Items" + }, + "ListAlerts": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Items" + }, + "ListPrefetchSchedules": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Items" + }, + "ListLiveSources": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/migrationhubstrategy/2020-02-19/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/migrationhubstrategy/2020-02-19/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/migrationhubstrategy/2020-02-19/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/migrationhubstrategy/2020-02-19/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/migrationhubstrategy/2020-02-19/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..889a45ef3b127e80a981e4d00024fef36dc17aca --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/migrationhubstrategy/2020-02-19/paginators-1.json @@ -0,0 +1,40 @@ +{ + "pagination": { + "GetServerDetails": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "associatedApplications" + }, + "ListApplicationComponents": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "applicationComponentInfos" + }, + "ListCollectors": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "Collectors" + }, + "ListImportFileTask": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "taskInfos" + }, + "ListServers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "serverInfos" + }, + "ListAnalyzableServers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "analyzableServers" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/migrationhubstrategy/2020-02-19/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/migrationhubstrategy/2020-02-19/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..2524463ac8ad31bb0e2fdd30cf4490f2262681cc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/migrationhubstrategy/2020-02-19/paginators-1.sdk-extras.json @@ -0,0 +1,12 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "GetServerDetails": { + "non_aggregate_keys": [ + "serverDetail" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/mq/2017-11-27/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/mq/2017-11-27/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..55160732c0cf610c3aae04c2090bbcb9974a408f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/mq/2017-11-27/paginators-1.json @@ -0,0 +1,10 @@ +{ + "pagination": { + "ListBrokers": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "BrokerSummaries" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/mturk/2017-01-17/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/mturk/2017-01-17/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/mturk/2017-01-17/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/mturk/2017-01-17/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/mturk/2017-01-17/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea50caccaaac1622d9584bf50d076caa737aada9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/mturk/2017-01-17/paginators-1.json @@ -0,0 +1,58 @@ +{ + "pagination": { + "ListAssignmentsForHIT": { + "result_key": "Assignments", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "ListQualificationTypes": { + "result_key": "QualificationTypes", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "ListHITs": { + "result_key": "HITs", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "ListWorkerBlocks": { + "result_key": "WorkerBlocks", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "ListReviewableHITs": { + "result_key": "HITs", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "ListHITsForQualificationType": { + "result_key": "HITs", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "ListQualificationRequests": { + "result_key": "QualificationRequests", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "ListWorkersWithQualificationType": { + "result_key": "Qualifications", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "ListBonusPayments": { + "result_key": "BonusPayments", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/network-firewall/2020-11-12/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/network-firewall/2020-11-12/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/network-firewall/2020-11-12/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/network-firewall/2020-11-12/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/network-firewall/2020-11-12/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..66d35f2d1d3bbe0ecf4e953d05634c38e0d3e91f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/network-firewall/2020-11-12/paginators-1.json @@ -0,0 +1,82 @@ +{ + "pagination": { + "ListFirewallPolicies": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "FirewallPolicies" + }, + "ListFirewalls": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Firewalls" + }, + "ListRuleGroups": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "RuleGroups" + }, + "ListTagsForResource": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Tags" + }, + "ListTLSInspectionConfigurations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "TLSInspectionConfigurations" + }, + "GetAnalysisReportResults": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "AnalysisReportResults" + }, + "ListAnalysisReports": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "AnalysisReports" + }, + "ListFlowOperationResults": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Flows" + }, + "ListFlowOperations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "FlowOperations" + }, + "ListVpcEndpointAssociations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "VpcEndpointAssociations" + }, + "ListProxies": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Proxies" + }, + "ListProxyConfigurations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ProxyConfigurations" + }, + "ListProxyRuleGroups": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ProxyRuleGroups" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/network-firewall/2020-11-12/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/network-firewall/2020-11-12/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..a0bc4ffd2a170aa0b41464434a341c72d5864bd6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/network-firewall/2020-11-12/paginators-1.sdk-extras.json @@ -0,0 +1,28 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "GetAnalysisReportResults": { + "non_aggregate_keys": [ + "EndTime", + "ReportTime", + "Status", + "AnalysisType", + "StartTime" + ] + }, + "ListFlowOperationResults": { + "non_aggregate_keys": [ + "FirewallArn", + "FlowOperationId", + "AvailabilityZone", + "FlowOperationStatus", + "FlowRequestTimestamp", + "StatusMessage", + "VpcEndpointAssociationArn", + "VpcEndpointId" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/oam/2022-06-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/oam/2022-06-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..3595f00983f127db3e94c40baf5dddf8ff3b565d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/oam/2022-06-10/paginators-1.json @@ -0,0 +1,22 @@ +{ + "pagination": { + "ListAttachedLinks": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListLinks": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + }, + "ListSinks": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/odb/2024-08-20/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/odb/2024-08-20/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..6bda94b16e8e9098ec6b1133537681999635e14c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/odb/2024-08-20/paginators-1.json @@ -0,0 +1,70 @@ +{ + "pagination": { + "ListAutonomousVirtualMachines": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "autonomousVirtualMachines" + }, + "ListCloudAutonomousVmClusters": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "cloudAutonomousVmClusters" + }, + "ListCloudExadataInfrastructures": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "cloudExadataInfrastructures" + }, + "ListCloudVmClusters": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "cloudVmClusters" + }, + "ListDbNodes": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "dbNodes" + }, + "ListDbServers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "dbServers" + }, + "ListDbSystemShapes": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "dbSystemShapes" + }, + "ListGiVersions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "giVersions" + }, + "ListOdbNetworks": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "odbNetworks" + }, + "ListOdbPeeringConnections": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "odbPeeringConnections" + }, + "ListSystemVersions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "systemVersions" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/odb/2024-08-20/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/odb/2024-08-20/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/odb/2024-08-20/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/organizations/2016-11-28/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/organizations/2016-11-28/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..8e39290e0838b22ff79a0fed94d293de6f9b220a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/organizations/2016-11-28/examples-1.json @@ -0,0 +1,1409 @@ +{ + "version": "1.0", + "examples": { + "AcceptHandshake": [ + { + "input": { + "HandshakeId": "h-examplehandshakeid111" + }, + "output": { + "Handshake": { + "Action": "INVITE", + "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/invite/h-examplehandshakeid111", + "ExpirationTimestamp": "20170228T1215Z", + "Id": "h-examplehandshakeid111", + "Parties": [ + { + "Id": "o-exampleorgid", + "Type": "ORGANIZATION" + }, + { + "Id": "juan@example.com", + "Type": "EMAIL" + } + ], + "RequestedTimestamp": "20170214T1215Z", + "Resources": [ + { + "Resources": [ + { + "Type": "MASTER_EMAIL", + "Value": "bill@amazon.com" + }, + { + "Type": "MASTER_NAME", + "Value": "Org Master Account" + }, + { + "Type": "ORGANIZATION_FEATURE_SET", + "Value": "ALL" + } + ], + "Type": "ORGANIZATION", + "Value": "o-exampleorgid" + }, + { + "Type": "ACCOUNT", + "Value": "222222222222" + } + ], + "State": "ACCEPTED" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Bill is the owner of an organization, and he invites Juan's account (222222222222) to join his organization. The following example shows Juan's account accepting the handshake and thus agreeing to the invitation.", + "id": "to-accept-a-handshake-from-another-account-1472500561150", + "title": "To accept a handshake from another account" + } + ], + "AttachPolicy": [ + { + "input": { + "PolicyId": "p-examplepolicyid111", + "TargetId": "ou-examplerootid111-exampleouid111" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to attach a service control policy (SCP) to an OU:\n", + "id": "to-attach-a-policy-to-an-ou", + "title": "To attach a policy to an OU" + }, + { + "input": { + "PolicyId": "p-examplepolicyid111", + "TargetId": "333333333333" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to attach a service control policy (SCP) to an account:\n", + "id": "to-attach-a-policy-to-an-account", + "title": "To attach a policy to an account" + } + ], + "CancelHandshake": [ + { + "input": { + "HandshakeId": "h-examplehandshakeid111" + }, + "output": { + "Handshake": { + "Action": "INVITE", + "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/invite/h-examplehandshakeid111", + "ExpirationTimestamp": "20170228T1215Z", + "Id": "h-examplehandshakeid111", + "Parties": [ + { + "Id": "o-exampleorgid", + "Type": "ORGANIZATION" + }, + { + "Id": "susan@example.com", + "Type": "EMAIL" + } + ], + "RequestedTimestamp": "20170214T1215Z", + "Resources": [ + { + "Resources": [ + { + "Type": "MASTER_EMAIL", + "Value": "bill@example.com" + }, + { + "Type": "MASTER_NAME", + "Value": "Master Account" + }, + { + "Type": "ORGANIZATION_FEATURE_SET", + "Value": "CONSOLIDATED_BILLING" + } + ], + "Type": "ORGANIZATION", + "Value": "o-exampleorgid" + }, + { + "Type": "ACCOUNT", + "Value": "222222222222" + }, + { + "Type": "NOTES", + "Value": "This is a request for Susan's account to join Bob's organization." + } + ], + "State": "CANCELED" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Bill previously sent an invitation to Susan's account to join his organization. He changes his mind and decides to cancel the invitation before Susan accepts it. The following example shows Bill's cancellation:\n", + "id": "to-cancel-a-handshake-sent-to-a-member-account-1472501320506", + "title": "To cancel a handshake sent to a member account" + } + ], + "CreateAccount": [ + { + "input": { + "AccountName": "Production Account", + "Email": "susan@example.com" + }, + "output": { + "CreateAccountStatus": { + "Id": "car-examplecreateaccountrequestid111", + "State": "IN_PROGRESS" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The owner of an organization creates a member account in the organization. The following example shows that when the organization owner creates the member account, the account is preconfigured with the name \"Production Account\" and an owner email address of susan@example.com. An IAM role is automatically created using the default name because the roleName parameter is not used. AWS Organizations sends Susan a \"Welcome to AWS\" email:\n\n", + "id": "to-create-a-new-account-that-is-automatically-part-of-the-organization-1472501463507", + "title": "To create a new account that is automatically part of the organization" + } + ], + "CreateOrganization": [ + { + "input": { + }, + "output": { + "Organization": { + "Arn": "arn:aws:organizations::111111111111:organization/o-exampleorgid", + "AvailablePolicyTypes": [ + { + "Status": "ENABLED", + "Type": "SERVICE_CONTROL_POLICY" + } + ], + "FeatureSet": "ALL", + "Id": "o-exampleorgid", + "MasterAccountArn": "arn:aws:organizations::111111111111:account/o-exampleorgid/111111111111", + "MasterAccountEmail": "bill@example.com", + "MasterAccountId": "111111111111" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Bill wants to create an organization using credentials from account 111111111111. The following example shows that the account becomes the master account in the new organization. Because he does not specify a feature set, the new organization defaults to all features enabled and service control policies enabled on the root:\n\n", + "id": "to-create-a-new-organization-with-all-features enabled", + "title": "To create a new organization with all features enabled" + }, + { + "input": { + "FeatureSet": "CONSOLIDATED_BILLING" + }, + "output": { + "Organization": { + "Arn": "arn:aws:organizations::111111111111:organization/o-exampleorgid", + "AvailablePolicyTypes": [ + + ], + "FeatureSet": "CONSOLIDATED_BILLING", + "Id": "o-exampleorgid", + "MasterAccountArn": "arn:aws:organizations::111111111111:account/o-exampleorgid/111111111111", + "MasterAccountEmail": "bill@example.com", + "MasterAccountId": "111111111111" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "In the following example, Bill creates an organization using credentials from account 111111111111, and configures the organization to support only the consolidated billing feature set:\n\n", + "id": "to-create-a-new-organization-with-consolidated-billing-features-only", + "title": "To create a new organization with consolidated billing features only" + } + ], + "CreateOrganizationalUnit": [ + { + "input": { + "Name": "AccountingOU", + "ParentId": "r-examplerootid111" + }, + "output": { + "OrganizationalUnit": { + "Arn": "arn:aws:organizations::111111111111:ou/o-exampleorgid/ou-examplerootid111-exampleouid111", + "Id": "ou-examplerootid111-exampleouid111", + "Name": "AccountingOU" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to create an OU that is named AccountingOU. The new OU is directly under the root.:\n\n", + "id": "to-create-a-new-organizational-unit", + "title": "To create a new organization unit" + } + ], + "CreatePolicy": [ + { + "input": { + "Content": "{\\\"Version\\\":\\\"2012-10-17\\\",\\\"Statement\\\":{\\\"Effect\\\":\\\"Allow\\\",\\\"Action\\\":\\\"s3:*\\\"}}", + "Description": "Enables admins of attached accounts to delegate all S3 permissions", + "Name": "AllowAllS3Actions", + "Type": "SERVICE_CONTROL_POLICY" + }, + "output": { + "Policy": { + "Content": "{\"Version\":\"2012-10-17\",\"Statement\":{\"Effect\":\"Allow\",\"Action\":\"s3:*\"}}", + "PolicySummary": { + "Arn": "arn:aws:organizations::111111111111:policy/o-exampleorgid/service_control_policy/p-examplepolicyid111", + "Description": "Allows delegation of all S3 actions", + "Name": "AllowAllS3Actions", + "Type": "SERVICE_CONTROL_POLICY" + } + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to create a service control policy (SCP) that is named AllowAllS3Actions. The JSON string in the content parameter specifies the content in the policy. The parameter string is escaped with backslashes to ensure that the embedded double quotes in the JSON policy are treated as literals in the parameter, which itself is surrounded by double quotes:\n\n", + "id": "to-create-a-service-control-policy", + "title": "To create a service control policy" + } + ], + "DeclineHandshake": [ + { + "input": { + "HandshakeId": "h-examplehandshakeid111" + }, + "output": { + "Handshake": { + "Action": "INVITE", + "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/invite/h-examplehandshakeid111", + "ExpirationTimestamp": "2016-12-15T19:27:58Z", + "Id": "h-examplehandshakeid111", + "Parties": [ + { + "Id": "222222222222", + "Type": "ACCOUNT" + }, + { + "Id": "o-exampleorgid", + "Type": "ORGANIZATION" + } + ], + "RequestedTimestamp": "2016-11-30T19:27:58Z", + "Resources": [ + { + "Resources": [ + { + "Type": "MASTER_EMAIL", + "Value": "bill@example.com" + }, + { + "Type": "MASTER_NAME", + "Value": "Master Account" + } + ], + "Type": "ORGANIZATION", + "Value": "o-exampleorgid" + }, + { + "Type": "ACCOUNT", + "Value": "222222222222" + }, + { + "Type": "NOTES", + "Value": "This is an invitation to Susan's account to join the Bill's organization." + } + ], + "State": "DECLINED" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows Susan declining an invitation to join Bill's organization. The DeclineHandshake operation returns a handshake object, showing that the state is now DECLINED:", + "id": "to-decline-a-handshake-sent-from-the-master-account-1472502666967", + "title": "To decline a handshake sent from the master account" + } + ], + "DeleteOrganizationalUnit": [ + { + "input": { + "OrganizationalUnitId": "ou-examplerootid111-exampleouid111" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to delete an OU. The example assumes that you previously removed all accounts and other OUs from the OU:\n\n", + "id": "to-delete-an-organizational-unit", + "title": "To delete an organization unit" + } + ], + "DeletePolicy": [ + { + "input": { + "PolicyId": "p-examplepolicyid111" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to delete a policy from an organization. The example assumes that you previously detached the policy from all entities:\n\n", + "id": "to-delete-a-policy", + "title": "To delete a policy" + } + ], + "DescribeAccount": [ + { + "input": { + "AccountId": "555555555555" + }, + "output": { + "Account": { + "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/555555555555", + "Email": "anika@example.com", + "Id": "555555555555", + "Name": "Beta Account" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows a user in the master account (111111111111) asking for details about account 555555555555:", + "id": "to-get-the-details-about-an-account-1472503166868", + "title": "To get the details about an account" + } + ], + "DescribeCreateAccountStatus": [ + { + "input": { + "CreateAccountRequestId": "car-exampleaccountcreationrequestid" + }, + "output": { + "CreateAccountStatus": { + "AccountId": "333333333333", + "Id": "car-exampleaccountcreationrequestid", + "State": "SUCCEEDED" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to request the status about a previous request to create an account in an organization. This operation can be called only by a principal from the organization's master account. In the example, the specified \"createAccountRequestId\" comes from the response of the original call to \"CreateAccount\":", + "id": "to-get-information-about-a-request-to-create-an-account-1472503727223", + "title": "To get information about a request to create an account" + } + ], + "DescribeHandshake": [ + { + "input": { + "HandshakeId": "h-examplehandshakeid111" + }, + "output": { + "Handshake": { + "Action": "INVITE", + "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/invite/h-examplehandshakeid111", + "ExpirationTimestamp": "2016-11-30T17:24:58.046Z", + "Id": "h-examplehandshakeid111", + "Parties": [ + { + "Id": "o-exampleorgid", + "Type": "ORGANIZATION" + }, + { + "Id": "333333333333", + "Type": "ACCOUNT" + } + ], + "RequestedTimestamp": "2016-11-30T17:24:58.046Z", + "Resources": [ + { + "Resources": [ + { + "Type": "MASTER_EMAIL", + "Value": "bill@example.com" + }, + { + "Type": "MASTER_NAME", + "Value": "Master Account" + } + ], + "Type": "ORGANIZATION", + "Value": "o-exampleorgid" + }, + { + "Type": "ACCOUNT", + "Value": "333333333333" + } + ], + "State": "OPEN" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows you how to request details about a handshake. The handshake ID comes either from the original call to \"InviteAccountToOrganization\", or from a call to \"ListHandshakesForAccount\" or \"ListHandshakesForOrganization\":", + "id": "to-get-information-about-a-handshake-1472503400505", + "title": "To get information about a handshake" + } + ], + "DescribeOrganization": [ + { + "output": { + "Organization": { + "Arn": "arn:aws:organizations::111111111111:organization/o-exampleorgid", + "AvailablePolicyTypes": [ + { + "Status": "ENABLED", + "Type": "SERVICE_CONTROL_POLICY" + } + ], + "FeatureSet": "ALL", + "Id": "o-exampleorgid", + "MasterAccountArn": "arn:aws:organizations::111111111111:account/o-exampleorgid/111111111111", + "MasterAccountEmail": "bill@example.com" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to request information about the current user's organization:/n/n", + "id": "to-get-information-about-an-organization-1472503400505", + "title": "To get information about an organization" + } + ], + "DescribeOrganizationalUnit": [ + { + "input": { + "OrganizationalUnitId": "ou-examplerootid111-exampleouid111" + }, + "output": { + "OrganizationalUnit": { + "Arn": "arn:aws:organizations::111111111111:ou/o-exampleorgid/ou-examplerootid111-exampleouid111", + "Id": "ou-examplerootid111-exampleouid111", + "Name": "Accounting Group" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to request details about an OU:/n/n", + "id": "to-get-information-about-an-organizational-unit", + "title": "To get information about an organizational unit" + } + ], + "DescribePolicy": [ + { + "input": { + "PolicyId": "p-examplepolicyid111" + }, + "output": { + "Policy": { + "Content": "{\\n \\\"Version\\\": \\\"2012-10-17\\\",\\n \\\"Statement\\\": [\\n {\\n \\\"Effect\\\": \\\"Allow\\\",\\n \\\"Action\\\": \\\"*\\\",\\n \\\"Resource\\\": \\\"*\\\"\\n }\\n ]\\n}", + "PolicySummary": { + "Arn": "arn:aws:organizations::111111111111:policy/o-exampleorgid/service_control_policy/p-examplepolicyid111", + "AwsManaged": false, + "Description": "Enables admins to delegate S3 permissions", + "Id": "p-examplepolicyid111", + "Name": "AllowAllS3Actions", + "Type": "SERVICE_CONTROL_POLICY" + } + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to request information about a policy:/n/n", + "id": "to-get-information-about-a-policy", + "title": "To get information about a policy" + } + ], + "DetachPolicy": [ + { + "input": { + "PolicyId": "p-examplepolicyid111", + "TargetId": "ou-examplerootid111-exampleouid111" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to detach a policy from an OU:/n/n", + "id": "to-detach-a-policy-from-a-root-ou-or-account", + "title": "To detach a policy from a root, OU, or account" + } + ], + "DisablePolicyType": [ + { + "input": { + "PolicyType": "SERVICE_CONTROL_POLICY", + "RootId": "r-examplerootid111" + }, + "output": { + "Root": { + "Arn": "arn:aws:organizations::111111111111:root/o-exampleorgid/r-examplerootid111", + "Id": "r-examplerootid111", + "Name": "Root", + "PolicyTypes": [ + + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to disable the service control policy (SCP) policy type in a root. The response shows that the PolicyTypes response element no longer includes SERVICE_CONTROL_POLICY:/n/n", + "id": "to-disable-a-policy-type-in-a-root", + "title": "To disable a policy type in a root" + } + ], + "EnableAllFeatures": [ + { + "input": { + }, + "output": { + "Handshake": { + "Action": "ENABLE_ALL_FEATURES", + "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/enable_all_features/h-examplehandshakeid111", + "ExpirationTimestamp": "2017-02-28T09:35:40.05Z", + "Id": "h-examplehandshakeid111", + "Parties": [ + { + "Id": "o-exampleorgid", + "Type": "ORGANIZATION" + } + ], + "RequestedTimestamp": "2017-02-13T09:35:40.05Z", + "Resources": [ + { + "Type": "ORGANIZATION", + "Value": "o-exampleorgid" + } + ], + "State": "REQUESTED" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example shows the administrator asking all the invited accounts in the organization to approve enabling all features in the organization. AWS Organizations sends an email to the address that is registered with every invited member account asking the owner to approve the change by accepting the handshake that is sent. After all invited member accounts accept the handshake, the organization administrator can finalize the change to enable all features, and those with appropriate permissions can create policies and apply them to roots, OUs, and accounts:/n/n", + "id": "to-enable-all-features-in-an-organization", + "title": "To enable all features in an organization" + } + ], + "EnablePolicyType": [ + { + "input": { + "PolicyType": "SERVICE_CONTROL_POLICY", + "RootId": "r-examplerootid111" + }, + "output": { + "Root": { + "Arn": "arn:aws:organizations::111111111111:root/o-exampleorgid/r-examplerootid111", + "Id": "r-examplerootid111", + "Name": "Root", + "PolicyTypes": [ + { + "Status": "ENABLED", + "Type": "SERVICE_CONTROL_POLICY" + } + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to enable the service control policy (SCP) policy type in a root. The output shows a root object with a PolicyTypes response element showing that SCPs are now enabled:/n/n", + "id": "to-enable-a-policy-type-in-a-root", + "title": "To enable a policy type in a root" + } + ], + "InviteAccountToOrganization": [ + { + "input": { + "Notes": "This is a request for Juan's account to join Bill's organization", + "Target": { + "Id": "juan@example.com", + "Type": "EMAIL" + } + }, + "output": { + "Handshake": { + "Action": "INVITE", + "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/invite/h-examplehandshakeid111", + "ExpirationTimestamp": "2017-02-16T09:36:05.02Z", + "Id": "h-examplehandshakeid111", + "Parties": [ + { + "Id": "o-exampleorgid", + "Type": "ORGANIZATION" + }, + { + "Id": "juan@example.com", + "Type": "EMAIL" + } + ], + "RequestedTimestamp": "2017-02-01T09:36:05.02Z", + "Resources": [ + { + "Resources": [ + { + "Type": "MASTER_EMAIL", + "Value": "bill@amazon.com" + }, + { + "Type": "MASTER_NAME", + "Value": "Org Master Account" + }, + { + "Type": "ORGANIZATION_FEATURE_SET", + "Value": "FULL" + } + ], + "Type": "ORGANIZATION", + "Value": "o-exampleorgid" + }, + { + "Type": "EMAIL", + "Value": "juan@example.com" + } + ], + "State": "OPEN" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows the admin of the master account owned by bill@example.com inviting the account owned by juan@example.com to join an organization.", + "id": "to-invite-an-account-to-join-an-organization-1472508594110", + "title": "To invite an account to join an organization" + } + ], + "LeaveOrganization": [ + { + "comments": { + "input": { + }, + "output": { + } + }, + "description": "TThe following example shows how to remove your member account from an organization:", + "id": "to-leave-an-organization-as-a-member-account-1472508784736", + "title": "To leave an organization as a member account" + } + ], + "ListAccounts": [ + { + "input": { + }, + "output": { + "Accounts": [ + { + "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/111111111111", + "Email": "bill@example.com", + "Id": "111111111111", + "JoinedMethod": "INVITED", + "JoinedTimestamp": "20161215T193015Z", + "Name": "Master Account", + "Status": "ACTIVE" + }, + { + "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/222222222222", + "Email": "alice@example.com", + "Id": "222222222222", + "JoinedMethod": "INVITED", + "JoinedTimestamp": "20161215T210221Z", + "Name": "Developer Account", + "Status": "ACTIVE" + }, + { + "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/333333333333", + "Email": "juan@example.com", + "Id": "333333333333", + "JoinedMethod": "INVITED", + "JoinedTimestamp": "20161215T210347Z", + "Name": "Test Account", + "Status": "ACTIVE" + }, + { + "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/444444444444", + "Email": "anika@example.com", + "Id": "444444444444", + "JoinedMethod": "INVITED", + "JoinedTimestamp": "20161215T210332Z", + "Name": "Production Account", + "Status": "ACTIVE" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows you how to request a list of the accounts in an organization:", + "id": "to-retrieve-a-list-of-all-of-the-accounts-in-an-organization-1472509590974", + "title": "To retrieve a list of all of the accounts in an organization" + } + ], + "ListAccountsForParent": [ + { + "input": { + "ParentId": "ou-examplerootid111-exampleouid111" + }, + "output": { + "Accounts": [ + { + "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/333333333333", + "Email": "juan@example.com", + "Id": "333333333333", + "JoinedMethod": "INVITED", + "JoinedTimestamp": 1481835795.536, + "Name": "Development Account", + "Status": "ACTIVE" + }, + { + "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/444444444444", + "Email": "anika@example.com", + "Id": "444444444444", + "JoinedMethod": "INVITED", + "JoinedTimestamp": 1481835812.143, + "Name": "Test Account", + "Status": "ACTIVE" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to request a list of the accounts in an OU:/n/n", + "id": "to-retrieve-a-list-of-all-of-the-accounts-in-a-root-or-ou-1472509590974", + "title": "To retrieve a list of all of the accounts in a root or OU" + } + ], + "ListChildren": [ + { + "input": { + "ChildType": "ORGANIZATIONAL_UNIT", + "ParentId": "ou-examplerootid111-exampleouid111" + }, + "output": { + "Children": [ + { + "Id": "ou-examplerootid111-exampleouid111", + "Type": "ORGANIZATIONAL_UNIT" + }, + { + "Id": "ou-examplerootid111-exampleouid222", + "Type": "ORGANIZATIONAL_UNIT" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to request a list of the child OUs in a parent root or OU:/n/n", + "id": "to-retrieve-a-list-of-all-of-the-child-accounts-and-OUs-in-a-parent-container", + "title": "To retrieve a list of all of the child accounts and OUs in a parent root or OU" + } + ], + "ListCreateAccountStatus": [ + { + "input": { + "States": [ + "SUCCEEDED" + ] + }, + "output": { + "CreateAccountStatuses": [ + { + "AccountId": "444444444444", + "AccountName": "Developer Test Account", + "CompletedTimestamp": "2017-01-15T13:45:23.6Z", + "Id": "car-exampleaccountcreationrequestid1", + "RequestedTimestamp": "2017-01-15T13:45:23.01Z", + "State": "SUCCEEDED" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows a user requesting a list of only the completed account creation requests made for the current organization:", + "id": "to-get-a-list-of-completed-account-creation-requests-made-in-the-organization", + "title": "To get a list of completed account creation requests made in the organization" + }, + { + "input": { + "States": [ + "IN_PROGRESS" + ] + }, + "output": { + "CreateAccountStatuses": [ + { + "AccountName": "Production Account", + "Id": "car-exampleaccountcreationrequestid2", + "RequestedTimestamp": "2017-01-15T13:45:23.01Z", + "State": "IN_PROGRESS" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows a user requesting a list of only the in-progress account creation requests made for the current organization:", + "id": "to-get-a-list-of-all-account-creation-requests-made-in-the-organization-1472509174532", + "title": "To get a list of all account creation requests made in the organization" + } + ], + "ListHandshakesForAccount": [ + { + "output": { + "Handshakes": [ + { + "Action": "INVITE", + "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/invite/h-examplehandshakeid111", + "ExpirationTimestamp": "2017-01-28T14:35:23.3Z", + "Id": "h-examplehandshakeid111", + "Parties": [ + { + "Id": "o-exampleorgid", + "Type": "ORGANIZATION" + }, + { + "Id": "juan@example.com", + "Type": "EMAIL" + } + ], + "RequestedTimestamp": "2017-01-13T14:35:23.3Z", + "Resources": [ + { + "Resources": [ + { + "Type": "MASTER_EMAIL", + "Value": "bill@amazon.com" + }, + { + "Type": "MASTER_NAME", + "Value": "Org Master Account" + }, + { + "Type": "ORGANIZATION_FEATURE_SET", + "Value": "FULL" + } + ], + "Type": "ORGANIZATION", + "Value": "o-exampleorgid" + }, + { + "Type": "EMAIL", + "Value": "juan@example.com" + } + ], + "State": "OPEN" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows you how to get a list of handshakes that are associated with the account of the credentials used to call the operation:", + "id": "to-retrieve-a-list-of-the-handshakes-sent-to-an-account-1472510214747", + "title": "To retrieve a list of the handshakes sent to an account" + } + ], + "ListHandshakesForOrganization": [ + { + "output": { + "Handshakes": [ + { + "Action": "INVITE", + "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/invite/h-examplehandshakeid111", + "ExpirationTimestamp": "2017-01-28T14:35:23.3Z", + "Id": "h-examplehandshakeid111", + "Parties": [ + { + "Id": "o-exampleorgid", + "Type": "ORGANIZATION" + }, + { + "Id": "juan@example.com", + "Type": "EMAIL" + } + ], + "RequestedTimestamp": "2017-01-13T14:35:23.3Z", + "Resources": [ + { + "Resources": [ + { + "Type": "MASTER_EMAIL", + "Value": "bill@amazon.com" + }, + { + "Type": "MASTER_NAME", + "Value": "Org Master Account" + }, + { + "Type": "ORGANIZATION_FEATURE_SET", + "Value": "FULL" + } + ], + "Type": "ORGANIZATION", + "Value": "o-exampleorgid" + }, + { + "Type": "EMAIL", + "Value": "juan@example.com" + } + ], + "State": "OPEN" + }, + { + "Action": "INVITE", + "Arn": "arn:aws:organizations::111111111111:handshake/o-exampleorgid/invite/h-examplehandshakeid111", + "ExpirationTimestamp": "2017-01-28T14:35:23.3Z", + "Id": "h-examplehandshakeid222", + "Parties": [ + { + "Id": "o-exampleorgid", + "Type": "ORGANIZATION" + }, + { + "Id": "anika@example.com", + "Type": "EMAIL" + } + ], + "RequestedTimestamp": "2017-01-13T14:35:23.3Z", + "Resources": [ + { + "Resources": [ + { + "Type": "MASTER_EMAIL", + "Value": "bill@example.com" + }, + { + "Type": "MASTER_NAME", + "Value": "Master Account" + } + ], + "Type": "ORGANIZATION", + "Value": "o-exampleorgid" + }, + { + "Type": "EMAIL", + "Value": "anika@example.com" + }, + { + "Type": "NOTES", + "Value": "This is an invitation to Anika's account to join Bill's organization." + } + ], + "State": "ACCEPTED" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows you how to get a list of handshakes associated with the current organization:", + "id": "to-retrieve-a-list-of-the-handshakes-associated-with-an-organization-1472511206653", + "title": "To retrieve a list of the handshakes associated with an organization" + } + ], + "ListOrganizationalUnitsForParent": [ + { + "input": { + "ParentId": "r-examplerootid111" + }, + "output": { + "OrganizationalUnits": [ + { + "Arn": "arn:aws:organizations::111111111111:ou/o-exampleorgid/ou-examlerootid111-exampleouid111", + "Id": "ou-examplerootid111-exampleouid111", + "Name": "Development" + }, + { + "Arn": "arn:aws:organizations::111111111111:ou/o-exampleorgid/ou-examlerootid111-exampleouid222", + "Id": "ou-examplerootid111-exampleouid222", + "Name": "Production" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to get a list of OUs in a specified root:/n/n", + "id": "to-retrieve-a-list-of-all-of-the-OUs-in-a-parent-container", + "title": "To retrieve a list of all of the child OUs in a parent root or OU" + } + ], + "ListParents": [ + { + "input": { + "ChildId": "444444444444" + }, + "output": { + "Parents": [ + { + "Id": "ou-examplerootid111-exampleouid111", + "Type": "ORGANIZATIONAL_UNIT" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to list the root or OUs that contain account 444444444444:/n/n", + "id": "to-retrieve-a-list-of-all-of-the-parents-of-a-child-ou-or-account", + "title": "To retrieve a list of all of the parents of a child OU or account" + } + ], + "ListPolicies": [ + { + "input": { + "Filter": "SERVICE_CONTROL_POLICY" + }, + "output": { + "Policies": [ + { + "Arn": "arn:aws:organizations::111111111111:policy/o-exampleorgid/service_control_policy/p-examplepolicyid111", + "AwsManaged": false, + "Description": "Enables account admins to delegate permissions for any S3 actions to users and roles in their accounts.", + "Id": "p-examplepolicyid111", + "Name": "AllowAllS3Actions", + "Type": "SERVICE_CONTROL_POLICY" + }, + { + "Arn": "arn:aws:organizations::111111111111:policy/o-exampleorgid/service_control_policy/p-examplepolicyid222", + "AwsManaged": false, + "Description": "Enables account admins to delegate permissions for any EC2 actions to users and roles in their accounts.", + "Id": "p-examplepolicyid222", + "Name": "AllowAllEC2Actions", + "Type": "SERVICE_CONTROL_POLICY" + }, + { + "Arn": "arn:aws:organizations::aws:policy/service_control_policy/p-FullAWSAccess", + "AwsManaged": true, + "Description": "Allows access to every operation", + "Id": "p-FullAWSAccess", + "Name": "FullAWSAccess", + "Type": "SERVICE_CONTROL_POLICY" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to get a list of service control policies (SCPs):/n/n", + "id": "to-retrieve-a-list-of--policies-in-the-organization", + "title": "To retrieve a list policies in the organization" + } + ], + "ListPoliciesForTarget": [ + { + "input": { + "Filter": "SERVICE_CONTROL_POLICY", + "TargetId": "444444444444" + }, + "output": { + "Policies": [ + { + "Arn": "arn:aws:organizations::111111111111:policy/o-exampleorgid/service_control_policy/p-examplepolicyid222", + "AwsManaged": false, + "Description": "Enables account admins to delegate permissions for any EC2 actions to users and roles in their accounts.", + "Id": "p-examplepolicyid222", + "Name": "AllowAllEC2Actions", + "Type": "SERVICE_CONTROL_POLICY" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to get a list of all service control policies (SCPs) of the type specified by the Filter parameter, that are directly attached to an account. The returned list does not include policies that apply to the account because of inheritance from its location in an OU hierarchy:/n/n", + "id": "to-retrieve-a-list-of-policies-attached-to-a-root-ou-or-account", + "title": "To retrieve a list policies attached to a root, OU, or account" + } + ], + "ListRoots": [ + { + "input": { + }, + "output": { + "Roots": [ + { + "Arn": "arn:aws:organizations::111111111111:root/o-exampleorgid/r-examplerootid111", + "Id": "r-examplerootid111", + "Name": "Root", + "PolicyTypes": [ + { + "Status": "ENABLED", + "Type": "SERVICE_CONTROL_POLICY" + } + ] + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to get the list of the roots in the current organization:/n/n", + "id": "to-retrieve-a-list-of-roots-in-the-organization", + "title": "To retrieve a list of roots in the organization" + } + ], + "ListTargetsForPolicy": [ + { + "input": { + "PolicyId": "p-FullAWSAccess" + }, + "output": { + "Targets": [ + { + "Arn": "arn:aws:organizations::111111111111:root/o-exampleorgid/r-examplerootid111", + "Name": "Root", + "TargetId": "r-examplerootid111", + "Type": "ROOT" + }, + { + "Arn": "arn:aws:organizations::111111111111:account/o-exampleorgid/333333333333;", + "Name": "Developer Test Account", + "TargetId": "333333333333", + "Type": "ACCOUNT" + }, + { + "Arn": "arn:aws:organizations::111111111111:ou/o-exampleorgid/ou-examplerootid111-exampleouid111", + "Name": "Accounting", + "TargetId": "ou-examplerootid111-exampleouid111", + "Type": "ORGANIZATIONAL_UNIT" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to get the list of roots, OUs, and accounts to which the specified policy is attached:/n/n", + "id": "to-retrieve-a-list-of-roots-ous-and-accounts-to-which-a-policy-is-attached", + "title": "To retrieve a list of roots, OUs, and accounts to which a policy is attached" + } + ], + "MoveAccount": [ + { + "input": { + "AccountId": "333333333333", + "DestinationParentId": "ou-examplerootid111-exampleouid111", + "SourceParentId": "r-examplerootid111" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to move a member account from the root to an OU:/n/n", + "id": "to-move-an-ou-or-account-to-another-ou-or-the-root", + "title": "To move an OU or account to another OU or the root" + } + ], + "RemoveAccountFromOrganization": [ + { + "input": { + "AccountId": "333333333333" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows you how to remove an account from an organization:", + "id": "to-remove-an-account-from-an-organization-as-the-master-account", + "title": "To remove an account from an organization as the master account" + } + ], + "UpdateOrganizationalUnit": [ + { + "input": { + "Name": "AccountingOU", + "OrganizationalUnitId": "ou-examplerootid111-exampleouid111" + }, + "output": { + "OrganizationalUnit": { + "Arn": "arn:aws:organizations::111111111111:ou/o-exampleorgid/ou-examplerootid111-exampleouid111", + "Id": "ou-examplerootid111-exampleouid111", + "Name": "AccountingOU" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to rename an OU. The output confirms the new name:/n/n", + "id": "to-rename-an-organizational-unit", + "title": "To rename an organizational unit" + } + ], + "UpdatePolicy": [ + { + "input": { + "Description": "This description replaces the original.", + "Name": "Renamed-Policy", + "PolicyId": "p-examplepolicyid111" + }, + "output": { + "Policy": { + "Content": "{ \"Version\": \"2012-10-17\", \"Statement\": { \"Effect\": \"Allow\", \"Action\": \"ec2:*\", \"Resource\": \"*\" } }", + "PolicySummary": { + "Arn": "arn:aws:organizations::111111111111:policy/o-exampleorgid/service_control_policy/p-examplepolicyid111", + "AwsManaged": false, + "Description": "This description replaces the original.", + "Id": "p-examplepolicyid111", + "Name": "Renamed-Policy", + "Type": "SERVICE_CONTROL_POLICY" + } + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to rename a policy and give it a new description and new content. The output confirms the new name and description text:/n/n", + "id": "to-update-the-details-of-a-policy", + "title": "To update the details of a policy" + }, + { + "input": { + "Content": "{ \\\"Version\\\": \\\"2012-10-17\\\", \\\"Statement\\\": {\\\"Effect\\\": \\\"Allow\\\", \\\"Action\\\": \\\"s3:*\\\", \\\"Resource\\\": \\\"*\\\" } }", + "PolicyId": "p-examplepolicyid111" + }, + "output": { + "Policy": { + "Content": "{ \\\"Version\\\": \\\"2012-10-17\\\", \\\"Statement\\\": { \\\"Effect\\\": \\\"Allow\\\", \\\"Action\\\": \\\"s3:*\\\", \\\"Resource\\\": \\\"*\\\" } }", + "PolicySummary": { + "Arn": "arn:aws:organizations::111111111111:policy/o-exampleorgid/service_control_policy/p-examplepolicyid111", + "AwsManaged": false, + "Description": "This description replaces the original.", + "Id": "p-examplepolicyid111", + "Name": "Renamed-Policy", + "Type": "SERVICE_CONTROL_POLICY" + } + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to replace the JSON text of the SCP from the preceding example with a new JSON policy text string that allows S3 actions instead of EC2 actions:/n/n", + "id": "to-update-the-content-of-a-policy", + "title": "To update the content of a policy" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/organizations/2016-11-28/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/organizations/2016-11-28/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..7d04f56e5ea4972dc2a4a9825b1a3692134eda76 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/organizations/2016-11-28/paginators-1.json @@ -0,0 +1,111 @@ +{ + "pagination": { + "ListAccounts": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Accounts" + }, + "ListAccountsForParent": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Accounts" + }, + "ListChildren": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Children" + }, + "ListCreateAccountStatus": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "CreateAccountStatuses" + }, + "ListHandshakesForAccount": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Handshakes" + }, + "ListHandshakesForOrganization": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Handshakes" + }, + "ListOrganizationalUnitsForParent": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "OrganizationalUnits" + }, + "ListParents": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Parents" + }, + "ListPolicies": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Policies" + }, + "ListPoliciesForTarget": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Policies" + }, + "ListRoots": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Roots" + }, + "ListTargetsForPolicy": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Targets" + }, + "ListAWSServiceAccessForOrganization": { + "result_key": "EnabledServicePrincipals", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "ListTagsForResource": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Tags" + }, + "ListDelegatedAdministrators": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "DelegatedAdministrators" + }, + "ListDelegatedServicesForAccount": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "DelegatedServices" + }, + "ListAccountsWithInvalidEffectivePolicy": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Accounts" + }, + "ListEffectivePolicyValidationErrors": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "EffectivePolicyValidationErrors" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/organizations/2016-11-28/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/organizations/2016-11-28/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..16e6eaccb8e84c6e903ce61d9767f492d4aa622f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/organizations/2016-11-28/paginators-1.sdk-extras.json @@ -0,0 +1,20 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "ListAccountsWithInvalidEffectivePolicy": { + "non_aggregate_keys": [ + "PolicyType" + ] + }, + "ListEffectivePolicyValidationErrors": { + "non_aggregate_keys": [ + "PolicyType", + "AccountId", + "EvaluationTimestamp", + "Path" + ] + } + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/outposts/2019-12-03/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/outposts/2019-12-03/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/outposts/2019-12-03/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/outposts/2019-12-03/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/outposts/2019-12-03/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..8ccc34fce6d8e871a6ac8fe3b8c209068d9df4e1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/outposts/2019-12-03/paginators-1.json @@ -0,0 +1,70 @@ +{ + "pagination": { + "GetOutpostInstanceTypes": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "InstanceTypes" + }, + "ListAssets": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Assets" + }, + "ListCatalogItems": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "CatalogItems" + }, + "ListOrders": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Orders" + }, + "ListOutposts": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Outposts" + }, + "ListSites": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Sites" + }, + "GetOutpostSupportedInstanceTypes": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "InstanceTypes" + }, + "ListCapacityTasks": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "CapacityTasks" + }, + "ListAssetInstances": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "AssetInstances" + }, + "ListBlockingInstancesForCapacityTask": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "BlockingInstances" + }, + "GetOutpostBillingInformation": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Subscriptions" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/outposts/2019-12-03/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/outposts/2019-12-03/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..c020d0a7f0e1ce3ab6e556c108e3db05993a7a8b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/outposts/2019-12-03/paginators-1.sdk-extras.json @@ -0,0 +1,18 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "GetOutpostInstanceTypes": { + "non_aggregate_keys": [ + "OutpostArn", + "OutpostId" + ] + }, + "GetOutpostBillingInformation": { + "non_aggregate_keys": [ + "ContractEndDate" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/panorama/2019-07-24/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/panorama/2019-07-24/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/panorama/2019-07-24/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/panorama/2019-07-24/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/panorama/2019-07-24/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/panorama/2019-07-24/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/partitions.json b/.venv/lib/python3.13/site-packages/botocore/data/partitions.json new file mode 100644 index 0000000000000000000000000000000000000000..c789264d2b0e9f364de072110eec784808595560 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/partitions.json @@ -0,0 +1,267 @@ +{ + "partitions" : [ { + "id" : "aws", + "outputs" : { + "dnsSuffix" : "amazonaws.com", + "dualStackDnsSuffix" : "api.aws", + "implicitGlobalRegion" : "us-east-1", + "name" : "aws", + "supportsDualStack" : true, + "supportsFIPS" : true + }, + "regionRegex" : "^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$", + "regions" : { + "af-south-1" : { + "description" : "Africa (Cape Town)" + }, + "ap-east-1" : { + "description" : "Asia Pacific (Hong Kong)" + }, + "ap-east-2" : { + "description" : "Asia Pacific (Taipei)" + }, + "ap-northeast-1" : { + "description" : "Asia Pacific (Tokyo)" + }, + "ap-northeast-2" : { + "description" : "Asia Pacific (Seoul)" + }, + "ap-northeast-3" : { + "description" : "Asia Pacific (Osaka)" + }, + "ap-south-1" : { + "description" : "Asia Pacific (Mumbai)" + }, + "ap-south-2" : { + "description" : "Asia Pacific (Hyderabad)" + }, + "ap-southeast-1" : { + "description" : "Asia Pacific (Singapore)" + }, + "ap-southeast-2" : { + "description" : "Asia Pacific (Sydney)" + }, + "ap-southeast-3" : { + "description" : "Asia Pacific (Jakarta)" + }, + "ap-southeast-4" : { + "description" : "Asia Pacific (Melbourne)" + }, + "ap-southeast-5" : { + "description" : "Asia Pacific (Malaysia)" + }, + "ap-southeast-6" : { + "description" : "Asia Pacific (New Zealand)" + }, + "ap-southeast-7" : { + "description" : "Asia Pacific (Thailand)" + }, + "aws-global" : { + "description" : "aws global region" + }, + "ca-central-1" : { + "description" : "Canada (Central)" + }, + "ca-west-1" : { + "description" : "Canada West (Calgary)" + }, + "eu-central-1" : { + "description" : "Europe (Frankfurt)" + }, + "eu-central-2" : { + "description" : "Europe (Zurich)" + }, + "eu-north-1" : { + "description" : "Europe (Stockholm)" + }, + "eu-south-1" : { + "description" : "Europe (Milan)" + }, + "eu-south-2" : { + "description" : "Europe (Spain)" + }, + "eu-west-1" : { + "description" : "Europe (Ireland)" + }, + "eu-west-2" : { + "description" : "Europe (London)" + }, + "eu-west-3" : { + "description" : "Europe (Paris)" + }, + "il-central-1" : { + "description" : "Israel (Tel Aviv)" + }, + "me-central-1" : { + "description" : "Middle East (UAE)" + }, + "me-south-1" : { + "description" : "Middle East (Bahrain)" + }, + "mx-central-1" : { + "description" : "Mexico (Central)" + }, + "sa-east-1" : { + "description" : "South America (Sao Paulo)" + }, + "us-east-1" : { + "description" : "US East (N. Virginia)" + }, + "us-east-2" : { + "description" : "US East (Ohio)" + }, + "us-west-1" : { + "description" : "US West (N. California)" + }, + "us-west-2" : { + "description" : "US West (Oregon)" + } + } + }, { + "id" : "aws-cn", + "outputs" : { + "dnsSuffix" : "amazonaws.com.cn", + "dualStackDnsSuffix" : "api.amazonwebservices.com.cn", + "implicitGlobalRegion" : "cn-northwest-1", + "name" : "aws-cn", + "supportsDualStack" : true, + "supportsFIPS" : true + }, + "regionRegex" : "^cn\\-\\w+\\-\\d+$", + "regions" : { + "aws-cn-global" : { + "description" : "aws-cn global region" + }, + "cn-north-1" : { + "description" : "China (Beijing)" + }, + "cn-northwest-1" : { + "description" : "China (Ningxia)" + } + } + }, { + "id" : "aws-eusc", + "outputs" : { + "dnsSuffix" : "amazonaws.eu", + "dualStackDnsSuffix" : "api.amazonwebservices.eu", + "implicitGlobalRegion" : "eusc-de-east-1", + "name" : "aws-eusc", + "supportsDualStack" : true, + "supportsFIPS" : true + }, + "regionRegex" : "^eusc\\-(de)\\-\\w+\\-\\d+$", + "regions" : { + "eusc-de-east-1" : { + "description" : "EU (Germany)" + } + } + }, { + "id" : "aws-iso", + "outputs" : { + "dnsSuffix" : "c2s.ic.gov", + "dualStackDnsSuffix" : "api.aws.ic.gov", + "implicitGlobalRegion" : "us-iso-east-1", + "name" : "aws-iso", + "supportsDualStack" : true, + "supportsFIPS" : true + }, + "regionRegex" : "^us\\-iso\\-\\w+\\-\\d+$", + "regions" : { + "aws-iso-global" : { + "description" : "aws-iso global region" + }, + "us-iso-east-1" : { + "description" : "US ISO East" + }, + "us-iso-west-1" : { + "description" : "US ISO WEST" + } + } + }, { + "id" : "aws-iso-b", + "outputs" : { + "dnsSuffix" : "sc2s.sgov.gov", + "dualStackDnsSuffix" : "api.aws.scloud", + "implicitGlobalRegion" : "us-isob-east-1", + "name" : "aws-iso-b", + "supportsDualStack" : true, + "supportsFIPS" : true + }, + "regionRegex" : "^us\\-isob\\-\\w+\\-\\d+$", + "regions" : { + "aws-iso-b-global" : { + "description" : "aws-iso-b global region" + }, + "us-isob-east-1" : { + "description" : "US ISOB East (Ohio)" + }, + "us-isob-west-1" : { + "description" : "US ISOB West" + } + } + }, { + "id" : "aws-iso-e", + "outputs" : { + "dnsSuffix" : "cloud.adc-e.uk", + "dualStackDnsSuffix" : "api.cloud-aws.adc-e.uk", + "implicitGlobalRegion" : "eu-isoe-west-1", + "name" : "aws-iso-e", + "supportsDualStack" : true, + "supportsFIPS" : true + }, + "regionRegex" : "^eu\\-isoe\\-\\w+\\-\\d+$", + "regions" : { + "aws-iso-e-global" : { + "description" : "aws-iso-e global region" + }, + "eu-isoe-west-1" : { + "description" : "EU ISOE West" + } + } + }, { + "id" : "aws-iso-f", + "outputs" : { + "dnsSuffix" : "csp.hci.ic.gov", + "dualStackDnsSuffix" : "api.aws.hci.ic.gov", + "implicitGlobalRegion" : "us-isof-south-1", + "name" : "aws-iso-f", + "supportsDualStack" : true, + "supportsFIPS" : true + }, + "regionRegex" : "^us\\-isof\\-\\w+\\-\\d+$", + "regions" : { + "aws-iso-f-global" : { + "description" : "aws-iso-f global region" + }, + "us-isof-east-1" : { + "description" : "US ISOF EAST" + }, + "us-isof-south-1" : { + "description" : "US ISOF SOUTH" + } + } + }, { + "id" : "aws-us-gov", + "outputs" : { + "dnsSuffix" : "amazonaws.com", + "dualStackDnsSuffix" : "api.aws", + "implicitGlobalRegion" : "us-gov-west-1", + "name" : "aws-us-gov", + "supportsDualStack" : true, + "supportsFIPS" : true + }, + "regionRegex" : "^us\\-gov\\-\\w+\\-\\d+$", + "regions" : { + "aws-us-gov-global" : { + "description" : "aws-us-gov global region" + }, + "us-gov-east-1" : { + "description" : "AWS GovCloud (US-East)" + }, + "us-gov-west-1" : { + "description" : "AWS GovCloud (US-West)" + } + } + } ], + "version" : "1.1" +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/partnercentral-channel/2024-03-18/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/partnercentral-channel/2024-03-18/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..1e923f47f512781ee42756f3e0997fdb7b084eea --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/partnercentral-channel/2024-03-18/paginators-1.json @@ -0,0 +1,22 @@ +{ + "pagination": { + "ListChannelHandshakes": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListProgramManagementAccounts": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListRelationships": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/partnercentral-channel/2024-03-18/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/partnercentral-channel/2024-03-18/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/partnercentral-channel/2024-03-18/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/payment-cryptography-data/2022-02-03/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/payment-cryptography-data/2022-02-03/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/payment-cryptography-data/2022-02-03/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/payment-cryptography-data/2022-02-03/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/payment-cryptography-data/2022-02-03/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/payment-cryptography-data/2022-02-03/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/pca-connector-ad/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/pca-connector-ad/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..89234776f16b0f71af9d7bfcdb7a6f4c7a08d9ca --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/pca-connector-ad/2018-05-10/paginators-1.json @@ -0,0 +1,34 @@ +{ + "pagination": { + "ListConnectors": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Connectors" + }, + "ListDirectoryRegistrations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "DirectoryRegistrations" + }, + "ListServicePrincipalNames": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ServicePrincipalNames" + }, + "ListTemplateGroupAccessControlEntries": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "AccessControlEntries" + }, + "ListTemplates": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Templates" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/pca-connector-scep/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/pca-connector-scep/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..7a913db52966d55b39c3e52f21e977001131647e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/pca-connector-scep/2018-05-10/paginators-1.json @@ -0,0 +1,16 @@ +{ + "pagination": { + "ListChallengeMetadata": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Challenges" + }, + "ListConnectors": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Connectors" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/pca-connector-scep/2018-05-10/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/pca-connector-scep/2018-05-10/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/pca-connector-scep/2018-05-10/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/pcs/2023-02-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/pcs/2023-02-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..555a266b316c2c0717a88d09a5ae6df88090eb6a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/pcs/2023-02-10/paginators-1.json @@ -0,0 +1,22 @@ +{ + "pagination": { + "ListClusters": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "clusters" + }, + "ListComputeNodeGroups": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "computeNodeGroups" + }, + "ListQueues": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "queues" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/pcs/2023-02-10/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/pcs/2023-02-10/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/pcs/2023-02-10/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/personalize-events/2018-03-22/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/personalize-events/2018-03-22/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/personalize-events/2018-03-22/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/personalize-events/2018-03-22/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/personalize-events/2018-03-22/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/personalize-events/2018-03-22/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/personalize-runtime/2018-05-22/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/personalize-runtime/2018-05-22/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/personalize-runtime/2018-05-22/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/personalize-runtime/2018-05-22/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/personalize-runtime/2018-05-22/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/personalize-runtime/2018-05-22/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/personalize/2018-05-22/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/personalize/2018-05-22/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/personalize/2018-05-22/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/personalize/2018-05-22/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/personalize/2018-05-22/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea43852fe96ec6481166f3bbbb677687ba695867 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/personalize/2018-05-22/paginators-1.json @@ -0,0 +1,100 @@ +{ + "pagination": { + "ListCampaigns": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "campaigns" + }, + "ListDatasetGroups": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "datasetGroups" + }, + "ListDatasetImportJobs": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "datasetImportJobs" + }, + "ListDatasets": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "datasets" + }, + "ListEventTrackers": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "eventTrackers" + }, + "ListRecipes": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "recipes" + }, + "ListSchemas": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "schemas" + }, + "ListSolutionVersions": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "solutionVersions" + }, + "ListSolutions": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "solutions" + }, + "ListBatchInferenceJobs": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "batchInferenceJobs" + }, + "ListDatasetExportJobs": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "datasetExportJobs" + }, + "ListFilters": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "Filters" + }, + "ListBatchSegmentJobs": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "batchSegmentJobs" + }, + "ListRecommenders": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "recommenders" + }, + "ListMetricAttributionMetrics": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "metrics" + }, + "ListMetricAttributions": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "metricAttributions" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/pinpoint-email/2018-07-26/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/pinpoint-email/2018-07-26/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/pinpoint-email/2018-07-26/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/pinpoint-email/2018-07-26/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/pinpoint-email/2018-07-26/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..f2693b192626936b15fc2a6f685f40fae8938450 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/pinpoint-email/2018-07-26/paginators-1.json @@ -0,0 +1,34 @@ +{ + "pagination": { + "GetDedicatedIps": { + "input_token": "NextToken", + "limit_key": "PageSize", + "output_token": "NextToken", + "result_key": "DedicatedIps" + }, + "ListConfigurationSets": { + "input_token": "NextToken", + "limit_key": "PageSize", + "output_token": "NextToken", + "result_key": "ConfigurationSets" + }, + "ListDedicatedIpPools": { + "input_token": "NextToken", + "limit_key": "PageSize", + "output_token": "NextToken", + "result_key": "DedicatedIpPools" + }, + "ListDeliverabilityTestReports": { + "input_token": "NextToken", + "limit_key": "PageSize", + "output_token": "NextToken", + "result_key": "DeliverabilityTestReports" + }, + "ListEmailIdentities": { + "input_token": "NextToken", + "limit_key": "PageSize", + "output_token": "NextToken", + "result_key": "EmailIdentities" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/pinpoint/2016-12-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/pinpoint/2016-12-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/pinpoint/2016-12-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/pipes/2015-10-07/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/pipes/2015-10-07/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..4663077cb456165bacedeb8e8e0f9c10f772c4a5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/pipes/2015-10-07/paginators-1.json @@ -0,0 +1,10 @@ +{ + "pagination": { + "ListPipes": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "Limit", + "result_key": "Pipes" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/pipes/2015-10-07/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/pipes/2015-10-07/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/pipes/2015-10-07/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/polly/2016-06-10/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/polly/2016-06-10/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..a0e354e0a21cf1fc6a05cefdbd033e4e8419b376 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/polly/2016-06-10/examples-1.json @@ -0,0 +1,171 @@ +{ + "version": "1.0", + "examples": { + "DeleteLexicon": [ + { + "input": { + "Name": "example" + }, + "output": { + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Deletes a specified pronunciation lexicon stored in an AWS Region.", + "id": "to-delete-a-lexicon-1481922498332", + "title": "To delete a lexicon" + } + ], + "DescribeVoices": [ + { + "input": { + "LanguageCode": "en-GB" + }, + "output": { + "Voices": [ + { + "Gender": "Female", + "Id": "Emma", + "LanguageCode": "en-GB", + "LanguageName": "British English", + "Name": "Emma" + }, + { + "Gender": "Male", + "Id": "Brian", + "LanguageCode": "en-GB", + "LanguageName": "British English", + "Name": "Brian" + }, + { + "Gender": "Female", + "Id": "Amy", + "LanguageCode": "en-GB", + "LanguageName": "British English", + "Name": "Amy" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns the list of voices that are available for use when requesting speech synthesis. Displayed languages are those within the specified language code. If no language code is specified, voices for all available languages are displayed.", + "id": "to-describe-available-voices-1482180557753", + "title": "To describe available voices" + } + ], + "GetLexicon": [ + { + "input": { + "Name": "" + }, + "output": { + "Lexicon": { + "Content": "\r\n\r\n \r\n W3C\r\n World Wide Web Consortium\r\n \r\n", + "Name": "example" + }, + "LexiconAttributes": { + "Alphabet": "ipa", + "LanguageCode": "en-US", + "LastModified": 1478542980.117, + "LexemesCount": 1, + "LexiconArn": "arn:aws:polly:us-east-1:123456789012:lexicon/example", + "Size": 503 + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns the content of the specified pronunciation lexicon stored in an AWS Region.", + "id": "to-retrieve-a-lexicon-1481912870836", + "title": "To retrieve a lexicon" + } + ], + "ListLexicons": [ + { + "input": { + }, + "output": { + "Lexicons": [ + { + "Attributes": { + "Alphabet": "ipa", + "LanguageCode": "en-US", + "LastModified": 1478542980.117, + "LexemesCount": 1, + "LexiconArn": "arn:aws:polly:us-east-1:123456789012:lexicon/example", + "Size": 503 + }, + "Name": "example" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns a list of pronunciation lexicons stored in an AWS Region.", + "id": "to-list-all-lexicons-in-a-region-1481842106487", + "title": "To list all lexicons in a region" + } + ], + "PutLexicon": [ + { + "input": { + "Content": "", + "Name": "W3C" + }, + "output": { + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Stores a pronunciation lexicon in an AWS Region.", + "id": "to-save-a-lexicon-1482272584088", + "title": "To save a lexicon" + } + ], + "SynthesizeSpeech": [ + { + "input": { + "LexiconNames": [ + "example" + ], + "OutputFormat": "mp3", + "SampleRate": "8000", + "Text": "All Gaul is divided into three parts", + "TextType": "text", + "VoiceId": "Joanna" + }, + "output": { + "AudioStream": "TEXT", + "ContentType": "audio/mpeg", + "RequestCharacters": 37 + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Synthesizes plain text or SSML into a file of human-like speech.", + "id": "to-synthesize-speech-1482186064046", + "title": "To synthesize speech" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/polly/2016-06-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/polly/2016-06-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..dc76e7c1ac8730a308873cecd3806e5fe61dff7c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/polly/2016-06-10/paginators-1.json @@ -0,0 +1,20 @@ +{ + "pagination": { + "DescribeVoices": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Voices" + }, + "ListLexicons": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Lexicons" + }, + "ListSpeechSynthesisTasks": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "SynthesisTasks" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/pricing/2017-10-15/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/pricing/2017-10-15/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..abc1c59f342d46436b129a8293bdb117533bbc6b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/pricing/2017-10-15/examples-1.json @@ -0,0 +1,104 @@ +{ + "version": "1.0", + "examples": { + "DescribeServices": [ + { + "input": { + "FormatVersion": "aws_v1", + "MaxResults": 1, + "ServiceCode": "AmazonEC2" + }, + "output": { + "FormatVersion": "aws_v1", + "NextToken": "abcdefg123", + "Services": [ + { + "AttributeNames": [ + "volumeType", + "maxIopsvolume", + "instanceCapacity10xlarge", + "locationType", + "operation" + ], + "ServiceCode": "AmazonEC2" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Retrieves the service for the given Service Code.", + "id": "to-retrieve-service-metadata", + "title": "To retrieve a list of services and service codes" + } + ], + "GetAttributeValues": [ + { + "input": { + "AttributeName": "volumeType", + "MaxResults": 2, + "ServiceCode": "AmazonEC2" + }, + "output": { + "AttributeValues": [ + { + "Value": "Throughput Optimized HDD" + }, + { + "Value": "Provisioned IOPS" + } + ], + "NextToken": "GpgauEXAMPLEezucl5LV0w==:7GzYJ0nw0DBTJ2J66EoTIIynE6O1uXwQtTRqioJzQadBnDVgHPzI1en4BUQnPCLpzeBk9RQQAWaFieA4+DapFAGLgk+Z/9/cTw9GldnPOHN98+FdmJP7wKU3QQpQ8MQr5KOeBkIsAqvAQYdL0DkL7tHwPtE5iCEByAmg9gcC/yBU1vAOsf7R3VaNN4M5jMDv3woSWqASSIlBVB6tgW78YL22KhssoItM/jWW+aP6Jqtq4mldxp/ct6DWAl+xLFwHU/CbketimPPXyqHF3/UXDw==" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This operation returns a list of values available for the given attribute.", + "id": "to-retreive-attribute-values", + "title": "To retrieve a list of attribute values" + } + ], + "GetProducts": [ + { + "input": { + "Filters": [ + { + "Field": "ServiceCode", + "Type": "TERM_MATCH", + "Value": "AmazonEC2" + }, + { + "Field": "volumeType", + "Type": "TERM_MATCH", + "Value": "Provisioned IOPS" + } + ], + "FormatVersion": "aws_v1", + "MaxResults": 1 + }, + "output": { + "FormatVersion": "aws_v1", + "NextToken": "57r3EXAMPLEujbzWfHF7Ciw==:ywSmZsD3mtpQmQLQ5XfOsIMkYybSj+vAT+kGmwMFq+K9DGmIoJkz7lunVeamiOPgthdWSO2a7YKojCO+zY4dJmuNl2QvbNhXs+AJ2Ufn7xGmJncNI2TsEuAsVCUfTAvAQNcwwamtk6XuZ4YdNnooV62FjkV3ZAn40d9+wAxV7+FImvhUHi/+f8afgZdGh2zPUlH8jlV9uUtj0oHp8+DhPUuHXh+WBII1E/aoKpPSm3c=", + "PriceList": [ + "{\"product\":{\"productFamily\":\"Storage\",\"attributes\":{\"storageMedia\":\"SSD-backed\",\"maxThroughputvolume\":\"320 MB/sec\",\"volumeType\":\"Provisioned IOPS\",\"maxIopsvolume\":\"20000\",\"servicecode\":\"AmazonEC2\",\"usagetype\":\"CAN1-EBS:VolumeUsage.piops\",\"locationType\":\"AWS Region\",\"location\":\"Canada (Central)\",\"servicename\":\"Amazon Elastic Compute Cloud\",\"maxVolumeSize\":\"16 TiB\",\"operation\":\"\"},\"sku\":\"WQGC34PB2AWS8R4U\"},\"serviceCode\":\"AmazonEC2\",\"terms\":{\"OnDemand\":{\"WQGC34PB2AWS8R4U.JRTCKXETXF\":{\"priceDimensions\":{\"WQGC34PB2AWS8R4U.JRTCKXETXF.6YS6EN2CT7\":{\"unit\":\"GB-Mo\",\"endRange\":\"Inf\",\"description\":\"$0.138 per GB-month of Provisioned IOPS SSD (io1) provisioned storage - Canada (Central)\",\"appliesTo\":[],\"rateCode\":\"WQGC34PB2AWS8R4U.JRTCKXETXF.6YS6EN2CT7\",\"beginRange\":\"0\",\"pricePerUnit\":{\"USD\":\"0.1380000000\"}}},\"sku\":\"WQGC34PB2AWS8R4U\",\"effectiveDate\":\"2017-08-01T00:00:00Z\",\"offerTermCode\":\"JRTCKXETXF\",\"termAttributes\":{}}}},\"version\":\"20170901182201\",\"publicationDate\":\"2017-09-01T18:22:01Z\"}" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This operation returns a list of products that match the given criteria.", + "id": "to-retrieve-available products", + "title": "To retrieve a list of products" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/pricing/2017-10-15/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/pricing/2017-10-15/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0f2ce4e8e26966d1df93b129a2cd610d10f02b86 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/pricing/2017-10-15/paginators-1.json @@ -0,0 +1,34 @@ +{ + "pagination": { + "DescribeServices": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Services", + "non_aggregate_keys": [ + "FormatVersion" + ] + }, + "GetAttributeValues": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "AttributeValues" + }, + "GetProducts": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "PriceList", + "non_aggregate_keys": [ + "FormatVersion" + ] + }, + "ListPriceLists": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "PriceLists" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/pricing/2017-10-15/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/pricing/2017-10-15/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/pricing/2017-10-15/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/qapps/2023-11-27/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/qapps/2023-11-27/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0d13e6c265bedb490eada533293a35273a9e14be --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/qapps/2023-11-27/paginators-1.json @@ -0,0 +1,16 @@ +{ + "pagination": { + "ListLibraryItems": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "limit", + "result_key": "libraryItems" + }, + "ListQApps": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "limit", + "result_key": "apps" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/qapps/2023-11-27/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/qapps/2023-11-27/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/qapps/2023-11-27/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/qbusiness/2023-11-27/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/qbusiness/2023-11-27/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..47e8498a7eb28e1cab4f78753f0775b65f0d12d4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/qbusiness/2023-11-27/paginators-1.json @@ -0,0 +1,124 @@ +{ + "pagination": { + "GetChatControlsConfiguration": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "topicConfigurations" + }, + "ListApplications": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "applications" + }, + "ListConversations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "conversations" + }, + "ListDataSourceSyncJobs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "history" + }, + "ListDataSources": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "dataSources" + }, + "ListDocuments": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "documentDetailList" + }, + "ListGroups": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListIndices": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "indices" + }, + "ListMessages": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "messages" + }, + "ListPlugins": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "plugins" + }, + "ListRetrievers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "retrievers" + }, + "ListWebExperiences": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "webExperiences" + }, + "ListAttachments": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "attachments" + }, + "ListDataAccessors": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "dataAccessors" + }, + "ListPluginActions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListPluginTypeActions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListPluginTypeMetadata": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "SearchRelevantContent": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "relevantContent" + }, + "ListSubscriptions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "subscriptions" + }, + "ListChatResponseConfigurations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "chatResponseConfigurations" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/qbusiness/2023-11-27/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/qbusiness/2023-11-27/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..b5a1e6e4deae0171baf1feaa200fc72c58f0dcbe --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/qbusiness/2023-11-27/paginators-1.sdk-extras.json @@ -0,0 +1,16 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "GetChatControlsConfiguration": { + "non_aggregate_keys": [ + "responseScope", + "blockedPhrases", + "creatorModeConfiguration", + "orchestrationConfiguration", + "hallucinationReductionConfiguration" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/qbusiness/2023-11-27/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/qbusiness/2023-11-27/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/qbusiness/2023-11-27/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ram/2018-01-04/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/ram/2018-01-04/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ram/2018-01-04/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ram/2018-01-04/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/ram/2018-01-04/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ec438a09a555fab33f744570760ad73a513155a5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ram/2018-01-04/paginators-1.json @@ -0,0 +1,40 @@ +{ + "pagination": { + "GetResourcePolicies": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "policies" + }, + "GetResourceShareAssociations": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "resourceShareAssociations" + }, + "GetResourceShareInvitations": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "resourceShareInvitations" + }, + "GetResourceShares": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "resourceShares" + }, + "ListPrincipals": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "principals" + }, + "ListResources": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "resources" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/redshift-data/2019-12-20/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/redshift-data/2019-12-20/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/redshift-data/2019-12-20/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/redshift-data/2019-12-20/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/redshift-data/2019-12-20/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ba46aa4b2813dc3f7e0b4d218d230ebf58a70990 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/redshift-data/2019-12-20/paginators-1.json @@ -0,0 +1,44 @@ +{ + "pagination": { + "DescribeTable": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ColumnList" + }, + "GetStatementResult": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Records" + }, + "ListDatabases": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Databases" + }, + "ListSchemas": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Schemas" + }, + "ListStatements": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Statements" + }, + "ListTables": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Tables" + }, + "GetStatementResultV2": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Records" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/redshift-data/2019-12-20/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/redshift-data/2019-12-20/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..8a0601670e5aa7138954c5d3ef93ebb44787bff6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/redshift-data/2019-12-20/paginators-1.sdk-extras.json @@ -0,0 +1,25 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "GetStatementResult": { + "non_aggregate_keys": [ + "ColumnMetadata", + "TotalNumRows" + ] + }, + "GetStatementResultV2": { + "non_aggregate_keys": [ + "ColumnMetadata", + "TotalNumRows", + "ResultFormat" + ] + }, + "DescribeTable": { + "non_aggregate_keys": [ + "TableName" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/redshift-serverless/2021-04-21/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/redshift-serverless/2021-04-21/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0b5e6ab900492f7fe65c37dd73a7726b51a41f48 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/redshift-serverless/2021-04-21/paginators-1.json @@ -0,0 +1,88 @@ +{ + "pagination": { + "ListEndpointAccess": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "endpoints" + }, + "ListNamespaces": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "namespaces" + }, + "ListRecoveryPoints": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "recoveryPoints" + }, + "ListSnapshots": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "snapshots" + }, + "ListUsageLimits": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "usageLimits" + }, + "ListWorkgroups": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "workgroups" + }, + "ListTableRestoreStatus": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "tableRestoreStatuses" + }, + "ListCustomDomainAssociations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "associations" + }, + "ListScheduledActions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "scheduledActions" + }, + "ListSnapshotCopyConfigurations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "snapshotCopyConfigurations" + }, + "ListManagedWorkgroups": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "managedWorkgroups" + }, + "ListTracks": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "tracks" + }, + "ListReservationOfferings": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "reservationOfferingsList" + }, + "ListReservations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "reservationsList" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/redshift/2012-12-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/redshift/2012-12-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/redshift/2012-12-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/redshift/2012-12-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/redshift/2012-12-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..97559e47c838155e960e35fd498f9192d50ce58a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/redshift/2012-12-01/paginators-1.json @@ -0,0 +1,226 @@ +{ + "pagination": { + "DescribeClusterParameterGroups": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "ParameterGroups" + }, + "DescribeClusterParameters": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "Parameters" + }, + "DescribeClusterSecurityGroups": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "ClusterSecurityGroups" + }, + "DescribeClusterSnapshots": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "Snapshots" + }, + "DescribeClusterSubnetGroups": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "ClusterSubnetGroups" + }, + "DescribeClusterVersions": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "ClusterVersions" + }, + "DescribeClusters": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "Clusters" + }, + "DescribeDefaultClusterParameters": { + "input_token": "Marker", + "output_token": "DefaultClusterParameters.Marker", + "limit_key": "MaxRecords", + "result_key": "DefaultClusterParameters.Parameters" + }, + "DescribeEventSubscriptions": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "EventSubscriptionsList" + }, + "DescribeEvents": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "Events" + }, + "DescribeHsmClientCertificates": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "HsmClientCertificates" + }, + "DescribeHsmConfigurations": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "HsmConfigurations" + }, + "DescribeOrderableClusterOptions": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "OrderableClusterOptions" + }, + "DescribeReservedNodeOfferings": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "ReservedNodeOfferings" + }, + "DescribeReservedNodes": { + "input_token": "Marker", + "output_token": "Marker", + "limit_key": "MaxRecords", + "result_key": "ReservedNodes" + }, + "DescribeClusterDbRevisions": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "ClusterDbRevisions" + }, + "DescribeClusterTracks": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "MaintenanceTracks" + }, + "DescribeSnapshotCopyGrants": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "SnapshotCopyGrants" + }, + "DescribeSnapshotSchedules": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "SnapshotSchedules" + }, + "DescribeTableRestoreStatus": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "TableRestoreStatusDetails" + }, + "DescribeTags": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "TaggedResources" + }, + "GetReservedNodeExchangeOfferings": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "ReservedNodeOfferings" + }, + "DescribeNodeConfigurationOptions": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "NodeConfigurationOptionList" + }, + "DescribeScheduledActions": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "ScheduledActions" + }, + "DescribeUsageLimits": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "UsageLimits" + }, + "DescribeEndpointAccess": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "EndpointAccessList" + }, + "DescribeEndpointAuthorization": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "EndpointAuthorizationList" + }, + "DescribeDataShares": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "DataShares" + }, + "DescribeDataSharesForConsumer": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "DataShares" + }, + "DescribeDataSharesForProducer": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "DataShares" + }, + "DescribeReservedNodeExchangeStatus": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "ReservedNodeExchangeStatusDetails" + }, + "GetReservedNodeExchangeConfigurationOptions": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "ReservedNodeConfigurationOptionList" + }, + "DescribeCustomDomainAssociations": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "Associations" + }, + "DescribeInboundIntegrations": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "InboundIntegrations" + }, + "DescribeRedshiftIdcApplications": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "RedshiftIdcApplications" + }, + "ListRecommendations": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "Recommendations" + }, + "DescribeIntegrations": { + "input_token": "Marker", + "limit_key": "MaxRecords", + "output_token": "Marker", + "result_key": "Integrations" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/redshift/2012-12-01/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/redshift/2012-12-01/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..164e9b0df2c8c7ba549743ad22034eb9f005a502 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/redshift/2012-12-01/waiters-2.json @@ -0,0 +1,97 @@ +{ + "version": 2, + "waiters": { + "ClusterAvailable": { + "delay": 60, + "operation": "DescribeClusters", + "maxAttempts": 30, + "acceptors": [ + { + "expected": "available", + "matcher": "pathAll", + "state": "success", + "argument": "Clusters[].ClusterStatus" + }, + { + "expected": "deleting", + "matcher": "pathAny", + "state": "failure", + "argument": "Clusters[].ClusterStatus" + }, + { + "expected": "ClusterNotFound", + "matcher": "error", + "state": "retry" + } + ] + }, + "ClusterDeleted": { + "delay": 60, + "operation": "DescribeClusters", + "maxAttempts": 30, + "acceptors": [ + { + "expected": "ClusterNotFound", + "matcher": "error", + "state": "success" + }, + { + "expected": "creating", + "matcher": "pathAny", + "state": "failure", + "argument": "Clusters[].ClusterStatus" + }, + { + "expected": "modifying", + "matcher": "pathAny", + "state": "failure", + "argument": "Clusters[].ClusterStatus" + } + ] + }, + "ClusterRestored": { + "operation": "DescribeClusters", + "maxAttempts": 30, + "delay": 60, + "acceptors": [ + { + "state": "success", + "matcher": "pathAll", + "argument": "Clusters[].RestoreStatus.Status", + "expected": "completed" + }, + { + "state": "failure", + "matcher": "pathAny", + "argument": "Clusters[].ClusterStatus", + "expected": "deleting" + } + ] + }, + "SnapshotAvailable": { + "delay": 15, + "operation": "DescribeClusterSnapshots", + "maxAttempts": 20, + "acceptors": [ + { + "expected": "available", + "matcher": "pathAll", + "state": "success", + "argument": "Snapshots[].Status" + }, + { + "expected": "failed", + "matcher": "pathAny", + "state": "failure", + "argument": "Snapshots[].Status" + }, + { + "expected": "deleted", + "matcher": "pathAny", + "state": "failure", + "argument": "Snapshots[].Status" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/repostspace/2022-05-13/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/repostspace/2022-05-13/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..005e53f9422df7414257db3d66a34d80013c58b2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/repostspace/2022-05-13/paginators-1.json @@ -0,0 +1,16 @@ +{ + "pagination": { + "ListSpaces": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "spaces" + }, + "ListChannels": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "channels" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/repostspace/2022-05-13/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/repostspace/2022-05-13/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..3439ab13dda2256f40671980105f34f6d74a30cf --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/repostspace/2022-05-13/waiters-2.json @@ -0,0 +1,97 @@ +{ + "version" : 2, + "waiters" : { + "ChannelCreated" : { + "delay" : 2, + "maxAttempts" : 60, + "operation" : "GetChannel", + "acceptors" : [ { + "matcher" : "path", + "argument" : "channelStatus", + "state" : "success", + "expected" : "CREATED" + }, { + "matcher" : "path", + "argument" : "channelStatus", + "state" : "failure", + "expected" : "CREATE_FAILED" + }, { + "matcher" : "path", + "argument" : "channelStatus", + "state" : "retry", + "expected" : "CREATING" + } ] + }, + "ChannelDeleted" : { + "delay" : 2, + "maxAttempts" : 60, + "operation" : "GetChannel", + "acceptors" : [ { + "matcher" : "error", + "state" : "success", + "expected" : "ResourceNotFoundException" + }, { + "matcher" : "path", + "argument" : "channelStatus", + "state" : "success", + "expected" : "DELETED" + }, { + "matcher" : "path", + "argument" : "channelStatus", + "state" : "failure", + "expected" : "DELETE_FAILED" + }, { + "matcher" : "path", + "argument" : "channelStatus", + "state" : "retry", + "expected" : "DELETING" + } ] + }, + "SpaceCreated" : { + "delay" : 300, + "maxAttempts" : 24, + "operation" : "GetSpace", + "acceptors" : [ { + "matcher" : "path", + "argument" : "status", + "state" : "success", + "expected" : "CREATED" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "CREATE_FAILED" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "retry", + "expected" : "CREATING" + } ] + }, + "SpaceDeleted" : { + "delay" : 300, + "maxAttempts" : 24, + "operation" : "GetSpace", + "acceptors" : [ { + "matcher" : "error", + "state" : "success", + "expected" : "ResourceNotFoundException" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "success", + "expected" : "DELETED" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "failure", + "expected" : "DELETE_FAILED" + }, { + "matcher" : "path", + "argument" : "status", + "state" : "retry", + "expected" : "DELETING" + } ] + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/resource-groups/2017-11-27/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/resource-groups/2017-11-27/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/resource-groups/2017-11-27/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/resource-groups/2017-11-27/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/resource-groups/2017-11-27/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..1210885d26087d0cfd97666905eadef8fc183623 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/resource-groups/2017-11-27/paginators-1.json @@ -0,0 +1,40 @@ +{ + "pagination": { + "ListGroups": { + "result_key": [ + "GroupIdentifiers", + "Groups" + ], + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "SearchResources": { + "result_key": "ResourceIdentifiers", + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "ListGroupResources": { + "result_key": [ + "ResourceIdentifiers", + "Resources" + ], + "output_token": "NextToken", + "input_token": "NextToken", + "limit_key": "MaxResults" + }, + "ListGroupingStatuses": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "GroupingStatuses" + }, + "ListTagSyncTasks": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "TagSyncTasks" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/resource-groups/2017-11-27/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/resource-groups/2017-11-27/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..eaa5232024155c0b4869a49807026b9e245d4c5f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/resource-groups/2017-11-27/paginators-1.sdk-extras.json @@ -0,0 +1,12 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "ListGroupingStatuses": { + "non_aggregate_keys": [ + "Group" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/route53-recovery-readiness/2019-12-02/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/route53-recovery-readiness/2019-12-02/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..a71f0880131ab924fde6023dbb40b1f6e7c90074 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/route53-recovery-readiness/2019-12-02/paginators-1.json @@ -0,0 +1,77 @@ +{ + "pagination": { + "ListReadinessChecks": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ReadinessChecks" + }, + "ListResourceSets": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ResourceSets" + }, + "ListCells": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Cells" + }, + "ListRecoveryGroups": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "RecoveryGroups" + }, + "ListRules": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Rules" + }, + "ListCrossAccountAuthorizations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "CrossAccountAuthorizations" + }, + "GetCellReadinessSummary": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ReadinessChecks", + "non_aggregate_keys": [ + "Readiness" + ] + }, + "GetRecoveryGroupReadinessSummary": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ReadinessChecks", + "non_aggregate_keys": [ + "Readiness" + ] + }, + "GetReadinessCheckStatus": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Resources", + "non_aggregate_keys": [ + "Readiness", + "Messages" + ] + }, + "GetReadinessCheckResourceStatus": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Rules", + "non_aggregate_keys": [ + "Readiness" + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/route53globalresolver/2022-09-27/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/route53globalresolver/2022-09-27/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..abc8b60744117c6de9e1740387eb0ae38584987a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/route53globalresolver/2022-09-27/paginators-1.json @@ -0,0 +1,58 @@ +{ + "pagination": { + "ListAccessSources": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "accessSources" + }, + "ListAccessTokens": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "accessTokens" + }, + "ListDNSViews": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "dnsViews" + }, + "ListFirewallDomainLists": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "firewallDomainLists" + }, + "ListFirewallDomains": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "domains" + }, + "ListFirewallRules": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "firewallRules" + }, + "ListGlobalResolvers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "globalResolvers" + }, + "ListHostedZoneAssociations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "hostedZoneAssociations" + }, + "ListManagedFirewallDomainLists": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "managedFirewallDomainLists" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/route53globalresolver/2022-09-27/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/route53globalresolver/2022-09-27/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/route53globalresolver/2022-09-27/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/route53resolver/2018-04-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/route53resolver/2018-04-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/route53resolver/2018-04-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/route53resolver/2018-04-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/route53resolver/2018-04-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..d6529438ffd29b129d2142623f58dc01442f6101 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/route53resolver/2018-04-01/paginators-1.json @@ -0,0 +1,100 @@ +{ + "pagination": { + "ListTagsForResource": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Tags" + }, + "ListResolverEndpointIpAddresses": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "IpAddresses" + }, + "ListResolverEndpoints": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ResolverEndpoints" + }, + "ListResolverQueryLogConfigAssociations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ResolverQueryLogConfigAssociations" + }, + "ListResolverQueryLogConfigs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ResolverQueryLogConfigs" + }, + "ListResolverRuleAssociations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ResolverRuleAssociations" + }, + "ListResolverRules": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ResolverRules" + }, + "ListResolverDnssecConfigs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ResolverDnssecConfigs" + }, + "ListFirewallConfigs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "FirewallConfigs" + }, + "ListFirewallDomainLists": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "FirewallDomainLists" + }, + "ListFirewallDomains": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Domains" + }, + "ListFirewallRuleGroupAssociations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "FirewallRuleGroupAssociations" + }, + "ListFirewallRuleGroups": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "FirewallRuleGroups" + }, + "ListFirewallRules": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "FirewallRules" + }, + "ListResolverConfigs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ResolverConfigs" + }, + "ListOutpostResolvers": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "OutpostResolvers" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/route53resolver/2018-04-01/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/route53resolver/2018-04-01/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..6808793615c586ec2de989bc04ab61ef0691ff44 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/route53resolver/2018-04-01/paginators-1.sdk-extras.json @@ -0,0 +1,39 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "ListResolverEndpointIpAddresses": { + "non_aggregate_keys": [ + "MaxResults" + ] + }, + "ListResolverEndpoints": { + "non_aggregate_keys": [ + "MaxResults" + ] + }, + "ListResolverQueryLogConfigAssociations": { + "non_aggregate_keys": [ + "TotalCount", + "TotalFilteredCount" + ] + }, + "ListResolverQueryLogConfigs": { + "non_aggregate_keys": [ + "TotalCount", + "TotalFilteredCount" + ] + }, + "ListResolverRuleAssociations": { + "non_aggregate_keys": [ + "MaxResults" + ] + }, + "ListResolverRules": { + "non_aggregate_keys": [ + "MaxResults" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/s3/2006-03-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/s3/2006-03-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..38a47bb331132331b2bcb270eb89bdaf92de7739 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/s3/2006-03-01/examples-1.json @@ -0,0 +1,1843 @@ +{ + "version": "1.0", + "examples": { + "AbortMultipartUpload": [ + { + "input": { + "Bucket": "examplebucket", + "Key": "bigobject", + "UploadId": "xadcOB_7YPBOJuoFiQ9cz4P3Pe6FIZwO4f7wN93uHsNBEw97pl5eNwzExg0LAT2dUN91cOmrEQHDsP3WA60CEg--" + }, + "output": { + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example aborts a multipart upload.", + "id": "to-abort-a-multipart-upload-1481853354987", + "title": "To abort a multipart upload" + } + ], + "CompleteMultipartUpload": [ + { + "input": { + "Bucket": "examplebucket", + "Key": "bigobject", + "MultipartUpload": { + "Parts": [ + { + "ETag": "\"d8c2eafd90c266e19ab9dcacc479f8af\"", + "PartNumber": "1" + }, + { + "ETag": "\"d8c2eafd90c266e19ab9dcacc479f8af\"", + "PartNumber": "2" + } + ] + }, + "UploadId": "7YPBOJuoFiQ9cz4P3Pe6FIZwO4f7wN93uHsNBEw97pl5eNwzExg0LAT2dUN91cOmrEQHDsP3WA60CEg--" + }, + "output": { + "Bucket": "acexamplebucket", + "ETag": "\"4d9031c7644d8081c2829f4ea23c55f7-2\"", + "Key": "bigobject", + "Location": "https://examplebucket.s3.amazonaws.com/bigobject" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example completes a multipart upload.", + "id": "to-complete-multipart-upload-1481851590483", + "title": "To complete multipart upload" + } + ], + "CopyObject": [ + { + "input": { + "Bucket": "destinationbucket", + "CopySource": "/sourcebucket/HappyFacejpg", + "Key": "HappyFaceCopyjpg" + }, + "output": { + "CopyObjectResult": { + "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"", + "LastModified": "2016-12-15T17:38:53.000Z" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example copies an object from one bucket to another.", + "id": "to-copy-an-object-1481823186878", + "title": "To copy an object" + } + ], + "CreateBucket": [ + { + "input": { + "Bucket": "examplebucket", + "CreateBucketConfiguration": { + "LocationConstraint": "eu-west-1" + } + }, + "output": { + "Location": "http://examplebucket.s3.amazonaws.com/" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example creates a bucket. The request specifies an AWS region where to create the bucket.", + "id": "to-create-a-bucket-in-a-specific-region-1483399072992", + "title": "To create a bucket in a specific region" + }, + { + "input": { + "Bucket": "examplebucket" + }, + "output": { + "Location": "/examplebucket" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example creates a bucket.", + "id": "to-create-a-bucket--1472851826060", + "title": "To create a bucket " + } + ], + "CreateMultipartUpload": [ + { + "input": { + "Bucket": "examplebucket", + "Key": "largeobject" + }, + "output": { + "Bucket": "examplebucket", + "Key": "largeobject", + "UploadId": "ibZBv_75gd9r8lH_gqXatLdxMVpAlj6ZQjEs.OwyF3953YdwbcQnMA2BLGn8Lx12fQNICtMw5KyteFeHw.Sjng--" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example initiates a multipart upload.", + "id": "to-initiate-a-multipart-upload-1481836794513", + "title": "To initiate a multipart upload" + } + ], + "DeleteBucket": [ + { + "input": { + "Bucket": "forrandall2" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes the specified bucket.", + "id": "to-delete-a-bucket-1473108514262", + "title": "To delete a bucket" + } + ], + "DeleteBucketCors": [ + { + "input": { + "Bucket": "examplebucket" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes CORS configuration on a bucket.", + "id": "to-delete-cors-configuration-on-a-bucket-1483042856112", + "title": "To delete cors configuration on a bucket." + } + ], + "DeleteBucketLifecycle": [ + { + "input": { + "Bucket": "examplebucket" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes lifecycle configuration on a bucket.", + "id": "to-delete-lifecycle-configuration-on-a-bucket-1483043310583", + "title": "To delete lifecycle configuration on a bucket." + } + ], + "DeleteBucketPolicy": [ + { + "input": { + "Bucket": "examplebucket" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes bucket policy on the specified bucket.", + "id": "to-delete-bucket-policy-1483043406577", + "title": "To delete bucket policy" + } + ], + "DeleteBucketReplication": [ + { + "input": { + "Bucket": "example" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes replication configuration set on bucket.", + "id": "to-delete-bucket-replication-configuration-1483043684668", + "title": "To delete bucket replication configuration" + } + ], + "DeleteBucketTagging": [ + { + "input": { + "Bucket": "examplebucket" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes bucket tags.", + "id": "to-delete-bucket-tags-1483043846509", + "title": "To delete bucket tags" + } + ], + "DeleteBucketWebsite": [ + { + "input": { + "Bucket": "examplebucket" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes bucket website configuration.", + "id": "to-delete-bucket-website-configuration-1483043937825", + "title": "To delete bucket website configuration" + } + ], + "DeleteObject": [ + { + "input": { + "Bucket": "examplebucket", + "Key": "objectkey.jpg" + }, + "output": { + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes an object from an S3 bucket.", + "id": "to-delete-an-object-1472850136595", + "title": "To delete an object" + }, + { + "input": { + "Bucket": "ExampleBucket", + "Key": "HappyFace.jpg" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes an object from a non-versioned bucket.", + "id": "to-delete-an-object-from-a-non-versioned-bucket-1481588533089", + "title": "To delete an object (from a non-versioned bucket)" + } + ], + "DeleteObjectTagging": [ + { + "input": { + "Bucket": "examplebucket", + "Key": "HappyFace.jpg", + "VersionId": "ydlaNkwWm0SfKJR.T1b1fIdPRbldTYRI" + }, + "output": { + "VersionId": "ydlaNkwWm0SfKJR.T1b1fIdPRbldTYRI" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example removes tag set associated with the specified object version. The request specifies both the object key and object version.", + "id": "to-remove-tag-set-from-an-object-version-1483145285913", + "title": "To remove tag set from an object version" + }, + { + "input": { + "Bucket": "examplebucket", + "Key": "HappyFace.jpg" + }, + "output": { + "VersionId": "null" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example removes tag set associated with the specified object. If the bucket is versioning enabled, the operation removes tag set from the latest object version.", + "id": "to-remove-tag-set-from-an-object-1483145342862", + "title": "To remove tag set from an object" + } + ], + "DeleteObjects": [ + { + "input": { + "Bucket": "examplebucket", + "Delete": { + "Objects": [ + { + "Key": "HappyFace.jpg", + "VersionId": "2LWg7lQLnY41.maGB5Z6SWW.dcq0vx7b" + }, + { + "Key": "HappyFace.jpg", + "VersionId": "yoz3HB.ZhCS_tKVEmIOr7qYyyAaZSKVd" + } + ], + "Quiet": false + } + }, + "output": { + "Deleted": [ + { + "Key": "HappyFace.jpg", + "VersionId": "yoz3HB.ZhCS_tKVEmIOr7qYyyAaZSKVd" + }, + { + "Key": "HappyFace.jpg", + "VersionId": "2LWg7lQLnY41.maGB5Z6SWW.dcq0vx7b" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes objects from a bucket. The request specifies object versions. S3 deletes specific object versions and returns the key and versions of deleted objects in the response.", + "id": "to-delete-multiple-object-versions-from-a-versioned-bucket-1483147087737", + "title": "To delete multiple object versions from a versioned bucket" + }, + { + "input": { + "Bucket": "examplebucket", + "Delete": { + "Objects": [ + { + "Key": "objectkey1" + }, + { + "Key": "objectkey2" + } + ], + "Quiet": false + } + }, + "output": { + "Deleted": [ + { + "DeleteMarker": "true", + "DeleteMarkerVersionId": "A._w1z6EFiCF5uhtQMDal9JDkID9tQ7F", + "Key": "objectkey1" + }, + { + "DeleteMarker": "true", + "DeleteMarkerVersionId": "iOd_ORxhkKe_e8G8_oSGxt2PjsCZKlkt", + "Key": "objectkey2" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes objects from a bucket. The bucket is versioned, and the request does not specify the object version to delete. In this case, all versions remain in the bucket and S3 adds a delete marker.", + "id": "to-delete-multiple-objects-from-a-versioned-bucket-1483146248805", + "title": "To delete multiple objects from a versioned bucket" + } + ], + "GetBucketCors": [ + { + "input": { + "Bucket": "examplebucket" + }, + "output": { + "CORSRules": [ + { + "AllowedHeaders": [ + "Authorization" + ], + "AllowedMethods": [ + "GET" + ], + "AllowedOrigins": [ + "*" + ], + "MaxAgeSeconds": 3000 + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns cross-origin resource sharing (CORS) configuration set on a bucket.", + "id": "to-get-cors-configuration-set-on-a-bucket-1481596855475", + "title": "To get cors configuration set on a bucket" + } + ], + "GetBucketLifecycle": [ + { + "input": { + "Bucket": "acl1" + }, + "output": { + "Rules": [ + { + "Expiration": { + "Days": 1 + }, + "ID": "delete logs", + "Prefix": "123/", + "Status": "Enabled" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example gets ACL on the specified bucket.", + "id": "to-get-a-bucket-acl-1474413606503", + "title": "To get a bucket acl" + } + ], + "GetBucketLifecycleConfiguration": [ + { + "input": { + "Bucket": "examplebucket" + }, + "output": { + "Rules": [ + { + "ID": "Rule for TaxDocs/", + "Prefix": "TaxDocs", + "Status": "Enabled", + "Transitions": [ + { + "Days": 365, + "StorageClass": "STANDARD_IA" + } + ] + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example retrieves lifecycle configuration on set on a bucket. ", + "id": "to-get-lifecycle-configuration-on-a-bucket-1481666063200", + "title": "To get lifecycle configuration on a bucket" + } + ], + "GetBucketLocation": [ + { + "input": { + "Bucket": "examplebucket" + }, + "output": { + "LocationConstraint": "us-west-2" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns bucket location.", + "id": "to-get-bucket-location-1481594573609", + "title": "To get bucket location" + } + ], + "GetBucketNotification": [ + { + "input": { + "Bucket": "examplebucket" + }, + "output": { + "QueueConfiguration": { + "Event": "s3:ObjectCreated:Put", + "Events": [ + "s3:ObjectCreated:Put" + ], + "Id": "MDQ2OGQ4NDEtOTBmNi00YTM4LTk0NzYtZDIwN2I3NWQ1NjIx", + "Queue": "arn:aws:sqs:us-east-1:acct-id:S3ObjectCreatedEventQueue" + }, + "TopicConfiguration": { + "Event": "s3:ObjectCreated:Copy", + "Events": [ + "s3:ObjectCreated:Copy" + ], + "Id": "YTVkMWEzZGUtNTY1NS00ZmE2LWJjYjktMmRlY2QwODFkNTJi", + "Topic": "arn:aws:sns:us-east-1:acct-id:S3ObjectCreatedEventTopic" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns notification configuration set on a bucket.", + "id": "to-get-notification-configuration-set-on-a-bucket-1481594028667", + "title": "To get notification configuration set on a bucket" + }, + { + "input": { + "Bucket": "examplebucket" + }, + "output": { + "QueueConfiguration": { + "Event": "s3:ObjectCreated:Put", + "Events": [ + "s3:ObjectCreated:Put" + ], + "Id": "MDQ2OGQ4NDEtOTBmNi00YTM4LTk0NzYtZDIwN2I3NWQ1NjIx", + "Queue": "arn:aws:sqs:us-east-1:acct-id:S3ObjectCreatedEventQueue" + }, + "TopicConfiguration": { + "Event": "s3:ObjectCreated:Copy", + "Events": [ + "s3:ObjectCreated:Copy" + ], + "Id": "YTVkMWEzZGUtNTY1NS00ZmE2LWJjYjktMmRlY2QwODFkNTJi", + "Topic": "arn:aws:sns:us-east-1:acct-id:S3ObjectCreatedEventTopic" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns notification configuration set on a bucket.", + "id": "to-get-notification-configuration-set-on-a-bucket-1481594028667", + "title": "To get notification configuration set on a bucket" + } + ], + "GetBucketPolicy": [ + { + "input": { + "Bucket": "examplebucket" + }, + "output": { + "Policy": "{\"Version\":\"2008-10-17\",\"Id\":\"LogPolicy\",\"Statement\":[{\"Sid\":\"Enables the log delivery group to publish logs to your bucket \",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"111122223333\"},\"Action\":[\"s3:GetBucketAcl\",\"s3:GetObjectAcl\",\"s3:PutObject\"],\"Resource\":[\"arn:aws:s3:::policytest1/*\",\"arn:aws:s3:::policytest1\"]}]}" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns bucket policy associated with a bucket.", + "id": "to-get-bucket-policy-1481595098424", + "title": "To get bucket policy" + } + ], + "GetBucketReplication": [ + { + "input": { + "Bucket": "examplebucket" + }, + "output": { + "ReplicationConfiguration": { + "Role": "arn:aws:iam::acct-id:role/example-role", + "Rules": [ + { + "Destination": { + "Bucket": "arn:aws:s3:::destination-bucket" + }, + "ID": "MWIwNTkwZmItMTE3MS00ZTc3LWJkZDEtNzRmODQwYzc1OTQy", + "Prefix": "Tax", + "Status": "Enabled" + } + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns replication configuration set on a bucket.", + "id": "to-get-replication-configuration-set-on-a-bucket-1481593597175", + "title": "To get replication configuration set on a bucket" + } + ], + "GetBucketRequestPayment": [ + { + "input": { + "Bucket": "examplebucket" + }, + "output": { + "Payer": "BucketOwner" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example retrieves bucket versioning configuration.", + "id": "to-get-bucket-versioning-configuration-1483037183929", + "title": "To get bucket versioning configuration" + } + ], + "GetBucketTagging": [ + { + "input": { + "Bucket": "examplebucket" + }, + "output": { + "TagSet": [ + { + "Key": "key1", + "Value": "value1" + }, + { + "Key": "key2", + "Value": "value2" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns tag set associated with a bucket", + "id": "to-get-tag-set-associated-with-a-bucket-1481593232107", + "title": "To get tag set associated with a bucket" + } + ], + "GetBucketVersioning": [ + { + "input": { + "Bucket": "examplebucket" + }, + "output": { + "MFADelete": "Disabled", + "Status": "Enabled" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example retrieves bucket versioning configuration.", + "id": "to-get-bucket-versioning-configuration-1483037183929", + "title": "To get bucket versioning configuration" + } + ], + "GetBucketWebsite": [ + { + "input": { + "Bucket": "examplebucket" + }, + "output": { + "ErrorDocument": { + "Key": "error.html" + }, + "IndexDocument": { + "Suffix": "index.html" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example retrieves website configuration of a bucket.", + "id": "to-get-bucket-website-configuration-1483037016926", + "title": "To get bucket website configuration" + } + ], + "GetObject": [ + { + "input": { + "Bucket": "examplebucket", + "Key": "HappyFace.jpg" + }, + "output": { + "AcceptRanges": "bytes", + "ContentLength": "3191", + "ContentType": "image/jpeg", + "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"", + "LastModified": "Thu, 15 Dec 2016 01:19:41 GMT", + "Metadata": { + }, + "TagCount": 2, + "VersionId": "null" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example retrieves an object for an S3 bucket.", + "id": "to-retrieve-an-object-1481827837012", + "title": "To retrieve an object" + }, + { + "input": { + "Bucket": "examplebucket", + "Key": "SampleFile.txt", + "Range": "bytes=0-9" + }, + "output": { + "AcceptRanges": "bytes", + "ContentLength": "10", + "ContentRange": "bytes 0-9/43", + "ContentType": "text/plain", + "ETag": "\"0d94420ffd0bc68cd3d152506b97a9cc\"", + "LastModified": "Thu, 09 Oct 2014 22:57:28 GMT", + "Metadata": { + }, + "VersionId": "null" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example retrieves an object for an S3 bucket. The request specifies the range header to retrieve a specific byte range.", + "id": "to-retrieve-a-byte-range-of-an-object--1481832674603", + "title": "To retrieve a byte range of an object " + } + ], + "GetObjectAcl": [ + { + "input": { + "Bucket": "examplebucket", + "Key": "HappyFace.jpg" + }, + "output": { + "Grants": [ + { + "Grantee": { + "DisplayName": "owner-display-name", + "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc", + "Type": "CanonicalUser" + }, + "Permission": "WRITE" + }, + { + "Grantee": { + "DisplayName": "owner-display-name", + "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc", + "Type": "CanonicalUser" + }, + "Permission": "WRITE_ACP" + }, + { + "Grantee": { + "DisplayName": "owner-display-name", + "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc", + "Type": "CanonicalUser" + }, + "Permission": "READ" + }, + { + "Grantee": { + "DisplayName": "owner-display-name", + "ID": "852b113eexamplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc", + "Type": "CanonicalUser" + }, + "Permission": "READ_ACP" + } + ], + "Owner": { + "DisplayName": "owner-display-name", + "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example retrieves access control list (ACL) of an object.", + "id": "to-retrieve-object-acl-1481833557740", + "title": "To retrieve object ACL" + } + ], + "GetObjectTagging": [ + { + "input": { + "Bucket": "examplebucket", + "Key": "HappyFace.jpg" + }, + "output": { + "TagSet": [ + { + "Key": "Key4", + "Value": "Value4" + }, + { + "Key": "Key3", + "Value": "Value3" + } + ], + "VersionId": "null" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example retrieves tag set of an object.", + "id": "to-retrieve-tag-set-of-an-object-1481833847896", + "title": "To retrieve tag set of an object" + }, + { + "input": { + "Bucket": "examplebucket", + "Key": "exampleobject", + "VersionId": "ydlaNkwWm0SfKJR.T1b1fIdPRbldTYRI" + }, + "output": { + "TagSet": [ + { + "Key": "Key1", + "Value": "Value1" + } + ], + "VersionId": "ydlaNkwWm0SfKJR.T1b1fIdPRbldTYRI" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example retrieves tag set of an object. The request specifies object version.", + "id": "to-retrieve-tag-set-of-a-specific-object-version-1483400283663", + "title": "To retrieve tag set of a specific object version" + } + ], + "GetObjectTorrent": [ + { + "input": { + "Bucket": "examplebucket", + "Key": "HappyFace.jpg" + }, + "output": { + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example retrieves torrent files of an object.", + "id": "to-retrieve-torrent-files-for-an-object-1481834115959", + "title": "To retrieve torrent files for an object" + } + ], + "HeadBucket": [ + { + "input": { + "Bucket": "acl1" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This operation checks to see if a bucket exists.", + "id": "to-determine-if-bucket-exists-1473110292262", + "title": "To determine if bucket exists" + } + ], + "HeadObject": [ + { + "input": { + "Bucket": "examplebucket", + "Key": "HappyFace.jpg" + }, + "output": { + "AcceptRanges": "bytes", + "ContentLength": "3191", + "ContentType": "image/jpeg", + "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"", + "LastModified": "Thu, 15 Dec 2016 01:19:41 GMT", + "Metadata": { + }, + "VersionId": "null" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example retrieves an object metadata.", + "id": "to-retrieve-metadata-of-an-object-without-returning-the-object-itself-1481834820480", + "title": "To retrieve metadata of an object without returning the object itself" + } + ], + "ListMultipartUploads": [ + { + "input": { + "Bucket": "examplebucket" + }, + "output": { + "Uploads": [ + { + "Initiated": "2014-05-01T05:40:58.000Z", + "Initiator": { + "DisplayName": "display-name", + "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc" + }, + "Key": "JavaFile", + "Owner": { + "DisplayName": "display-name", + "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc" + }, + "StorageClass": "STANDARD", + "UploadId": "examplelUa.CInXklLQtSMJITdUnoZ1Y5GACB5UckOtspm5zbDMCkPF_qkfZzMiFZ6dksmcnqxJyIBvQMG9X9Q--" + }, + { + "Initiated": "2014-05-01T05:41:27.000Z", + "Initiator": { + "DisplayName": "display-name", + "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc" + }, + "Key": "JavaFile", + "Owner": { + "DisplayName": "display-name", + "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc" + }, + "StorageClass": "STANDARD", + "UploadId": "examplelo91lv1iwvWpvCiJWugw2xXLPAD7Z8cJyX9.WiIRgNrdG6Ldsn.9FtS63TCl1Uf5faTB.1U5Ckcbmdw--" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example lists in-progress multipart uploads on a specific bucket.", + "id": "to-list-in-progress-multipart-uploads-on-a-bucket-1481852775260", + "title": "To list in-progress multipart uploads on a bucket" + }, + { + "input": { + "Bucket": "examplebucket", + "KeyMarker": "nextkeyfrompreviousresponse", + "MaxUploads": "2", + "UploadIdMarker": "valuefrompreviousresponse" + }, + "output": { + "Bucket": "acl1", + "IsTruncated": true, + "KeyMarker": "", + "MaxUploads": "2", + "NextKeyMarker": "someobjectkey", + "NextUploadIdMarker": "examplelo91lv1iwvWpvCiJWugw2xXLPAD7Z8cJyX9.WiIRgNrdG6Ldsn.9FtS63TCl1Uf5faTB.1U5Ckcbmdw--", + "UploadIdMarker": "", + "Uploads": [ + { + "Initiated": "2014-05-01T05:40:58.000Z", + "Initiator": { + "DisplayName": "ownder-display-name", + "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc" + }, + "Key": "JavaFile", + "Owner": { + "DisplayName": "mohanataws", + "ID": "852b113e7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc" + }, + "StorageClass": "STANDARD", + "UploadId": "gZ30jIqlUa.CInXklLQtSMJITdUnoZ1Y5GACB5UckOtspm5zbDMCkPF_qkfZzMiFZ6dksmcnqxJyIBvQMG9X9Q--" + }, + { + "Initiated": "2014-05-01T05:41:27.000Z", + "Initiator": { + "DisplayName": "ownder-display-name", + "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc" + }, + "Key": "JavaFile", + "Owner": { + "DisplayName": "ownder-display-name", + "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc" + }, + "StorageClass": "STANDARD", + "UploadId": "b7tZSqIlo91lv1iwvWpvCiJWugw2xXLPAD7Z8cJyX9.WiIRgNrdG6Ldsn.9FtS63TCl1Uf5faTB.1U5Ckcbmdw--" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example specifies the upload-id-marker and key-marker from previous truncated response to retrieve next setup of multipart uploads.", + "id": "list-next-set-of-multipart-uploads-when-previous-result-is-truncated-1482428106748", + "title": "List next set of multipart uploads when previous result is truncated" + } + ], + "ListObjectVersions": [ + { + "input": { + "Bucket": "examplebucket", + "Prefix": "HappyFace.jpg" + }, + "output": { + "Versions": [ + { + "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"", + "IsLatest": true, + "Key": "HappyFace.jpg", + "LastModified": "2016-12-15T01:19:41.000Z", + "Owner": { + "DisplayName": "owner-display-name", + "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc" + }, + "Size": 3191, + "StorageClass": "STANDARD", + "VersionId": "null" + }, + { + "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"", + "IsLatest": false, + "Key": "HappyFace.jpg", + "LastModified": "2016-12-13T00:58:26.000Z", + "Owner": { + "DisplayName": "owner-display-name", + "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc" + }, + "Size": 3191, + "StorageClass": "STANDARD", + "VersionId": "PHtexPGjH2y.zBgT8LmB7wwLI2mpbz.k" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example return versions of an object with specific key name prefix. The request limits the number of items returned to two. If there are are more than two object version, S3 returns NextToken in the response. You can specify this token value in your next request to fetch next set of object versions.", + "id": "to-list-object-versions-1481910996058", + "title": "To list object versions" + } + ], + "ListObjects": [ + { + "input": { + "Bucket": "examplebucket", + "MaxKeys": "2" + }, + "output": { + "Contents": [ + { + "ETag": "\"70ee1738b6b21e2c8a43f3a5ab0eee71\"", + "Key": "example1.jpg", + "LastModified": "2014-11-21T19:40:05.000Z", + "Owner": { + "DisplayName": "myname", + "ID": "12345example25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc" + }, + "Size": 11, + "StorageClass": "STANDARD" + }, + { + "ETag": "\"9c8af9a76df052144598c115ef33e511\"", + "Key": "example2.jpg", + "LastModified": "2013-11-15T01:10:49.000Z", + "Owner": { + "DisplayName": "myname", + "ID": "12345example25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc" + }, + "Size": 713193, + "StorageClass": "STANDARD" + } + ], + "NextMarker": "eyJNYXJrZXIiOiBudWxsLCAiYm90b190cnVuY2F0ZV9hbW91bnQiOiAyfQ==" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example list two objects in a bucket.", + "id": "to-list-objects-in-a-bucket-1473447646507", + "title": "To list objects in a bucket" + } + ], + "ListObjectsV2": [ + { + "input": { + "Bucket": "examplebucket", + "MaxKeys": "2" + }, + "output": { + "Contents": [ + { + "ETag": "\"70ee1738b6b21e2c8a43f3a5ab0eee71\"", + "Key": "happyface.jpg", + "LastModified": "2014-11-21T19:40:05.000Z", + "Size": 11, + "StorageClass": "STANDARD" + }, + { + "ETag": "\"becf17f89c30367a9a44495d62ed521a-1\"", + "Key": "test.jpg", + "LastModified": "2014-05-02T04:51:50.000Z", + "Size": 4192256, + "StorageClass": "STANDARD" + } + ], + "IsTruncated": true, + "KeyCount": "2", + "MaxKeys": "2", + "Name": "examplebucket", + "NextContinuationToken": "1w41l63U0xa8q7smH50vCxyTQqdxo69O3EmK28Bi5PcROI4wI/EyIJg==", + "Prefix": "" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example retrieves object list. The request specifies max keys to limit response to include only 2 object keys. ", + "id": "to-get-object-list", + "title": "To get object list" + } + ], + "ListParts": [ + { + "input": { + "Bucket": "examplebucket", + "Key": "bigobject", + "UploadId": "example7YPBOJuoFiQ9cz4P3Pe6FIZwO4f7wN93uHsNBEw97pl5eNwzExg0LAT2dUN91cOmrEQHDsP3WA60CEg--" + }, + "output": { + "Initiator": { + "DisplayName": "owner-display-name", + "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc" + }, + "Owner": { + "DisplayName": "owner-display-name", + "ID": "examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484be31bebcc" + }, + "Parts": [ + { + "ETag": "\"d8c2eafd90c266e19ab9dcacc479f8af\"", + "LastModified": "2016-12-16T00:11:42.000Z", + "PartNumber": "1", + "Size": 26246026 + }, + { + "ETag": "\"d8c2eafd90c266e19ab9dcacc479f8af\"", + "LastModified": "2016-12-16T00:15:01.000Z", + "PartNumber": "2", + "Size": 26246026 + } + ], + "StorageClass": "STANDARD" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example lists parts uploaded for a specific multipart upload.", + "id": "to-list-parts-of-a-multipart-upload-1481852006923", + "title": "To list parts of a multipart upload." + } + ], + "PutBucketAcl": [ + { + "input": { + "Bucket": "examplebucket", + "GrantFullControl": "id=examplee7a2f25102679df27bb0ae12b3f85be6f290b936c4393484", + "GrantWrite": "uri=http://acs.amazonaws.com/groups/s3/LogDelivery" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example replaces existing ACL on a bucket. The ACL grants the bucket owner (specified using the owner ID) and write permission to the LogDelivery group. Because this is a replace operation, you must specify all the grants in your request. To incrementally add or remove ACL grants, you might use the console.", + "id": "put-bucket-acl-1482260397033", + "title": "Put bucket acl" + } + ], + "PutBucketCors": [ + { + "input": { + "Bucket": "", + "CORSConfiguration": { + "CORSRules": [ + { + "AllowedHeaders": [ + "*" + ], + "AllowedMethods": [ + "PUT", + "POST", + "DELETE" + ], + "AllowedOrigins": [ + "http://www.example.com" + ], + "ExposeHeaders": [ + "x-amz-server-side-encryption" + ], + "MaxAgeSeconds": 3000 + }, + { + "AllowedHeaders": [ + "Authorization" + ], + "AllowedMethods": [ + "GET" + ], + "AllowedOrigins": [ + "*" + ], + "MaxAgeSeconds": 3000 + } + ] + }, + "ContentMD5": "" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example enables PUT, POST, and DELETE requests from www.example.com, and enables GET requests from any domain.", + "id": "to-set-cors-configuration-on-a-bucket-1483037818805", + "title": "To set cors configuration on a bucket." + } + ], + "PutBucketLifecycleConfiguration": [ + { + "input": { + "Bucket": "examplebucket", + "LifecycleConfiguration": { + "Rules": [ + { + "Expiration": { + "Days": 3650 + }, + "Filter": { + "Prefix": "documents/" + }, + "ID": "TestOnly", + "Status": "Enabled", + "Transitions": [ + { + "Days": 365, + "StorageClass": "GLACIER" + } + ] + } + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example replaces existing lifecycle configuration, if any, on the specified bucket. ", + "id": "put-bucket-lifecycle-1482264533092", + "title": "Put bucket lifecycle" + } + ], + "PutBucketLogging": [ + { + "input": { + "Bucket": "sourcebucket", + "BucketLoggingStatus": { + "LoggingEnabled": { + "TargetBucket": "targetbucket", + "TargetGrants": [ + { + "Grantee": { + "Type": "Group", + "URI": "http://acs.amazonaws.com/groups/global/AllUsers" + }, + "Permission": "READ" + } + ], + "TargetPrefix": "MyBucketLogs/" + } + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example sets logging policy on a bucket. For the Log Delivery group to deliver logs to the destination bucket, it needs permission for the READ_ACP action which the policy grants.", + "id": "set-logging-configuration-for-a-bucket-1482269119909", + "title": "Set logging configuration for a bucket" + } + ], + "PutBucketNotificationConfiguration": [ + { + "input": { + "Bucket": "examplebucket", + "NotificationConfiguration": { + "TopicConfigurations": [ + { + "Events": [ + "s3:ObjectCreated:*" + ], + "TopicArn": "arn:aws:sns:us-west-2:123456789012:s3-notification-topic" + } + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example sets notification configuration on a bucket to publish the object created events to an SNS topic.", + "id": "set-notification-configuration-for-a-bucket-1482270296426", + "title": "Set notification configuration for a bucket" + } + ], + "PutBucketPolicy": [ + { + "input": { + "Bucket": "examplebucket", + "Policy": "{\"Version\": \"2012-10-17\", \"Statement\": [{ \"Sid\": \"id-1\",\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"arn:aws:iam::123456789012:root\"}, \"Action\": [ \"s3:PutObject\",\"s3:PutObjectAcl\"], \"Resource\": [\"arn:aws:s3:::acl3/*\" ] } ]}" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example sets a permission policy on a bucket.", + "id": "set-bucket-policy-1482448903302", + "title": "Set bucket policy" + } + ], + "PutBucketReplication": [ + { + "input": { + "Bucket": "examplebucket", + "ReplicationConfiguration": { + "Role": "arn:aws:iam::123456789012:role/examplerole", + "Rules": [ + { + "Destination": { + "Bucket": "arn:aws:s3:::destinationbucket", + "StorageClass": "STANDARD" + }, + "Prefix": "", + "Status": "Enabled" + } + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example sets replication configuration on a bucket.", + "id": "id-1", + "title": "Set replication configuration on a bucket" + } + ], + "PutBucketRequestPayment": [ + { + "input": { + "Bucket": "examplebucket", + "RequestPaymentConfiguration": { + "Payer": "Requester" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example sets request payment configuration on a bucket so that person requesting the download is charged.", + "id": "set-request-payment-configuration-on-a-bucket-1482343596680", + "title": "Set request payment configuration on a bucket." + } + ], + "PutBucketTagging": [ + { + "input": { + "Bucket": "examplebucket", + "Tagging": { + "TagSet": [ + { + "Key": "Key1", + "Value": "Value1" + }, + { + "Key": "Key2", + "Value": "Value2" + } + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example sets tags on a bucket. Any existing tags are replaced.", + "id": "set-tags-on-a-bucket-1482346269066", + "title": "Set tags on a bucket" + } + ], + "PutBucketVersioning": [ + { + "input": { + "Bucket": "examplebucket", + "VersioningConfiguration": { + "MFADelete": "Disabled", + "Status": "Enabled" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example sets versioning configuration on bucket. The configuration enables versioning on the bucket.", + "id": "set-versioning-configuration-on-a-bucket-1482344186279", + "title": "Set versioning configuration on a bucket" + } + ], + "PutBucketWebsite": [ + { + "input": { + "Bucket": "examplebucket", + "ContentMD5": "", + "WebsiteConfiguration": { + "ErrorDocument": { + "Key": "error.html" + }, + "IndexDocument": { + "Suffix": "index.html" + } + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example adds website configuration to a bucket.", + "id": "set-website-configuration-on-a-bucket-1482346836261", + "title": "Set website configuration on a bucket" + } + ], + "PutObject": [ + { + "input": { + "Body": "filetoupload", + "Bucket": "examplebucket", + "Key": "objectkey" + }, + "output": { + "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"", + "VersionId": "Bvq0EDKxOcXLJXNo_Lkz37eM3R4pfzyQ" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example creates an object. If the bucket is versioning enabled, S3 returns version ID in response.", + "id": "to-create-an-object-1483147613675", + "title": "To create an object." + }, + { + "input": { + "Body": "HappyFace.jpg", + "Bucket": "examplebucket", + "Key": "HappyFace.jpg", + "ServerSideEncryption": "AES256", + "StorageClass": "STANDARD_IA" + }, + "output": { + "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"", + "ServerSideEncryption": "AES256", + "VersionId": "CG612hodqujkf8FaaNfp8U..FIhLROcp" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example uploads an object. The request specifies optional request headers to directs S3 to use specific storage class and use server-side encryption.", + "id": "to-upload-an-object-(specify-optional-headers)", + "title": "To upload an object (specify optional headers)" + }, + { + "input": { + "ACL": "authenticated-read", + "Body": "filetoupload", + "Bucket": "examplebucket", + "Key": "exampleobject" + }, + "output": { + "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"", + "VersionId": "Kirh.unyZwjQ69YxcQLA8z4F5j3kJJKr" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example uploads and object. The request specifies optional canned ACL (access control list) to all READ access to authenticated users. If the bucket is versioning enabled, S3 returns version ID in response.", + "id": "to-upload-an-object-and-specify-canned-acl-1483397779571", + "title": "To upload an object and specify canned ACL." + }, + { + "input": { + "Body": "HappyFace.jpg", + "Bucket": "examplebucket", + "Key": "HappyFace.jpg" + }, + "output": { + "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"", + "VersionId": "tpf3zF08nBplQK1XLOefGskR7mGDwcDk" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example uploads an object to a versioning-enabled bucket. The source file is specified using Windows file syntax. S3 returns VersionId of the newly created object.", + "id": "to-upload-an-object-1481760101010", + "title": "To upload an object" + }, + { + "input": { + "Body": "filetoupload", + "Bucket": "examplebucket", + "Key": "exampleobject", + "Metadata": { + "metadata1": "value1", + "metadata2": "value2" + } + }, + "output": { + "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"", + "VersionId": "pSKidl4pHBiNwukdbcPXAIs.sshFFOc0" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example creates an object. The request also specifies optional metadata. If the bucket is versioning enabled, S3 returns version ID in response.", + "id": "to-upload-object-and-specify-user-defined-metadata-1483396974757", + "title": "To upload object and specify user-defined metadata" + }, + { + "input": { + "Body": "c:\\HappyFace.jpg", + "Bucket": "examplebucket", + "Key": "HappyFace.jpg", + "Tagging": "key1=value1&key2=value2" + }, + "output": { + "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"", + "VersionId": "psM2sYY4.o1501dSx8wMvnkOzSBB.V4a" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example uploads an object. The request specifies optional object tags. The bucket is versioned, therefore S3 returns version ID of the newly created object.", + "id": "to-upload-an-object-and-specify-optional-tags-1481762310955", + "title": "To upload an object and specify optional tags" + }, + { + "input": { + "Body": "filetoupload", + "Bucket": "examplebucket", + "Key": "exampleobject", + "ServerSideEncryption": "AES256", + "Tagging": "key1=value1&key2=value2" + }, + "output": { + "ETag": "\"6805f2cfc46c0f04559748bb039d69ae\"", + "ServerSideEncryption": "AES256", + "VersionId": "Ri.vC6qVlA4dEnjgRV4ZHsHoFIjqEMNt" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example uploads and object. The request specifies the optional server-side encryption option. The request also specifies optional object tags. If the bucket is versioning enabled, S3 returns version ID in response.", + "id": "to-upload-an-object-and-specify-server-side-encryption-and-object-tags-1483398331831", + "title": "To upload an object and specify server-side encryption and object tags" + } + ], + "PutObjectAcl": [ + { + "input": { + "AccessControlPolicy": { + }, + "Bucket": "examplebucket", + "GrantFullControl": "emailaddress=user1@example.com,emailaddress=user2@example.com", + "GrantRead": "uri=http://acs.amazonaws.com/groups/global/AllUsers", + "Key": "HappyFace.jpg" + }, + "output": { + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example adds grants to an object ACL. The first permission grants user1 and user2 FULL_CONTROL and the AllUsers group READ permission.", + "id": "to-grant-permissions-using-object-acl-1481835549285", + "title": "To grant permissions using object ACL" + } + ], + "PutObjectTagging": [ + { + "input": { + "Bucket": "examplebucket", + "Key": "HappyFace.jpg", + "Tagging": { + "TagSet": [ + { + "Key": "Key3", + "Value": "Value3" + }, + { + "Key": "Key4", + "Value": "Value4" + } + ] + } + }, + "output": { + "VersionId": "null" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example adds tags to an existing object.", + "id": "to-add-tags-to-an-existing-object-1481764668793", + "title": "To add tags to an existing object" + } + ], + "RestoreObject": [ + { + "input": { + "Bucket": "examplebucket", + "Key": "archivedobjectkey", + "RestoreRequest": { + "Days": 1, + "GlacierJobParameters": { + "Tier": "Expedited" + } + } + }, + "output": { + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example restores for one day an archived copy of an object back into Amazon S3 bucket.", + "id": "to-restore-an-archived-object-1483049329953", + "title": "To restore an archived object" + } + ], + "UploadPart": [ + { + "input": { + "Body": "fileToUpload", + "Bucket": "examplebucket", + "Key": "examplelargeobject", + "PartNumber": "1", + "UploadId": "xadcOB_7YPBOJuoFiQ9cz4P3Pe6FIZwO4f7wN93uHsNBEw97pl5eNwzExg0LAT2dUN91cOmrEQHDsP3WA60CEg--" + }, + "output": { + "ETag": "\"d8c2eafd90c266e19ab9dcacc479f8af\"" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example uploads part 1 of a multipart upload. The example specifies a file name for the part data. The Upload ID is same that is returned by the initiate multipart upload.", + "id": "to-upload-a-part-1481847914943", + "title": "To upload a part" + } + ], + "UploadPartCopy": [ + { + "input": { + "Bucket": "examplebucket", + "CopySource": "/bucketname/sourceobjectkey", + "Key": "examplelargeobject", + "PartNumber": "1", + "UploadId": "exampleuoh_10OhKhT7YukE9bjzTPRiuaCotmZM_pFngJFir9OZNrSr5cWa3cq3LZSUsfjI4FI7PkP91We7Nrw--" + }, + "output": { + "CopyPartResult": { + "ETag": "\"b0c6f0e7e054ab8fa2536a2677f8734d\"", + "LastModified": "2016-12-29T21:24:43.000Z" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example uploads a part of a multipart upload by copying data from an existing object as data source.", + "id": "to-upload-a-part-by-copying-data-from-an-existing-object-as-data-source-1483046746348", + "title": "To upload a part by copying data from an existing object as data source" + }, + { + "input": { + "Bucket": "examplebucket", + "CopySource": "/bucketname/sourceobjectkey", + "CopySourceRange": "bytes=1-100000", + "Key": "examplelargeobject", + "PartNumber": "2", + "UploadId": "exampleuoh_10OhKhT7YukE9bjzTPRiuaCotmZM_pFngJFir9OZNrSr5cWa3cq3LZSUsfjI4FI7PkP91We7Nrw--" + }, + "output": { + "CopyPartResult": { + "ETag": "\"65d16d19e65a7508a51f043180edcc36\"", + "LastModified": "2016-12-29T21:44:28.000Z" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example uploads a part of a multipart upload by copying a specified byte range from an existing object as data source.", + "id": "to-upload-a-part-by-copying-byte-range-from-an-existing-object-as-data-source-1483048068594", + "title": "To upload a part by copying byte range from an existing object as data source" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/s3/2006-03-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/s3/2006-03-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..b1b432071f5de20236b02ecfbc791f4eb282e7bb --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/s3/2006-03-01/paginators-1.json @@ -0,0 +1,76 @@ +{ + "pagination": { + "ListMultipartUploads": { + "limit_key": "MaxUploads", + "more_results": "IsTruncated", + "output_token": [ + "NextKeyMarker", + "NextUploadIdMarker" + ], + "input_token": [ + "KeyMarker", + "UploadIdMarker" + ], + "result_key": [ + "Uploads", + "CommonPrefixes" + ] + }, + "ListObjectVersions": { + "more_results": "IsTruncated", + "limit_key": "MaxKeys", + "output_token": [ + "NextKeyMarker", + "NextVersionIdMarker" + ], + "input_token": [ + "KeyMarker", + "VersionIdMarker" + ], + "result_key": [ + "Versions", + "DeleteMarkers", + "CommonPrefixes" + ] + }, + "ListObjects": { + "more_results": "IsTruncated", + "limit_key": "MaxKeys", + "output_token": "NextMarker || Contents[-1].Key", + "input_token": "Marker", + "result_key": [ + "Contents", + "CommonPrefixes" + ] + }, + "ListObjectsV2": { + "more_results": "IsTruncated", + "limit_key": "MaxKeys", + "output_token": "NextContinuationToken", + "input_token": "ContinuationToken", + "result_key": [ + "Contents", + "CommonPrefixes" + ] + }, + "ListParts": { + "more_results": "IsTruncated", + "limit_key": "MaxParts", + "output_token": "NextPartNumberMarker", + "input_token": "PartNumberMarker", + "result_key": "Parts" + }, + "ListDirectoryBuckets": { + "input_token": "ContinuationToken", + "limit_key": "MaxDirectoryBuckets", + "output_token": "ContinuationToken", + "result_key": "Buckets" + }, + "ListBuckets": { + "input_token": "ContinuationToken", + "limit_key": "MaxBuckets", + "output_token": "ContinuationToken", + "result_key": "Buckets" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/s3/2006-03-01/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/s3/2006-03-01/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..39e13606ef515b6f4fdfc0c058c7b0570527b676 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/s3/2006-03-01/paginators-1.sdk-extras.json @@ -0,0 +1,46 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "ListBuckets": { + "non_aggregate_keys": [ + "Owner", + "Prefix" + ] + }, + "ListMultipartUploads": { + "non_aggregate_keys": [ + "RequestCharged", + "Prefix" + ] + }, + "ListObjectVersions": { + "non_aggregate_keys": [ + "RequestCharged", + "Prefix" + ] + }, + "ListObjects": { + "non_aggregate_keys": [ + "RequestCharged", + "Prefix" + ] + }, + "ListObjectsV2": { + "non_aggregate_keys": [ + "RequestCharged", + "Prefix" + ] + }, + "ListParts": { + "non_aggregate_keys": [ + "ChecksumAlgorithm", + "Initiator", + "Owner", + "StorageClass", + "ChecksumType" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/s3/2006-03-01/service-2.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/s3/2006-03-01/service-2.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..d04e9d0b451c282ce22dede0d86e0f753a3869c8 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/s3/2006-03-01/service-2.sdk-extras.json @@ -0,0 +1,8 @@ +{ + "version": 1.0, + "merge": { + "shapes": { + "Expires":{"type":"timestamp"} + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/s3/2006-03-01/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/s3/2006-03-01/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..b508a8f5b06f0fe24eade4a2c328f98e51623c1d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/s3/2006-03-01/waiters-2.json @@ -0,0 +1,73 @@ +{ + "version": 2, + "waiters": { + "BucketExists": { + "delay": 5, + "operation": "HeadBucket", + "maxAttempts": 20, + "acceptors": [ + { + "expected": 200, + "matcher": "status", + "state": "success" + }, + { + "expected": 301, + "matcher": "status", + "state": "success" + }, + { + "expected": 403, + "matcher": "status", + "state": "success" + }, + { + "expected": 404, + "matcher": "status", + "state": "retry" + } + ] + }, + "BucketNotExists": { + "delay": 5, + "operation": "HeadBucket", + "maxAttempts": 20, + "acceptors": [ + { + "expected": 404, + "matcher": "status", + "state": "success" + } + ] + }, + "ObjectExists": { + "delay": 5, + "operation": "HeadObject", + "maxAttempts": 20, + "acceptors": [ + { + "expected": 200, + "matcher": "status", + "state": "success" + }, + { + "expected": 404, + "matcher": "status", + "state": "retry" + } + ] + }, + "ObjectNotExists": { + "delay": 5, + "operation": "HeadObject", + "maxAttempts": 20, + "acceptors": [ + { + "expected": 404, + "matcher": "status", + "state": "success" + } + ] + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/s3outposts/2017-07-25/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/s3outposts/2017-07-25/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/s3outposts/2017-07-25/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/s3outposts/2017-07-25/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/s3outposts/2017-07-25/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..5a8fa86cc79d818cc326c7c0ab302a22fdbca23c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/s3outposts/2017-07-25/paginators-1.json @@ -0,0 +1,22 @@ +{ + "pagination": { + "ListEndpoints": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Endpoints" + }, + "ListSharedEndpoints": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Endpoints" + }, + "ListOutpostsWithS3": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Outposts" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/s3vectors/2025-07-15/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/s3vectors/2025-07-15/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..90e3363f693d555e637d7569642640c83e456660 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/s3vectors/2025-07-15/paginators-1.json @@ -0,0 +1,22 @@ +{ + "pagination": { + "ListIndexes": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "indexes" + }, + "ListVectorBuckets": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "vectorBuckets" + }, + "ListVectors": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "vectors" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/s3vectors/2025-07-15/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/s3vectors/2025-07-15/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/s3vectors/2025-07-15/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/sagemaker-a2i-runtime/2019-11-07/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/sagemaker-a2i-runtime/2019-11-07/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/sagemaker-a2i-runtime/2019-11-07/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/sagemaker-a2i-runtime/2019-11-07/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/sagemaker-a2i-runtime/2019-11-07/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..b19128c2626af09e3dd8b0ced2a382caac7f93f4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/sagemaker-a2i-runtime/2019-11-07/paginators-1.json @@ -0,0 +1,10 @@ +{ + "pagination": { + "ListHumanLoops": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "HumanLoopSummaries" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/sagemaker-geospatial/2020-05-27/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/sagemaker-geospatial/2020-05-27/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..8802d9431cb5ce9013c69b32d176f60dd410ac2f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/sagemaker-geospatial/2020-05-27/paginators-1.json @@ -0,0 +1,22 @@ +{ + "pagination": { + "ListEarthObservationJobs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "EarthObservationJobSummaries" + }, + "ListRasterDataCollections": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "RasterDataCollectionSummaries" + }, + "ListVectorEnrichmentJobs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "VectorEnrichmentJobSummaries" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/sagemaker-runtime/2017-05-13/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/sagemaker-runtime/2017-05-13/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/sagemaker-runtime/2017-05-13/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/sagemaker-runtime/2017-05-13/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/sagemaker-runtime/2017-05-13/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/sagemaker-runtime/2017-05-13/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/savingsplans/2019-06-28/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/savingsplans/2019-06-28/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/savingsplans/2019-06-28/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/savingsplans/2019-06-28/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/savingsplans/2019-06-28/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/savingsplans/2019-06-28/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/sdk-default-configuration.json b/.venv/lib/python3.13/site-packages/botocore/data/sdk-default-configuration.json new file mode 100644 index 0000000000000000000000000000000000000000..3db13b26cc5e9d56882479c603a2a7cbd8721cb1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/sdk-default-configuration.json @@ -0,0 +1,55 @@ +{ + "version": 1, + "base": { + "retryMode": "standard", + "stsRegionalEndpoints": "regional", + "s3UsEast1RegionalEndpoints": "regional", + "connectTimeoutInMillis": 1100, + "tlsNegotiationTimeoutInMillis": 1100 + }, + "modes": { + "standard": { + "connectTimeoutInMillis": { + "override": 3100 + }, + "tlsNegotiationTimeoutInMillis": { + "override": 3100 + } + }, + "in-region": { + }, + "cross-region": { + "connectTimeoutInMillis": { + "override": 3100 + }, + "tlsNegotiationTimeoutInMillis": { + "override": 3100 + } + }, + "mobile": { + "connectTimeoutInMillis": { + "override": 30000 + }, + "tlsNegotiationTimeoutInMillis": { + "override": 30000 + } + } + }, + "documentation": { + "modes": { + "standard": "

The STANDARD mode provides the latest recommended default values that should be safe to run in most scenarios

Note that the default values vended from this mode might change as best practices may evolve. As a result, it is encouraged to perform tests when upgrading the SDK

", + "in-region": "

The IN_REGION mode builds on the standard mode and includes optimization tailored for applications which call AWS services from within the same AWS region

Note that the default values vended from this mode might change as best practices may evolve. As a result, it is encouraged to perform tests when upgrading the SDK

", + "cross-region": "

The CROSS_REGION mode builds on the standard mode and includes optimization tailored for applications which call AWS services in a different region

Note that the default values vended from this mode might change as best practices may evolve. As a result, it is encouraged to perform tests when upgrading the SDK

", + "mobile": "

The MOBILE mode builds on the standard mode and includes optimization tailored for mobile applications

Note that the default values vended from this mode might change as best practices may evolve. As a result, it is encouraged to perform tests when upgrading the SDK

", + "auto": "

The AUTO mode is an experimental mode that builds on the standard mode. The SDK will attempt to discover the execution environment to determine the appropriate settings automatically.

Note that the auto detection is heuristics-based and does not guarantee 100% accuracy. STANDARD mode will be used if the execution environment cannot be determined. The auto detection might query EC2 Instance Metadata service, which might introduce latency. Therefore we recommend choosing an explicit defaults_mode instead if startup latency is critical to your application

", + "legacy": "

The LEGACY mode provides default settings that vary per SDK and were used prior to establishment of defaults_mode

" + }, + "configuration": { + "retryMode": "

A retry mode specifies how the SDK attempts retries. See Retry Mode

", + "stsRegionalEndpoints": "

Specifies how the SDK determines the AWS service endpoint that it uses to talk to the AWS Security Token Service (AWS STS). See Setting STS Regional endpoints

", + "s3UsEast1RegionalEndpoints": "

Specifies how the SDK determines the AWS service endpoint that it uses to talk to the Amazon S3 for the us-east-1 region

", + "connectTimeoutInMillis": "

The amount of time after making an initial connection attempt on a socket, where if the client does not receive a completion of the connect handshake, the client gives up and fails the operation

", + "tlsNegotiationTimeoutInMillis": "

The maximum amount of time that a TLS handshake is allowed to take from the time the CLIENT HELLO message is sent to ethe time the client and server have fully negotiated ciphers and exchanged keys

" + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/secretsmanager/2017-10-17/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/secretsmanager/2017-10-17/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..43a3ec4fd46523d0d87a2d533ce45d070b14a8af --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/secretsmanager/2017-10-17/examples-1.json @@ -0,0 +1,596 @@ +{ + "version": "1.0", + "examples": { + "CancelRotateSecret": [ + { + "input": { + "SecretId": "MyTestDatabaseSecret" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Name": "Name" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to cancel rotation for a secret. The operation sets the RotationEnabled field to false and cancels all scheduled rotations. To resume scheduled rotations, you must re-enable rotation by calling the rotate-secret operation.", + "id": "to-cancel-scheduled-rotation-for-a-secret-1523996016032", + "title": "To cancel scheduled rotation for a secret" + } + ], + "CreateSecret": [ + { + "input": { + "ClientRequestToken": "EXAMPLE1-90ab-cdef-fedc-ba987SECRET1", + "Description": "My test database secret created with the CLI", + "Name": "MyTestDatabaseSecret", + "SecretString": "{\"username\":\"david\",\"password\":\"EXAMPLE-PASSWORD\"}" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Name": "MyTestDatabaseSecret", + "VersionId": "EXAMPLE1-90ab-cdef-fedc-ba987SECRET1" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to create a secret. The credentials stored in the encrypted secret value are retrieved from a file on disk named mycreds.json.", + "id": "to-create-a-basic-secret-1523996473658", + "title": "To create a basic secret" + } + ], + "DeleteResourcePolicy": [ + { + "input": { + "SecretId": "MyTestDatabaseSecret" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseMasterSecret-a1b2c3", + "Name": "MyTestDatabaseSecret" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to delete the resource-based policy that is attached to a secret.", + "id": "to-delete-the-resource-based-policy-attached-to-a-secret-1530209419204", + "title": "To delete the resource-based policy attached to a secret" + } + ], + "DeleteSecret": [ + { + "input": { + "RecoveryWindowInDays": 7, + "SecretId": "MyTestDatabaseSecret1" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "DeletionDate": "1524085349.095", + "Name": "MyTestDatabaseSecret" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to delete a secret. The secret stays in your account in a deprecated and inaccessible state until the recovery window ends. After the date and time in the DeletionDate response field has passed, you can no longer recover this secret with restore-secret.", + "id": "to-delete-a-secret-1523996905092", + "title": "To delete a secret" + } + ], + "DescribeSecret": [ + { + "input": { + "SecretId": "MyTestDatabaseSecret" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Description": "My test database secret", + "KmsKeyId": "arn:aws:kms:us-west-2:123456789012:key/EXAMPLE1-90ab-cdef-fedc-ba987KMSKEY1", + "LastAccessedDate": "1523923200", + "LastChangedDate": 1523477145.729, + "LastRotatedDate": 1525747253.72, + "Name": "MyTestDatabaseSecret", + "RotationEnabled": true, + "RotationLambdaARN": "arn:aws:lambda:us-west-2:123456789012:function:MyTestRotationLambda", + "RotationRules": { + "AutomaticallyAfterDays": 14, + "Duration": "2h", + "ScheduleExpression": "cron(0 16 1,15 * ? *)" + }, + "Tags": [ + { + "Key": "SecondTag", + "Value": "AnotherValue" + }, + { + "Key": "FirstTag", + "Value": "SomeValue" + } + ], + "VersionIdsToStages": { + "EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE": [ + "AWSPREVIOUS" + ], + "EXAMPLE2-90ab-cdef-fedc-ba987EXAMPLE": [ + "AWSCURRENT" + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to get the details about a secret.", + "id": "to-retrieve-the-details-of-a-secret-1524000138629", + "title": "To retrieve the details of a secret" + } + ], + "GetRandomPassword": [ + { + "input": { + "IncludeSpace": true, + "PasswordLength": 20, + "RequireEachIncludedType": true + }, + "output": { + "RandomPassword": "EXAMPLE-PASSWORD" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to request a randomly generated password. This example includes the optional flags to require spaces and at least one character of each included type. It specifies a length of 20 characters.", + "id": "to-generate-a-random-password-1524000546092", + "title": "To generate a random password" + } + ], + "GetResourcePolicy": [ + { + "input": { + "SecretId": "MyTestDatabaseSecret" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Name": "MyTestDatabaseSecret", + "ResourcePolicy": "{\n\"Version\":\"2012-10-17\",\n\"Statement\":[{\n\"Effect\":\"Allow\",\n\"Principal\":{\n\"AWS\":\"arn:aws:iam::123456789012:root\"\n},\n\"Action\":\"secretsmanager:GetSecretValue\",\n\"Resource\":\"*\"\n}]\n}" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to retrieve the resource-based policy that is attached to a secret.", + "id": "to-retrieve-the-resource-based-policy-attached-to-a-secret-1530209677536", + "title": "To retrieve the resource-based policy attached to a secret" + } + ], + "GetSecretValue": [ + { + "input": { + "SecretId": "MyTestDatabaseSecret" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "CreatedDate": 1523477145.713, + "Name": "MyTestDatabaseSecret", + "SecretString": "{\n \"username\":\"david\",\n \"password\":\"EXAMPLE-PASSWORD\"\n}\n", + "VersionId": "EXAMPLE1-90ab-cdef-fedc-ba987SECRET1", + "VersionStages": [ + "AWSPREVIOUS" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to retrieve a secret string value.", + "id": "to-retrieve-the-encrypted-secret-value-of-a-secret-1524000702484", + "title": "To retrieve the encrypted secret value of a secret" + } + ], + "ListSecretVersionIds": [ + { + "input": { + "IncludeDeprecated": true, + "SecretId": "MyTestDatabaseSecret" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Name": "MyTestDatabaseSecret", + "Versions": [ + { + "CreatedDate": 1523477145.713, + "VersionId": "EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE", + "VersionStages": [ + "AWSPREVIOUS" + ] + }, + { + "CreatedDate": 1523486221.391, + "VersionId": "EXAMPLE2-90ab-cdef-fedc-ba987EXAMPLE", + "VersionStages": [ + "AWSCURRENT" + ] + }, + { + "CreatedDate": 1511974462.36, + "VersionId": "EXAMPLE3-90ab-cdef-fedc-ba987EXAMPLE;" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to retrieve a list of all of the versions of a secret, including those without any staging labels.", + "id": "to-list-all-of-the-secret-versions-associated-with-a-secret-1524000999164", + "title": "To list all of the secret versions associated with a secret" + } + ], + "ListSecrets": [ + { + "input": { + }, + "output": { + "SecretList": [ + { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Description": "My test database secret", + "LastChangedDate": 1523477145.729, + "Name": "MyTestDatabaseSecret", + "SecretVersionsToStages": { + "EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE": [ + "AWSCURRENT" + ] + } + }, + { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret1-d4e5f6", + "Description": "Another secret created for a different database", + "LastChangedDate": 1523482025.685, + "Name": "MyTestDatabaseSecret1", + "SecretVersionsToStages": { + "EXAMPLE2-90ab-cdef-fedc-ba987EXAMPLE": [ + "AWSCURRENT" + ] + } + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to list all of the secrets in your account.", + "id": "to-list-the-secrets-in-your-account-1524001246087", + "title": "To list the secrets in your account" + } + ], + "PutResourcePolicy": [ + { + "input": { + "ResourcePolicy": "{\n\"Version\":\"2012-10-17\",\n\"Statement\":[{\n\"Effect\":\"Allow\",\n\"Principal\":{\n\"AWS\":\"arn:aws:iam::123456789012:root\"\n},\n\"Action\":\"secretsmanager:GetSecretValue\",\n\"Resource\":\"*\"\n}]\n}", + "SecretId": "MyTestDatabaseSecret" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Name": "MyTestDatabaseSecret" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to add a resource-based policy to a secret.", + "id": "to-add-a-resource-based-policy-to-a-secret-1530209881839", + "title": "To add a resource-based policy to a secret" + } + ], + "PutSecretValue": [ + { + "input": { + "ClientRequestToken": "EXAMPLE2-90ab-cdef-fedc-ba987EXAMPLE", + "SecretId": "MyTestDatabaseSecret", + "SecretString": "{\"username\":\"david\",\"password\":\"EXAMPLE-PASSWORD\"}" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Name": "MyTestDatabaseSecret", + "VersionId": "EXAMPLE2-90ab-cdef-fedc-ba987EXAMPLE", + "VersionStages": [ + "AWSCURRENT" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to create a new version of the secret. Alternatively, you can use the update-secret command.", + "id": "to-store-a-secret-value-in-a-new-version-of-a-secret-1524001393971", + "title": "To store a secret value in a new version of a secret" + } + ], + "RestoreSecret": [ + { + "input": { + "SecretId": "MyTestDatabaseSecret" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Name": "MyTestDatabaseSecret" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to restore a secret that you previously scheduled for deletion.", + "id": "to-restore-a-previously-deleted-secret-1524001513930", + "title": "To restore a previously deleted secret" + } + ], + "RotateSecret": [ + { + "input": { + "RotationLambdaARN": "arn:aws:lambda:us-west-2:123456789012:function:MyTestDatabaseRotationLambda", + "RotationRules": { + "Duration": "2h", + "ScheduleExpression": "cron(0 16 1,15 * ? *)" + }, + "SecretId": "MyTestDatabaseSecret" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Name": "MyTestDatabaseSecret", + "VersionId": "EXAMPLE2-90ab-cdef-fedc-ba987SECRET2" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example configures rotation for a secret using a cron expression. The first rotation happens immediately after the changes are stored in the secret. The rotation schedule is the first and 15th day of every month. The rotation window begins at 4:00 PM UTC and ends at 6:00 PM.", + "id": "to-configure-rotation-for-a-secret-1524001629475", + "title": "To configure rotation for a secret" + }, + { + "input": { + "SecretId": "MyTestDatabaseSecret" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Name": "MyTestDatabaseSecret", + "VersionId": "EXAMPLE2-90ab-cdef-fedc-ba987SECRET2" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example requests an immediate invocation of the secret's Lambda rotation function. It assumes that the specified secret already has rotation configured. The rotation function runs asynchronously in the background.", + "id": "to-request-an-immediate-rotation-for-a-secret-1524001949004", + "title": "To request an immediate rotation for a secret" + } + ], + "TagResource": [ + { + "input": { + "SecretId": "MyExampleSecret", + "Tags": [ + { + "Key": "FirstTag", + "Value": "SomeValue" + }, + { + "Key": "SecondTag", + "Value": "AnotherValue" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to attach two tags each with a Key and Value to a secret. There is no output from this API. To see the result, use the DescribeSecret operation.", + "id": "to-add-tags-to-a-secret-1524002106718", + "title": "To add tags to a secret" + } + ], + "UntagResource": [ + { + "input": { + "SecretId": "MyTestDatabaseSecret", + "TagKeys": [ + "FirstTag", + "SecondTag" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to remove two tags from a secret's metadata. For each, both the tag and the associated value are removed. There is no output from this API. To see the result, use the DescribeSecret operation.", + "id": "to-remove-tags-from-a-secret-1524002239065", + "title": "To remove tags from a secret" + } + ], + "UpdateSecret": [ + { + "input": { + "ClientRequestToken": "EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE", + "Description": "This is a new description for the secret.", + "SecretId": "MyTestDatabaseSecret" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Name": "MyTestDatabaseSecret" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to modify the description of a secret.", + "id": "to-update-the-description-of-a-secret-1524002349094", + "title": "To update the description of a secret" + }, + { + "input": { + "KmsKeyId": "arn:aws:kms:us-west-2:123456789012:key/EXAMPLE2-90ab-cdef-fedc-ba987EXAMPLE", + "SecretId": "MyTestDatabaseSecret" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Name": "MyTestDatabaseSecret" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example shows how to update the KMS customer managed key (CMK) used to encrypt the secret value. The KMS CMK must be in the same region as the secret.", + "id": "to-update-the-kms-key-associated-with-a-secret-1524002421563", + "title": "To update the KMS key associated with a secret" + }, + { + "input": { + "SecretId": "MyTestDatabaseSecret", + "SecretString": "{JSON STRING WITH CREDENTIALS}" + }, + "output": { + "ARN": "aws:arn:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Name": "MyTestDatabaseSecret", + "VersionId": "EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to create a new version of the secret by updating the SecretString field. Alternatively, you can use the put-secret-value operation.", + "id": "to-create-a-new-version-of-the-encrypted-secret-value-1524004651836", + "title": "To create a new version of the encrypted secret value" + } + ], + "UpdateSecretVersionStage": [ + { + "input": { + "MoveToVersionId": "EXAMPLE1-90ab-cdef-fedc-ba987SECRET1", + "SecretId": "MyTestDatabaseSecret", + "VersionStage": "STAGINGLABEL1" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Name": "MyTestDatabaseSecret" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows you how to add a staging label to a version of a secret. You can review the results by running the operation ListSecretVersionIds and viewing the VersionStages response field for the affected version.", + "id": "to-add-a-staging-label-attached-to-a-version-of-a-secret-1524004783841", + "title": "To add a staging label attached to a version of a secret" + }, + { + "input": { + "RemoveFromVersionId": "EXAMPLE1-90ab-cdef-fedc-ba987SECRET1", + "SecretId": "MyTestDatabaseSecret", + "VersionStage": "STAGINGLABEL1" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Name": "MyTestDatabaseSecret" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows you how to delete a staging label that is attached to a version of a secret. You can review the results by running the operation ListSecretVersionIds and viewing the VersionStages response field for the affected version.", + "id": "to-delete-a-staging-label-attached-to-a-version-of-a-secret-1524004862181", + "title": "To delete a staging label attached to a version of a secret" + }, + { + "input": { + "MoveToVersionId": "EXAMPLE2-90ab-cdef-fedc-ba987SECRET2", + "RemoveFromVersionId": "EXAMPLE1-90ab-cdef-fedc-ba987SECRET1", + "SecretId": "MyTestDatabaseSecret", + "VersionStage": "AWSCURRENT" + }, + "output": { + "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3", + "Name": "MyTestDatabaseSecret" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows you how to move a staging label that is attached to one version of a secret to a different version. You can review the results by running the operation ListSecretVersionIds and viewing the VersionStages response field for the affected version.", + "id": "to-move-a-staging-label-from-one-version-of-a-secret-to-another-1524004963841", + "title": "To move a staging label from one version of a secret to another" + } + ], + "ValidateResourcePolicy": [ + { + "input": { + "ResourcePolicy": "{\n\"Version\":\"2012-10-17\",\n\"Statement\":[{\n\"Effect\":\"Allow\",\n\"Principal\":{\n\"AWS\":\"arn:aws:iam::123456789012:root\"\n},\n\"Action\":\"secretsmanager:GetSecretValue\",\n\"Resource\":\"*\"\n}]\n}", + "SecretId": "MyTestDatabaseSecret" + }, + "output": { + "PolicyValidationPassed": true, + "ValidationErrors": [ + + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows how to validate a resource-based policy to a secret.", + "id": "to-validate-the-resource-policy-of-a-secret-1524000138629", + "title": "To validate a resource-based policy to a secret" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/secretsmanager/2017-10-17/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/secretsmanager/2017-10-17/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0f62e8e1d1fdf8628a410ca3f4cd715ad97a8776 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/secretsmanager/2017-10-17/paginators-1.json @@ -0,0 +1,10 @@ +{ + "pagination": { + "ListSecrets": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "SecretList" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/secretsmanager/2017-10-17/service-2.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/secretsmanager/2017-10-17/service-2.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..dc78f8922c0a2fed349d96078385bcd5df1fe791 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/secretsmanager/2017-10-17/service-2.sdk-extras.json @@ -0,0 +1,8 @@ +{ + "version": 1.0, + "merge": { + "metadata": { + "serviceId": "Secrets Manager" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/security-ir/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/security-ir/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..9f78befbce3754c48ba77407bb73e25c27008841 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/security-ir/2018-05-10/paginators-1.json @@ -0,0 +1,34 @@ +{ + "pagination": { + "ListCaseEdits": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListCases": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListComments": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListMemberships": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListInvestigations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "investigationActions" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/security-ir/2018-05-10/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/security-ir/2018-05-10/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..74820d54a3823a4fd87d837940dff1c11ccf9e70 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/security-ir/2018-05-10/paginators-1.sdk-extras.json @@ -0,0 +1,22 @@ +{ + "version": 1, + "merge": { + "pagination": { + "ListCaseEdits": { + "non_aggregate_keys": [ + "total" + ] + }, + "ListCases": { + "non_aggregate_keys": [ + "total" + ] + }, + "ListComments": { + "non_aggregate_keys": [ + "total" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/security-ir/2018-05-10/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/security-ir/2018-05-10/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/security-ir/2018-05-10/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/securityhub/2018-10-26/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/securityhub/2018-10-26/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/securityhub/2018-10-26/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/securityhub/2018-10-26/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/securityhub/2018-10-26/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..76fbaa12ce2a1d2a76547ce3c158c87be01298f6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/securityhub/2018-10-26/paginators-1.json @@ -0,0 +1,142 @@ +{ + "pagination": { + "GetEnabledStandards": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "StandardsSubscriptions" + }, + "GetFindings": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Findings" + }, + "GetInsights": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Insights" + }, + "ListEnabledProductsForImport": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ProductSubscriptions" + }, + "ListInvitations": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Invitations" + }, + "ListMembers": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Members" + }, + "DescribeActionTargets": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ActionTargets" + }, + "DescribeProducts": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Products" + }, + "DescribeStandards": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Standards" + }, + "DescribeStandardsControls": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Controls" + }, + "ListOrganizationAdminAccounts": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "AdminAccounts" + }, + "ListFindingAggregators": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "FindingAggregators" + }, + "ListSecurityControlDefinitions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "SecurityControlDefinitions" + }, + "ListStandardsControlAssociations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "StandardsControlAssociationSummaries" + }, + "GetFindingHistory": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Records" + }, + "ListConfigurationPolicies": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ConfigurationPolicySummaries" + }, + "ListConfigurationPolicyAssociations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ConfigurationPolicyAssociationSummaries" + }, + "DescribeProductsV2": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ProductsV2" + }, + "GetFindingsV2": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Findings" + }, + "GetResourcesV2": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Resources" + }, + "ListAggregatorsV2": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "AggregatorsV2" + }, + "GetFindingsTrendsV2": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "TrendsMetrics" + }, + "GetResourcesTrendsV2": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "TrendsMetrics" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/securityhub/2018-10-26/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/securityhub/2018-10-26/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..73ef2eee1d02a648e13a28f6cc47e53cfffa94fe --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/securityhub/2018-10-26/paginators-1.sdk-extras.json @@ -0,0 +1,22 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "ListOrganizationAdminAccounts": { + "non_aggregate_keys": [ + "Feature" + ] + }, + "GetFindingsTrendsV2": { + "non_aggregate_keys": [ + "Granularity" + ] + }, + "GetResourcesTrendsV2": { + "non_aggregate_keys": [ + "Granularity" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/securitylake/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/securitylake/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..19e482b211275eef3eca3ca0a6eff195019d7793 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/securitylake/2018-05-10/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "GetDataLakeSources": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "dataLakeSources" + }, + "ListDataLakeExceptions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "exceptions" + }, + "ListLogSources": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "sources" + }, + "ListSubscribers": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "subscribers" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/securitylake/2018-05-10/paginators-1.sdk-extras.json b/.venv/lib/python3.13/site-packages/botocore/data/securitylake/2018-05-10/paginators-1.sdk-extras.json new file mode 100644 index 0000000000000000000000000000000000000000..41ae7fe618b8b8888975df1b39a915b159850b7a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/securitylake/2018-05-10/paginators-1.sdk-extras.json @@ -0,0 +1,12 @@ +{ + "version": 1.0, + "merge": { + "pagination": { + "GetDataLakeSources": { + "non_aggregate_keys": [ + "dataLakeArn" + ] + } + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/service-quotas/2019-06-24/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/service-quotas/2019-06-24/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/service-quotas/2019-06-24/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/service-quotas/2019-06-24/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/service-quotas/2019-06-24/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..e0d4547601f224c74f4c491cde55d352b0033e83 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/service-quotas/2019-06-24/paginators-1.json @@ -0,0 +1,40 @@ +{ + "pagination": { + "ListAWSDefaultServiceQuotas": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Quotas" + }, + "ListRequestedServiceQuotaChangeHistory": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "RequestedQuotas" + }, + "ListRequestedServiceQuotaChangeHistoryByQuota": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "RequestedQuotas" + }, + "ListServiceQuotaIncreaseRequestsInTemplate": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ServiceQuotaIncreaseRequestInTemplateList" + }, + "ListServiceQuotas": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Quotas" + }, + "ListServices": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Services" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/sesv2/2019-09-27/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/sesv2/2019-09-27/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/sesv2/2019-09-27/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/sesv2/2019-09-27/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/sesv2/2019-09-27/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..efa658c468005e36b98137d694390dd6cf394007 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/sesv2/2019-09-27/paginators-1.json @@ -0,0 +1,34 @@ +{ + "pagination": { + "ListMultiRegionEndpoints": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "MultiRegionEndpoints" + }, + "ListReputationEntities": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "ReputationEntities" + }, + "ListResourceTenants": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "ResourceTenants" + }, + "ListTenantResources": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "TenantResources" + }, + "ListTenants": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "PageSize", + "result_key": "Tenants" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/shield/2016-06-02/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/shield/2016-06-02/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/shield/2016-06-02/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/shield/2016-06-02/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/shield/2016-06-02/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..c5ded64262c5624ce6346cd7d9dcdf9f0c2a85c3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/shield/2016-06-02/paginators-1.json @@ -0,0 +1,16 @@ +{ + "pagination": { + "ListProtections": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Protections" + }, + "ListAttacks": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "AttackSummaries" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/signin/2023-01-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/signin/2023-01-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/signin/2023-01-01/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/simspaceweaver/2022-10-28/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/simspaceweaver/2022-10-28/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/simspaceweaver/2022-10-28/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/snow-device-management/2021-08-04/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/snow-device-management/2021-08-04/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/snow-device-management/2021-08-04/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/snow-device-management/2021-08-04/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/snow-device-management/2021-08-04/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..8b112099e7b54d4efbcf9c9e54188c140fd2817e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/snow-device-management/2021-08-04/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "ListDeviceResources": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "resources" + }, + "ListDevices": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "devices" + }, + "ListExecutions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "executions" + }, + "ListTasks": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "tasks" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/snowball/2016-06-30/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/snowball/2016-06-30/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..2b13f7b443a59c3d80cf615f03f3af0dff241a5f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/snowball/2016-06-30/examples-1.json @@ -0,0 +1,442 @@ +{ + "version": "1.0", + "examples": { + "CancelCluster": [ + { + "input": { + "ClusterId": "CID123e4567-e89b-12d3-a456-426655440000" + }, + "comments": { + }, + "description": "This operation cancels a cluster job. You can only cancel a cluster job while it's in the AwaitingQuorum status.", + "id": "to-cancel-a-cluster-job-1482533760554", + "title": "To cancel a cluster job" + } + ], + "CancelJob": [ + { + "input": { + "JobId": "JID123e4567-e89b-12d3-a456-426655440000" + }, + "comments": { + }, + "description": "This operation cancels a job. You can only cancel a job before its JobState value changes to PreparingAppliance.", + "id": "to-cancel-a-job-for-a-snowball-device-1482534699477", + "title": "To cancel a job for a Snowball device" + } + ], + "CreateAddress": [ + { + "input": { + "Address": { + "City": "Seattle", + "Company": "My Company's Name", + "Country": "USA", + "Name": "My Name", + "PhoneNumber": "425-555-5555", + "PostalCode": "98101", + "StateOrProvince": "WA", + "Street1": "123 Main Street" + } + }, + "output": { + "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b" + }, + "comments": { + }, + "description": "This operation creates an address for a job. Addresses are validated at the time of creation. The address you provide must be located within the serviceable area of your region. If the address is invalid or unsupported, then an exception is thrown.", + "id": "to-create-an-address-for-a-job-1482535416294", + "title": "To create an address for a job" + } + ], + "CreateCluster": [ + { + "input": { + "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b", + "Description": "MyCluster", + "JobType": "LOCAL_USE", + "KmsKeyARN": "arn:aws:kms:us-east-1:123456789012:key/abcd1234-12ab-34cd-56ef-123456123456", + "Notification": { + "JobStatesToNotify": [ + + ], + "NotifyAll": false + }, + "Resources": { + "S3Resources": [ + { + "BucketArn": "arn:aws:s3:::MyBucket", + "KeyRange": { + } + } + ] + }, + "RoleARN": "arn:aws:iam::123456789012:role/snowball-import-S3-role", + "ShippingOption": "SECOND_DAY", + "SnowballType": "EDGE" + }, + "output": { + "ClusterId": "CID123e4567-e89b-12d3-a456-426655440000" + }, + "comments": { + }, + "description": "Creates an empty cluster. Each cluster supports five nodes. You use the CreateJob action separately to create the jobs for each of these nodes. The cluster does not ship until these five node jobs have been created.", + "id": "to-create-a-cluster-1482864724077", + "title": "To create a cluster" + } + ], + "CreateJob": [ + { + "input": { + "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b", + "Description": "My Job", + "JobType": "IMPORT", + "KmsKeyARN": "arn:aws:kms:us-east-1:123456789012:key/abcd1234-12ab-34cd-56ef-123456123456", + "Notification": { + "JobStatesToNotify": [ + + ], + "NotifyAll": false + }, + "Resources": { + "S3Resources": [ + { + "BucketArn": "arn:aws:s3:::MyBucket", + "KeyRange": { + } + } + ] + }, + "RoleARN": "arn:aws:iam::123456789012:role/snowball-import-S3-role", + "ShippingOption": "SECOND_DAY", + "SnowballCapacityPreference": "T80", + "SnowballType": "STANDARD" + }, + "output": { + "JobId": "JID123e4567-e89b-12d3-a456-426655440000" + }, + "comments": { + }, + "description": "Creates a job to import or export data between Amazon S3 and your on-premises data center. Your AWS account must have the right trust policies and permissions in place to create a job for Snowball. If you're creating a job for a node in a cluster, you only need to provide the clusterId value; the other job attributes are inherited from the cluster.", + "id": "to-create-a-job-1482864834886", + "title": "To create a job" + } + ], + "DescribeAddress": [ + { + "input": { + "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b" + }, + "output": { + "Address": { + "AddressId": "ADID5643ec50-3eec-4eb3-9be6-9374c10eb51b", + "City": "Seattle", + "Company": "My Company", + "Country": "US", + "Name": "My Name", + "PhoneNumber": "425-555-5555", + "PostalCode": "98101", + "StateOrProvince": "WA", + "Street1": "123 Main Street" + } + }, + "comments": { + }, + "description": "This operation describes an address for a job.", + "id": "to-describe-an-address-for-a-job-1482538608745", + "title": "To describe an address for a job" + } + ], + "DescribeAddresses": [ + { + "input": { + }, + "output": { + "Addresses": [ + { + "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b", + "City": "Seattle", + "Company": "My Company", + "Country": "US", + "Name": "My Name", + "PhoneNumber": "425-555-5555", + "PostalCode": "98101", + "StateOrProvince": "WA", + "Street1": "123 Main Street" + } + ] + }, + "comments": { + }, + "description": "This operation describes all the addresses that you've created for AWS Snowball. Calling this API in one of the US regions will return addresses from the list of all addresses associated with this account in all US regions.", + "id": "to-describe-all-the-addresses-youve-created-for-aws-snowball-1482538936603", + "title": "To describe all the addresses you've created for AWS Snowball" + } + ], + "DescribeCluster": [ + { + "input": { + "ClusterId": "CID123e4567-e89b-12d3-a456-426655440000" + }, + "output": { + "ClusterMetadata": { + "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b", + "ClusterId": "CID123e4567-e89b-12d3-a456-426655440000", + "ClusterState": "Pending", + "CreationDate": "1480475517.0", + "Description": "MyCluster", + "JobType": "LOCAL_USE", + "KmsKeyARN": "arn:aws:kms:us-east-1:123456789012:key/abcd1234-12ab-34cd-56ef-123456123456", + "Notification": { + "JobStatesToNotify": [ + + ], + "NotifyAll": false + }, + "Resources": { + "S3Resources": [ + { + "BucketArn": "arn:aws:s3:::MyBucket", + "KeyRange": { + } + } + ] + }, + "RoleARN": "arn:aws:iam::123456789012:role/snowball-import-S3-role", + "ShippingOption": "SECOND_DAY" + } + }, + "comments": { + }, + "description": "Returns information about a specific cluster including shipping information, cluster status, and other important metadata.", + "id": "to-describe-a-cluster-1482864218396", + "title": "To describe a cluster" + } + ], + "DescribeJob": [ + { + "input": { + "JobId": "JID123e4567-e89b-12d3-a456-426655440000" + }, + "output": { + "JobMetadata": { + "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b", + "CreationDate": "1475626164", + "Description": "My Job", + "JobId": "JID123e4567-e89b-12d3-a456-426655440000", + "JobState": "New", + "JobType": "IMPORT", + "KmsKeyARN": "arn:aws:kms:us-east-1:123456789012:key/abcd1234-12ab-34cd-56ef-123456123456", + "Notification": { + "JobStatesToNotify": [ + + ], + "NotifyAll": false + }, + "Resources": { + "S3Resources": [ + { + "BucketArn": "arn:aws:s3:::MyBucket", + "KeyRange": { + } + } + ] + }, + "RoleARN": "arn:aws:iam::123456789012:role/snowball-import-S3-role", + "ShippingDetails": { + "ShippingOption": "SECOND_DAY" + }, + "SnowballCapacityPreference": "T80", + "SnowballType": "STANDARD" + } + }, + "comments": { + }, + "description": "This operation describes a job you've created for AWS Snowball.", + "id": "to-describe-a-job-youve-created-for-aws-snowball-1482539500180", + "title": "To describe a job you've created for AWS Snowball" + } + ], + "GetJobManifest": [ + { + "input": { + "JobId": "JID123e4567-e89b-12d3-a456-426655440000" + }, + "output": { + "ManifestURI": "https://awsie-frosty-manifests-prod.s3.amazonaws.com/JID123e4567-e89b-12d3-a456-426655440000_manifest.bin?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20161224T005115Z&X-Amz-SignedHeaders=..." + }, + "comments": { + }, + "description": "Returns a link to an Amazon S3 presigned URL for the manifest file associated with the specified JobId value. You can access the manifest file for up to 60 minutes after this request has been made. To access the manifest file after 60 minutes have passed, you'll have to make another call to the GetJobManifest action.\n\nThe manifest is an encrypted file that you can download after your job enters the WithCustomer status. The manifest is decrypted by using the UnlockCode code value, when you pass both values to the Snowball through the Snowball client when the client is started for the first time.\n\nAs a best practice, we recommend that you don't save a copy of an UnlockCode value in the same location as the manifest file for that job. Saving these separately helps prevent unauthorized parties from gaining access to the Snowball associated with that job.\n\nThe credentials of a given job, including its manifest file and unlock code, expire 90 days after the job is created.", + "id": "to-get-the-manifest-for-a-job-youve-created-for-aws-snowball-1482540389246", + "title": "To get the manifest for a job you've created for AWS Snowball" + } + ], + "GetJobUnlockCode": [ + { + "input": { + "JobId": "JID123e4567-e89b-12d3-a456-426655440000" + }, + "output": { + "UnlockCode": "12345-abcde-56789-fghij-01234" + }, + "comments": { + }, + "description": "Returns the UnlockCode code value for the specified job. A particular UnlockCode value can be accessed for up to 90 days after the associated job has been created.\n\nThe UnlockCode value is a 29-character code with 25 alphanumeric characters and 4 hyphens. This code is used to decrypt the manifest file when it is passed along with the manifest to the Snowball through the Snowball client when the client is started for the first time.\n\nAs a best practice, we recommend that you don't save a copy of the UnlockCode in the same location as the manifest file for that job. Saving these separately helps prevent unauthorized parties from gaining access to the Snowball associated with that job.", + "id": "to-get-the-unlock-code-for-a-job-youve-created-for-aws-snowball-1482541987286", + "title": "To get the unlock code for a job you've created for AWS Snowball" + } + ], + "GetSnowballUsage": [ + { + "input": { + }, + "output": { + "SnowballLimit": 1, + "SnowballsInUse": 0 + }, + "comments": { + }, + "description": "Returns information about the Snowball service limit for your account, and also the number of Snowballs your account has in use.\n\nThe default service limit for the number of Snowballs that you can have at one time is 1. If you want to increase your service limit, contact AWS Support.", + "id": "to-see-your-snowball-service-limit-and-the-number-of-snowballs-you-have-in-use-1482863394588", + "title": "To see your Snowball service limit and the number of Snowballs you have in use" + } + ], + "ListClusterJobs": [ + { + "input": { + "ClusterId": "CID123e4567-e89b-12d3-a456-426655440000" + }, + "output": { + "JobListEntries": [ + { + "CreationDate": "1480475524.0", + "Description": "MyClustrer-node-001", + "IsMaster": false, + "JobId": "JID123e4567-e89b-12d3-a456-426655440000", + "JobState": "New", + "JobType": "LOCAL_USE", + "SnowballType": "EDGE" + }, + { + "CreationDate": "1480475525.0", + "Description": "MyClustrer-node-002", + "IsMaster": false, + "JobId": "JID123e4567-e89b-12d3-a456-426655440001", + "JobState": "New", + "JobType": "LOCAL_USE", + "SnowballType": "EDGE" + }, + { + "CreationDate": "1480475525.0", + "Description": "MyClustrer-node-003", + "IsMaster": false, + "JobId": "JID123e4567-e89b-12d3-a456-426655440002", + "JobState": "New", + "JobType": "LOCAL_USE", + "SnowballType": "EDGE" + }, + { + "CreationDate": "1480475525.0", + "Description": "MyClustrer-node-004", + "IsMaster": false, + "JobId": "JID123e4567-e89b-12d3-a456-426655440003", + "JobState": "New", + "JobType": "LOCAL_USE", + "SnowballType": "EDGE" + }, + { + "CreationDate": "1480475525.0", + "Description": "MyClustrer-node-005", + "IsMaster": false, + "JobId": "JID123e4567-e89b-12d3-a456-426655440004", + "JobState": "New", + "JobType": "LOCAL_USE", + "SnowballType": "EDGE" + } + ] + }, + "comments": { + }, + "description": "Returns an array of JobListEntry objects of the specified length. Each JobListEntry object is for a job in the specified cluster and contains a job's state, a job's ID, and other information.", + "id": "to-get-a-list-of-jobs-in-a-cluster-that-youve-created-for-aws-snowball-1482863105773", + "title": "To get a list of jobs in a cluster that you've created for AWS Snowball" + } + ], + "ListClusters": [ + { + "input": { + }, + "output": { + "ClusterListEntries": [ + { + "ClusterId": "CID123e4567-e89b-12d3-a456-426655440000", + "ClusterState": "Pending", + "CreationDate": "1480475517.0", + "Description": "MyCluster" + } + ] + }, + "comments": { + }, + "description": "Returns an array of ClusterListEntry objects of the specified length. Each ClusterListEntry object contains a cluster's state, a cluster's ID, and other important status information.", + "id": "to-get-a-list-of-clusters-that-youve-created-for-aws-snowball-1482862223003", + "title": "To get a list of clusters that you've created for AWS Snowball" + } + ], + "ListJobs": [ + { + "input": { + }, + "output": { + "JobListEntries": [ + { + "CreationDate": "1460678186.0", + "Description": "MyJob", + "IsMaster": false, + "JobId": "JID123e4567-e89b-12d3-a456-426655440000", + "JobState": "New", + "JobType": "IMPORT", + "SnowballType": "STANDARD" + } + ] + }, + "comments": { + }, + "description": "Returns an array of JobListEntry objects of the specified length. Each JobListEntry object contains a job's state, a job's ID, and a value that indicates whether the job is a job part, in the case of export jobs. Calling this API action in one of the US regions will return jobs from the list of all jobs associated with this account in all US regions.", + "id": "to-get-a-list-of-jobs-that-youve-created-for-aws-snowball-1482542167627", + "title": "To get a list of jobs that you've created for AWS Snowball" + } + ], + "UpdateCluster": [ + { + "input": { + "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b", + "ClusterId": "CID123e4567-e89b-12d3-a456-426655440000", + "Description": "updated-cluster-name" + }, + "comments": { + }, + "description": "This action allows you to update certain parameters for a cluster. Once the cluster changes to a different state, usually within 60 minutes of it being created, this action is no longer available.", + "id": "to-update-a-cluster-1482863900595", + "title": "To update a cluster" + } + ], + "UpdateJob": [ + { + "input": { + "AddressId": "ADID1234ab12-3eec-4eb3-9be6-9374c10eb51b", + "Description": "updated-job-name", + "JobId": "JID123e4567-e89b-12d3-a456-426655440000", + "ShippingOption": "NEXT_DAY", + "SnowballCapacityPreference": "T100" + }, + "comments": { + }, + "description": "This action allows you to update certain parameters for a job. Once the job changes to a different job state, usually within 60 minutes of the job being created, this action is no longer available.", + "id": "to-update-a-job-1482863556886", + "title": "To update a job" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/snowball/2016-06-30/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/snowball/2016-06-30/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..05a7ea8482fa00e21d3e5a776f0a3c82de576319 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/snowball/2016-06-30/paginators-1.json @@ -0,0 +1,40 @@ +{ + "pagination": { + "ListJobs": { + "limit_key": "MaxResults", + "output_token": "NextToken", + "input_token": "NextToken", + "result_key": "JobListEntries" + }, + "DescribeAddresses": { + "limit_key": "MaxResults", + "output_token": "NextToken", + "input_token": "NextToken", + "result_key": "Addresses" + }, + "ListClusterJobs": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "JobListEntries" + }, + "ListClusters": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ClusterListEntries" + }, + "ListCompatibleImages": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "CompatibleImages" + }, + "ListLongTermPricing": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "LongTermPricingEntries" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/socialmessaging/2024-01-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/socialmessaging/2024-01-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..a13774357b089a3f1ccf0b59a9e9b447981d61a3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/socialmessaging/2024-01-01/paginators-1.json @@ -0,0 +1,22 @@ +{ + "pagination": { + "ListLinkedWhatsAppBusinessAccounts": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "linkedAccounts" + }, + "ListWhatsAppMessageTemplates": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "templates" + }, + "ListWhatsAppTemplateLibrary": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "metaLibraryTemplates" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ssm-guiconnect/2021-05-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/ssm-guiconnect/2021-05-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ssm-guiconnect/2021-05-01/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ssm-incidents/2018-05-10/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/ssm-incidents/2018-05-10/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ssm-incidents/2018-05-10/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ssm-incidents/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/ssm-incidents/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..662c714f115e86d6ce2097728f4b87e480c6a916 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ssm-incidents/2018-05-10/paginators-1.json @@ -0,0 +1,46 @@ +{ + "pagination": { + "GetResourcePolicies": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "resourcePolicies" + }, + "ListIncidentRecords": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "incidentRecordSummaries" + }, + "ListRelatedItems": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "relatedItems" + }, + "ListReplicationSets": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "replicationSetArns" + }, + "ListResponsePlans": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "responsePlanSummaries" + }, + "ListTimelineEvents": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "eventSummaries" + }, + "ListIncidentFindings": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "findings" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ssm-incidents/2018-05-10/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/ssm-incidents/2018-05-10/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..47c19b3a70cf0256a23ad46e57070d6fedde2606 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ssm-incidents/2018-05-10/waiters-2.json @@ -0,0 +1,53 @@ +{ + "version" : 2, + "waiters" : { + "WaitForReplicationSetActive" : { + "description" : "Wait for a replication set to become ACTIVE", + "delay" : 30, + "maxAttempts" : 5, + "operation" : "GetReplicationSet", + "acceptors" : [ { + "matcher" : "path", + "argument" : "replicationSet.status", + "state" : "success", + "expected" : "ACTIVE" + }, { + "matcher" : "path", + "argument" : "replicationSet.status", + "state" : "retry", + "expected" : "CREATING" + }, { + "matcher" : "path", + "argument" : "replicationSet.status", + "state" : "retry", + "expected" : "UPDATING" + }, { + "matcher" : "path", + "argument" : "replicationSet.status", + "state" : "failure", + "expected" : "FAILED" + } ] + }, + "WaitForReplicationSetDeleted" : { + "description" : "Wait for a replication set to be deleted", + "delay" : 30, + "maxAttempts" : 5, + "operation" : "GetReplicationSet", + "acceptors" : [ { + "matcher" : "error", + "state" : "success", + "expected" : "ResourceNotFoundException" + }, { + "matcher" : "path", + "argument" : "replicationSet.status", + "state" : "retry", + "expected" : "DELETING" + }, { + "matcher" : "path", + "argument" : "replicationSet.status", + "state" : "failure", + "expected" : "FAILED" + } ] + } + } +} \ No newline at end of file diff --git a/.venv/lib/python3.13/site-packages/botocore/data/ssm-sap/2018-05-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/ssm-sap/2018-05-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..52391d74122e5e00d5e6adcd11ad8e8fdd514a82 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/ssm-sap/2018-05-10/paginators-1.json @@ -0,0 +1,58 @@ +{ + "pagination": { + "ListApplications": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Applications" + }, + "ListComponents": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Components" + }, + "ListDatabases": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Databases" + }, + "ListOperations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "Operations" + }, + "ListOperationEvents": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "OperationEvents" + }, + "ListConfigurationCheckDefinitions": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ConfigurationChecks" + }, + "ListConfigurationCheckOperations": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "ConfigurationCheckOperations" + }, + "ListSubCheckResults": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "SubCheckResults" + }, + "ListSubCheckRuleResults": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "RuleResults" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/sso-oidc/2019-06-10/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/sso-oidc/2019-06-10/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/sso-oidc/2019-06-10/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/sso-oidc/2019-06-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/sso-oidc/2019-06-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/sso-oidc/2019-06-10/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/sso/2019-06-10/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/sso/2019-06-10/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/sso/2019-06-10/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/sso/2019-06-10/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/sso/2019-06-10/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..daaed6fe69df01e4c8718c5468e644d6cbd111a6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/sso/2019-06-10/paginators-1.json @@ -0,0 +1,16 @@ +{ + "pagination": { + "ListAccountRoles": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "roleList" + }, + "ListAccounts": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "accountList" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/stepfunctions/2016-11-23/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/stepfunctions/2016-11-23/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/stepfunctions/2016-11-23/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/stepfunctions/2016-11-23/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/stepfunctions/2016-11-23/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..fb8eb5e586913d187c90f7667548afff81539a9f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/stepfunctions/2016-11-23/paginators-1.json @@ -0,0 +1,34 @@ +{ + "pagination": { + "GetExecutionHistory": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "events" + }, + "ListActivities": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "activities" + }, + "ListExecutions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "executions" + }, + "ListStateMachines": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "stateMachines" + }, + "ListMapRuns": { + "input_token": "nextToken", + "limit_key": "maxResults", + "output_token": "nextToken", + "result_key": "mapRuns" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/storagegateway/2013-06-30/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/storagegateway/2013-06-30/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..7cc0d7d410ae09397fc33f44eea458d362f0f828 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/storagegateway/2013-06-30/examples-1.json @@ -0,0 +1,1381 @@ +{ + "version": "1.0", + "examples": { + "ActivateGateway": [ + { + "input": { + "ActivationKey": "29AV1-3OFV9-VVIUB-NKT0I-LRO6V", + "GatewayName": "My_Gateway", + "GatewayRegion": "us-east-1", + "GatewayTimezone": "GMT-12:00", + "GatewayType": "STORED", + "MediumChangerType": "AWS-Gateway-VTL", + "TapeDriveType": "IBM-ULT3580-TD5" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-11A2222B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Activates the gateway you previously deployed on your host.", + "id": "to-activate-the-gateway-1471281611207", + "title": "To activate the gateway" + } + ], + "AddCache": [ + { + "input": { + "DiskIds": [ + "pci-0000:03:00.0-scsi-0:0:0:0", + "pci-0000:03:00.0-scsi-0:0:1:0" + ], + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example shows a request that activates a gateway-stored volume.", + "id": "to-add-a-cache-1471043606854", + "title": "To add a cache" + } + ], + "AddTagsToResource": [ + { + "input": { + "ResourceARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-11A2222B", + "Tags": [ + { + "Key": "Dev Gatgeway Region", + "Value": "East Coast" + } + ] + }, + "output": { + "ResourceARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-11A2222B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Adds one or more tags to the specified resource.", + "id": "to-add-tags-to-resource-1471283689460", + "title": "To add tags to resource" + } + ], + "AddUploadBuffer": [ + { + "input": { + "DiskIds": [ + "pci-0000:03:00.0-scsi-0:0:0:0", + "pci-0000:03:00.0-scsi-0:0:1:0" + ], + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Configures one or more gateway local disks as upload buffer for a specified gateway.", + "id": "to-add-upload-buffer-on-local-disk-1471293902847", + "title": "To add upload buffer on local disk" + } + ], + "AddWorkingStorage": [ + { + "input": { + "DiskIds": [ + "pci-0000:03:00.0-scsi-0:0:0:0", + "pci-0000:03:00.0-scsi-0:0:1:0" + ], + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Configures one or more gateway local disks as working storage for a gateway. (Working storage is also referred to as upload buffer.)", + "id": "to-add-storage-on-local-disk-1471294305401", + "title": "To add storage on local disk" + } + ], + "CancelArchival": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/AMZN01A2A4" + }, + "output": { + "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/AMZN01A2A4" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Cancels archiving of a virtual tape to the virtual tape shelf (VTS) after the archiving process is initiated.", + "id": "to-cancel-virtual-tape-archiving-1471294865203", + "title": "To cancel virtual tape archiving" + } + ], + "CancelRetrieval": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/AMZN01A2A4" + }, + "output": { + "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/AMZN01A2A4" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Cancels retrieval of a virtual tape from the virtual tape shelf (VTS) to a gateway after the retrieval process is initiated.", + "id": "to-cancel-virtual-tape-retrieval-1471295704491", + "title": "To cancel virtual tape retrieval" + } + ], + "CreateCachediSCSIVolume": [ + { + "input": { + "ClientToken": "cachedvol112233", + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "NetworkInterfaceId": "10.1.1.1", + "SnapshotId": "snap-f47b7b94", + "TargetName": "my-volume", + "VolumeSizeInBytes": 536870912000 + }, + "output": { + "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume", + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Creates a cached volume on a specified cached gateway.", + "id": "to-create-a-cached-iscsi-volume-1471296661787", + "title": "To create a cached iSCSI volume" + } + ], + "CreateSnapshot": [ + { + "input": { + "SnapshotDescription": "My root volume snapshot as of 10/03/2017", + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB" + }, + "output": { + "SnapshotId": "snap-78e22663", + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Initiates an ad-hoc snapshot of a gateway volume.", + "id": "to-create-a-snapshot-of-a-gateway-volume-1471301469561", + "title": "To create a snapshot of a gateway volume" + } + ], + "CreateSnapshotFromVolumeRecoveryPoint": [ + { + "input": { + "SnapshotDescription": "My root volume snapshot as of 2017-06-30T10:10:10.000Z", + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB" + }, + "output": { + "SnapshotId": "snap-78e22663", + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB", + "VolumeRecoveryPointTime": "2017-06-30T10:10:10.000Z" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Initiates a snapshot of a gateway from a volume recovery point.", + "id": "to-create-a-snapshot-of-a-gateway-volume-1471301469561", + "title": "To create a snapshot of a gateway volume" + } + ], + "CreateStorediSCSIVolume": [ + { + "input": { + "DiskId": "pci-0000:03:00.0-scsi-0:0:0:0", + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "NetworkInterfaceId": "10.1.1.1", + "PreserveExistingData": true, + "SnapshotId": "snap-f47b7b94", + "TargetName": "my-volume" + }, + "output": { + "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume", + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB", + "VolumeSizeInBytes": 1099511627776 + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Creates a stored volume on a specified stored gateway.", + "id": "to-create-a-stored-iscsi-volume-1471367662813", + "title": "To create a stored iSCSI volume" + } + ], + "CreateTapeWithBarcode": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B", + "TapeBarcode": "TEST12345", + "TapeSizeInBytes": 107374182400 + }, + "output": { + "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST12345" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Creates a virtual tape by using your own barcode.", + "id": "to-create-a-virtual-tape-using-a-barcode-1471371842452", + "title": "To create a virtual tape using a barcode" + } + ], + "CreateTapes": [ + { + "input": { + "ClientToken": "77777", + "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B", + "NumTapesToCreate": 3, + "TapeBarcodePrefix": "TEST", + "TapeSizeInBytes": 107374182400 + }, + "output": { + "TapeARNs": [ + "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST38A29D", + "arn:aws:storagegateway:us-east-1:204469490176:tape/TEST3AA29F", + "arn:aws:storagegateway:us-east-1:204469490176:tape/TEST3BA29E" + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Creates one or more virtual tapes.", + "id": "to-create-a-virtual-tape-1471372061659", + "title": "To create a virtual tape" + } + ], + "DeleteBandwidthRateLimit": [ + { + "input": { + "BandwidthType": "All", + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Deletes the bandwidth rate limits of a gateway; either the upload or download limit, or both.", + "id": "to-delete-bandwidth-rate-limits-of-gateway-1471373225520", + "title": "To delete bandwidth rate limits of gateway" + } + ], + "DeleteChapCredentials": [ + { + "input": { + "InitiatorName": "iqn.1991-05.com.microsoft:computername.domain.example.com", + "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume" + }, + "output": { + "InitiatorName": "iqn.1991-05.com.microsoft:computername.domain.example.com", + "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Deletes Challenge-Handshake Authentication Protocol (CHAP) credentials for a specified iSCSI target and initiator pair.", + "id": "to-delete-chap-credentials-1471375025612", + "title": "To delete CHAP credentials" + } + ], + "DeleteGateway": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This operation deletes the gateway, but not the gateway's VM from the host computer.", + "id": "to-delete-a-gatgeway-1471381697333", + "title": "To delete a gatgeway" + } + ], + "DeleteSnapshotSchedule": [ + { + "input": { + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB" + }, + "output": { + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This action enables you to delete a snapshot schedule for a volume.", + "id": "to-delete-a-snapshot-of-a-volume-1471382234377", + "title": "To delete a snapshot of a volume" + } + ], + "DeleteTape": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:204469490176:gateway/sgw-12A3456B", + "TapeARN": "arn:aws:storagegateway:us-east-1:204469490176:tape/TEST05A2A0" + }, + "output": { + "TapeARN": "arn:aws:storagegateway:us-east-1:204469490176:tape/TEST05A2A0" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This example deletes the specified virtual tape.", + "id": "to-delete-a-virtual-tape-1471382444157", + "title": "To delete a virtual tape" + } + ], + "DeleteTapeArchive": [ + { + "input": { + "TapeARN": "arn:aws:storagegateway:us-east-1:204469490176:tape/TEST05A2A0" + }, + "output": { + "TapeARN": "arn:aws:storagegateway:us-east-1:204469490176:tape/TEST05A2A0" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Deletes the specified virtual tape from the virtual tape shelf (VTS).", + "id": "to-delete-a-virtual-tape-from-the-shelf-vts-1471383964329", + "title": "To delete a virtual tape from the shelf (VTS)" + } + ], + "DeleteVolume": [ + { + "input": { + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB" + }, + "output": { + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Deletes the specified gateway volume that you previously created using the CreateCachediSCSIVolume or CreateStorediSCSIVolume API.", + "id": "to-delete-a-gateway-volume-1471384418416", + "title": "To delete a gateway volume" + } + ], + "DescribeBandwidthRateLimit": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "AverageDownloadRateLimitInBitsPerSec": 204800, + "AverageUploadRateLimitInBitsPerSec": 102400, + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns a value for a bandwidth rate limit if set. If not set, then only the gateway ARN is returned.", + "id": "to-describe-the-bandwidth-rate-limits-of-a-gateway-1471384826404", + "title": "To describe the bandwidth rate limits of a gateway" + } + ], + "DescribeCache": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "CacheAllocatedInBytes": 2199023255552, + "CacheDirtyPercentage": 0.07, + "CacheHitPercentage": 99.68, + "CacheMissPercentage": 0.32, + "CacheUsedPercentage": 0.07, + "DiskIds": [ + "pci-0000:03:00.0-scsi-0:0:0:0", + "pci-0000:04:00.0-scsi-0:1:0:0" + ], + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns information about the cache of a gateway.", + "id": "to-describe-cache-information-1471385756036", + "title": "To describe cache information" + } + ], + "DescribeCachediSCSIVolumes": [ + { + "input": { + "VolumeARNs": [ + "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB" + ] + }, + "output": { + "CachediSCSIVolumes": [ + { + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB", + "VolumeId": "vol-1122AABB", + "VolumeSizeInBytes": 1099511627776, + "VolumeStatus": "AVAILABLE", + "VolumeType": "CACHED iSCSI", + "VolumeiSCSIAttributes": { + "ChapEnabled": true, + "LunNumber": 1, + "NetworkInterfaceId": "10.243.43.207", + "NetworkInterfacePort": 3260, + "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume" + } + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns a description of the gateway cached iSCSI volumes specified in the request.", + "id": "to-describe-gateway-cached-iscsi-volumes-1471458094649", + "title": "To describe gateway cached iSCSI volumes" + } + ], + "DescribeChapCredentials": [ + { + "input": { + "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume" + }, + "output": { + "ChapCredentials": [ + { + "InitiatorName": "iqn.1991-05.com.microsoft:computername.domain.example.com", + "SecretToAuthenticateInitiator": "111111111111", + "SecretToAuthenticateTarget": "222222222222", + "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns an array of Challenge-Handshake Authentication Protocol (CHAP) credentials information for a specified iSCSI target, one for each target-initiator pair.", + "id": "to-describe-chap-credetnitals-for-an-iscsi-1471467462967", + "title": "To describe CHAP credetnitals for an iSCSI" + } + ], + "DescribeGatewayInformation": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "GatewayId": "sgw-AABB1122", + "GatewayName": "My_Gateway", + "GatewayNetworkInterfaces": [ + { + "Ipv4Address": "10.35.69.216" + } + ], + "GatewayState": "STATE_RUNNING", + "GatewayTimezone": "GMT-8:00", + "GatewayType": "STORED", + "LastSoftwareUpdate": "2016-01-02T16:00:00", + "NextUpdateAvailabilityDate": "2017-01-02T16:00:00" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns metadata about a gateway such as its name, network interfaces, configured time zone, and the state (whether the gateway is running or not).", + "id": "to-describe-metadata-about-the-gateway-1471467849079", + "title": "To describe metadata about the gateway" + } + ], + "DescribeMaintenanceStartTime": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "DayOfWeek": 2, + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "HourOfDay": 15, + "MinuteOfHour": 35, + "Timezone": "GMT+7:00" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns your gateway's weekly maintenance start time including the day and time of the week.", + "id": "to-describe-gateways-maintenance-start-time-1471470727387", + "title": "To describe gateway's maintenance start time" + } + ], + "DescribeSnapshotSchedule": [ + { + "input": { + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB" + }, + "output": { + "Description": "sgw-AABB1122:vol-AABB1122:Schedule", + "RecurrenceInHours": 24, + "StartAt": 6, + "Timezone": "GMT+7:00", + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Describes the snapshot schedule for the specified gateway volume including intervals at which snapshots are automatically initiated.", + "id": "to-describe-snapshot-schedule-for-gateway-volume-1471471139538", + "title": "To describe snapshot schedule for gateway volume" + } + ], + "DescribeStorediSCSIVolumes": [ + { + "input": { + "VolumeARNs": [ + "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB" + ] + }, + "output": { + "StorediSCSIVolumes": [ + { + "PreservedExistingData": false, + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB", + "VolumeDiskId": "pci-0000:03:00.0-scsi-0:0:0:0", + "VolumeId": "vol-1122AABB", + "VolumeProgress": 23.7, + "VolumeSizeInBytes": 1099511627776, + "VolumeStatus": "BOOTSTRAPPING", + "VolumeiSCSIAttributes": { + "ChapEnabled": true, + "NetworkInterfaceId": "10.243.43.207", + "NetworkInterfacePort": 3260, + "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume" + } + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns the description of the gateway volumes specified in the request belonging to the same gateway.", + "id": "to-describe-the-volumes-of-a-gateway-1471472640660", + "title": "To describe the volumes of a gateway" + } + ], + "DescribeTapeArchives": [ + { + "input": { + "Limit": 123, + "Marker": "1", + "TapeARNs": [ + "arn:aws:storagegateway:us-east-1:999999999999:tape/AM08A1AD", + "arn:aws:storagegateway:us-east-1:999999999999:tape/AMZN01A2A4" + ] + }, + "output": { + "Marker": "1", + "TapeArchives": [ + { + "CompletionTime": "2016-12-16T13:50Z", + "TapeARN": "arn:aws:storagegateway:us-east-1:999999999:tape/AM08A1AD", + "TapeBarcode": "AM08A1AD", + "TapeSizeInBytes": 107374182400, + "TapeStatus": "ARCHIVED" + }, + { + "CompletionTime": "2016-12-16T13:59Z", + "TapeARN": "arn:aws:storagegateway:us-east-1:999999999:tape/AMZN01A2A4", + "TapeBarcode": "AMZN01A2A4", + "TapeSizeInBytes": 429496729600, + "TapeStatus": "ARCHIVED" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns a description of specified virtual tapes in the virtual tape shelf (VTS).", + "id": "to-describe-virtual-tapes-in-the-vts-1471473188198", + "title": "To describe virtual tapes in the VTS" + } + ], + "DescribeTapeRecoveryPoints": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "Limit": 1, + "Marker": "1" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "Marker": "1", + "TapeRecoveryPointInfos": [ + { + "TapeARN": "arn:aws:storagegateway:us-east-1:999999999:tape/AMZN01A2A4", + "TapeRecoveryPointTime": "2016-12-16T13:50Z", + "TapeSizeInBytes": 1471550497, + "TapeStatus": "AVAILABLE" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns a list of virtual tape recovery points that are available for the specified gateway-VTL.", + "id": "to-describe-virtual-tape-recovery-points-1471542042026", + "title": "To describe virtual tape recovery points" + } + ], + "DescribeTapes": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B", + "Limit": 2, + "Marker": "1", + "TapeARNs": [ + "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST04A2A1", + "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST05A2A0" + ] + }, + "output": { + "Marker": "1", + "Tapes": [ + { + "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST04A2A1", + "TapeBarcode": "TEST04A2A1", + "TapeSizeInBytes": 107374182400, + "TapeStatus": "AVAILABLE" + }, + { + "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST05A2A0", + "TapeBarcode": "TEST05A2A0", + "TapeSizeInBytes": 107374182400, + "TapeStatus": "AVAILABLE" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns a description of the specified Amazon Resource Name (ARN) of virtual tapes. If a TapeARN is not specified, returns a description of all virtual tapes.", + "id": "to-describe-virtual-tapes-associated-with-gateway-1471629287727", + "title": "To describe virtual tape(s) associated with gateway" + } + ], + "DescribeUploadBuffer": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "DiskIds": [ + "pci-0000:03:00.0-scsi-0:0:0:0", + "pci-0000:04:00.0-scsi-0:1:0:0" + ], + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "UploadBufferAllocatedInBytes": 0, + "UploadBufferUsedInBytes": 161061273600 + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns information about the upload buffer of a gateway including disk IDs and the amount of upload buffer space allocated/used.", + "id": "to-describe-upload-buffer-of-gateway-1471631099003", + "title": "To describe upload buffer of gateway" + }, + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "DiskIds": [ + "pci-0000:03:00.0-scsi-0:0:0:0", + "pci-0000:04:00.0-scsi-0:1:0:0" + ], + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "UploadBufferAllocatedInBytes": 161061273600, + "UploadBufferUsedInBytes": 0 + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns information about the upload buffer of a gateway including disk IDs and the amount of upload buffer space allocated and used.", + "id": "to-describe-upload-buffer-of-a-gateway--1471904566370", + "title": "To describe upload buffer of a gateway" + } + ], + "DescribeVTLDevices": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B", + "Limit": 123, + "Marker": "1", + "VTLDeviceARNs": [ + + ] + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B", + "Marker": "1", + "VTLDevices": [ + { + "DeviceiSCSIAttributes": { + "ChapEnabled": false, + "NetworkInterfaceId": "10.243.43.207", + "NetworkInterfacePort": 3260, + "TargetARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:sgw-1fad4876-mediachanger" + }, + "VTLDeviceARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B/device/AMZN_SGW-1FAD4876_MEDIACHANGER_00001", + "VTLDeviceProductIdentifier": "L700", + "VTLDeviceType": "Medium Changer", + "VTLDeviceVendor": "STK" + }, + { + "DeviceiSCSIAttributes": { + "ChapEnabled": false, + "NetworkInterfaceId": "10.243.43.209", + "NetworkInterfacePort": 3260, + "TargetARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:sgw-1fad4876-tapedrive-01" + }, + "VTLDeviceARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B/device/AMZN_SGW-1FAD4876_TAPEDRIVE_00001", + "VTLDeviceProductIdentifier": "ULT3580-TD5", + "VTLDeviceType": "Tape Drive", + "VTLDeviceVendor": "IBM" + }, + { + "DeviceiSCSIAttributes": { + "ChapEnabled": false, + "NetworkInterfaceId": "10.243.43.209", + "NetworkInterfacePort": 3260, + "TargetARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:sgw-1fad4876-tapedrive-02" + }, + "VTLDeviceARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B/device/AMZN_SGW-1FAD4876_TAPEDRIVE_00002", + "VTLDeviceProductIdentifier": "ULT3580-TD5", + "VTLDeviceType": "Tape Drive", + "VTLDeviceVendor": "IBM" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Returns a description of virtual tape library (VTL) devices for the specified gateway.", + "id": "to-describe-virtual-tape-library-vtl-devices-of-a-single-gateway-1471906071410", + "title": "To describe virtual tape library (VTL) devices of a single gateway" + } + ], + "DescribeWorkingStorage": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "DiskIds": [ + "pci-0000:03:00.0-scsi-0:0:0:0", + "pci-0000:03:00.0-scsi-0:0:1:0" + ], + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "WorkingStorageAllocatedInBytes": 2199023255552, + "WorkingStorageUsedInBytes": 789207040 + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This operation is supported only for the gateway-stored volume architecture. This operation is deprecated in cached-volumes API version (20120630). Use DescribeUploadBuffer instead.", + "id": "to-describe-the-working-storage-of-a-gateway-depreciated-1472070842332", + "title": "To describe the working storage of a gateway [Depreciated]" + } + ], + "DisableGateway": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Disables a gateway when the gateway is no longer functioning. Use this operation for a gateway-VTL that is not reachable or not functioning.", + "id": "to-disable-a-gateway-when-it-is-no-longer-functioning-1472076046936", + "title": "To disable a gateway when it is no longer functioning" + } + ], + "ListGateways": [ + { + "input": { + "Limit": 2, + "Marker": "1" + }, + "output": { + "Gateways": [ + { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-23A4567C" + } + ], + "Marker": "1" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Lists gateways owned by an AWS account in a specified region as requested. Results are sorted by gateway ARN up to a maximum of 100 gateways.", + "id": "to-lists-region-specific-gateways-per-aws-account-1472077860657", + "title": "To lists region specific gateways per AWS account" + } + ], + "ListLocalDisks": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "Disks": [ + { + "DiskAllocationType": "CACHE_STORAGE", + "DiskId": "pci-0000:03:00.0-scsi-0:0:0:0", + "DiskNode": "SCSI(0:0)", + "DiskPath": "/dev/sda", + "DiskSizeInBytes": 1099511627776, + "DiskStatus": "missing" + }, + { + "DiskAllocationResource": "", + "DiskAllocationType": "UPLOAD_BUFFER", + "DiskId": "pci-0000:03:00.0-scsi-0:0:1:0", + "DiskNode": "SCSI(0:1)", + "DiskPath": "/dev/sdb", + "DiskSizeInBytes": 1099511627776, + "DiskStatus": "present" + } + ], + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The request returns a list of all disks, specifying which are configured as working storage, cache storage, or stored volume or not configured at all.", + "id": "to-list-the-gateways-local-disks-1472079564618", + "title": "To list the gateway's local disks" + } + ], + "ListTagsForResource": [ + { + "input": { + "Limit": 1, + "Marker": "1", + "ResourceARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-11A2222B" + }, + "output": { + "Marker": "1", + "ResourceARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-11A2222B", + "Tags": [ + { + "Key": "Dev Gatgeway Region", + "Value": "East Coast" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Lists the tags that have been added to the specified resource.", + "id": "to-list-tags-that-have-been-added-to-a-resource-1472080268972", + "title": "To list tags that have been added to a resource" + } + ], + "ListVolumeRecoveryPoints": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "VolumeRecoveryPointInfos": [ + { + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB", + "VolumeRecoveryPointTime": "2012-09-04T21:08:44.627Z", + "VolumeSizeInBytes": 536870912000 + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Lists the recovery points for a specified gateway in which all data of the volume is consistent and can be used to create a snapshot.", + "id": "to-list-recovery-points-for-a-gateway-1472143015088", + "title": "To list recovery points for a gateway" + } + ], + "ListVolumes": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "Limit": 2, + "Marker": "1" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "Marker": "1", + "VolumeInfos": [ + { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "GatewayId": "sgw-12A3456B", + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB", + "VolumeId": "vol-1122AABB", + "VolumeSizeInBytes": 107374182400, + "VolumeType": "STORED" + }, + { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-13B4567C", + "GatewayId": "sgw-gw-13B4567C", + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-13B4567C/volume/vol-3344CCDD", + "VolumeId": "vol-1122AABB", + "VolumeSizeInBytes": 107374182400, + "VolumeType": "STORED" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Lists the iSCSI stored volumes of a gateway. Results are sorted by volume ARN up to a maximum of 100 volumes.", + "id": "to-list-the-iscsi-stored-volumes-of-a-gateway-1472145723653", + "title": "To list the iSCSI stored volumes of a gateway" + } + ], + "RemoveTagsFromResource": [ + { + "input": { + "ResourceARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-11A2222B", + "TagKeys": [ + "Dev Gatgeway Region", + "East Coast" + ] + }, + "output": { + "ResourceARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-11A2222B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Lists the iSCSI stored volumes of a gateway. Removes one or more tags from the specified resource.", + "id": "to-remove-tags-from-a-resource-1472147210553", + "title": "To remove tags from a resource" + } + ], + "ResetCache": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-13B4567C" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-13B4567C" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Resets all cache disks that have encountered a error and makes the disks available for reconfiguration as cache storage.", + "id": "to-reset-cache-disks-in-error-status-1472148909807", + "title": "To reset cache disks in error status" + } + ], + "RetrieveTapeArchive": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B", + "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST0AA2AF" + }, + "output": { + "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST0AA2AF" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Retrieves an archived virtual tape from the virtual tape shelf (VTS) to a gateway-VTL. Virtual tapes archived in the VTS are not associated with any gateway.", + "id": "to-retrieve-an-archived-tape-from-the-vts-1472149812358", + "title": "To retrieve an archived tape from the VTS" + } + ], + "RetrieveTapeRecoveryPoint": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B", + "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST0AA2AF" + }, + "output": { + "TapeARN": "arn:aws:storagegateway:us-east-1:999999999999:tape/TEST0AA2AF" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Retrieves the recovery point for the specified virtual tape.", + "id": "to-retrieve-the-recovery-point-of-a-virtual-tape-1472150014805", + "title": "To retrieve the recovery point of a virtual tape" + } + ], + "SetLocalConsolePassword": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B", + "LocalConsolePassword": "PassWordMustBeAtLeast6Chars." + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Sets the password for your VM local console.", + "id": "to-set-a-password-for-your-vm-1472150202632", + "title": "To set a password for your VM" + } + ], + "ShutdownGateway": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "This operation shuts down the gateway service component running in the storage gateway's virtual machine (VM) and not the VM.", + "id": "to-shut-down-a-gateway-service-1472150508835", + "title": "To shut down a gateway service" + } + ], + "StartGateway": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Starts a gateway service that was previously shut down.", + "id": "to-start-a-gateway-service-1472150722315", + "title": "To start a gateway service" + } + ], + "UpdateBandwidthRateLimit": [ + { + "input": { + "AverageDownloadRateLimitInBitsPerSec": 102400, + "AverageUploadRateLimitInBitsPerSec": 51200, + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Updates the bandwidth rate limits of a gateway. Both the upload and download bandwidth rate limit can be set, or either one of the two. If a new limit is not set, the existing rate limit remains.", + "id": "to-update-the-bandwidth-rate-limits-of-a-gateway-1472151016202", + "title": "To update the bandwidth rate limits of a gateway" + } + ], + "UpdateChapCredentials": [ + { + "input": { + "InitiatorName": "iqn.1991-05.com.microsoft:computername.domain.example.com", + "SecretToAuthenticateInitiator": "111111111111", + "SecretToAuthenticateTarget": "222222222222", + "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume" + }, + "output": { + "InitiatorName": "iqn.1991-05.com.microsoft:computername.domain.example.com", + "TargetARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/target/iqn.1997-05.com.amazon:myvolume" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Updates the Challenge-Handshake Authentication Protocol (CHAP) credentials for a specified iSCSI target.", + "id": "to-update-chap-credentials-for-an-iscsi-target-1472151325795", + "title": "To update CHAP credentials for an iSCSI target" + } + ], + "UpdateGatewayInformation": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "GatewayName": "MyGateway2", + "GatewayTimezone": "GMT-12:00" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "GatewayName": "" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Updates a gateway's metadata, which includes the gateway's name and time zone.", + "id": "to-update-a-gateways-metadata-1472151688693", + "title": "To update a gateway's metadata" + } + ], + "UpdateGatewaySoftwareNow": [ + { + "input": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Updates the gateway virtual machine (VM) software. The request immediately triggers the software update.", + "id": "to-update-a-gateways-vm-software-1472152020929", + "title": "To update a gateway's VM software" + } + ], + "UpdateMaintenanceStartTime": [ + { + "input": { + "DayOfWeek": 2, + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B", + "HourOfDay": 0, + "MinuteOfHour": 30 + }, + "output": { + "GatewayARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Updates a gateway's weekly maintenance start time information, including day and time of the week. The maintenance time is in your gateway's time zone.", + "id": "to-update-a-gateways-maintenance-start-time-1472152552031", + "title": "To update a gateway's maintenance start time" + } + ], + "UpdateSnapshotSchedule": [ + { + "input": { + "Description": "Hourly snapshot", + "RecurrenceInHours": 1, + "StartAt": 0, + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB" + }, + "output": { + "VolumeARN": "arn:aws:storagegateway:us-east-1:111122223333:gateway/sgw-12A3456B/volume/vol-1122AABB" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Updates a snapshot schedule configured for a gateway volume.", + "id": "to-update-a-volume-snapshot-schedule-1472152757068", + "title": "To update a volume snapshot schedule" + } + ], + "UpdateVTLDeviceType": [ + { + "input": { + "DeviceType": "Medium Changer", + "VTLDeviceARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B/device/AMZN_SGW-1FAD4876_MEDIACHANGER_00001" + }, + "output": { + "VTLDeviceARN": "arn:aws:storagegateway:us-east-1:999999999999:gateway/sgw-12A3456B/device/AMZN_SGW-1FAD4876_MEDIACHANGER_00001" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "Updates the type of medium changer in a gateway-VTL after a gateway-VTL is activated.", + "id": "to-update-a-vtl-device-type-1472153012967", + "title": "To update a VTL device type" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/storagegateway/2013-06-30/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/storagegateway/2013-06-30/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..e43b890de7d36587d069b74f409005ce4e5a35e6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/storagegateway/2013-06-30/paginators-1.json @@ -0,0 +1,84 @@ +{ + "pagination": { + "DescribeTapeArchives": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "TapeArchives" + }, + "DescribeTapeRecoveryPoints": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "TapeRecoveryPointInfos" + }, + "DescribeTapes": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "Tapes" + }, + "DescribeVTLDevices": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "VTLDevices" + }, + "ListGateways": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "Gateways" + }, + "ListVolumes": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "VolumeInfos" + }, + "ListTapes": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "TapeInfos" + }, + "ListFileShares": { + "input_token": "Marker", + "limit_key": "Limit", + "non_aggregate_keys": [ + "Marker" + ], + "output_token": "NextMarker", + "result_key": "FileShareInfoList" + }, + "ListTagsForResource": { + "input_token": "Marker", + "limit_key": "Limit", + "non_aggregate_keys": [ + "ResourceARN" + ], + "output_token": "Marker", + "result_key": "Tags" + }, + "ListTapePools": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "PoolInfos" + }, + "ListFileSystemAssociations": { + "input_token": "Marker", + "limit_key": "Limit", + "non_aggregate_keys": [ + "Marker" + ], + "output_token": "NextMarker", + "result_key": "FileSystemAssociationSummaryList" + }, + "ListCacheReports": { + "input_token": "Marker", + "output_token": "Marker", + "result_key": "CacheReportList" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/supplychain/2024-01-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/supplychain/2024-01-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..cd55b3055c5405e8dd1f094893d6742315c0b9a0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/supplychain/2024-01-01/paginators-1.json @@ -0,0 +1,40 @@ +{ + "pagination": { + "ListDataIntegrationFlows": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "flows" + }, + "ListDataLakeDatasets": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "datasets" + }, + "ListInstances": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "instances" + }, + "ListDataIntegrationEvents": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "events" + }, + "ListDataIntegrationFlowExecutions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "flowExecutions" + }, + "ListDataLakeNamespaces": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "namespaces" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/synthetics/2017-10-11/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/synthetics/2017-10-11/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/synthetics/2017-10-11/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/synthetics/2017-10-11/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/synthetics/2017-10-11/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/synthetics/2017-10-11/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/timestream-influxdb/2023-01-27/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/timestream-influxdb/2023-01-27/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..e0b4f3c57b61bd501cefb157a0ca33b9a42b0097 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/timestream-influxdb/2023-01-27/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "ListDbInstances": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListDbParameterGroups": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListDbClusters": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListDbInstancesForCluster": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/timestream-query/2018-11-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/timestream-query/2018-11-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/timestream-query/2018-11-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/timestream-query/2018-11-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/timestream-query/2018-11-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..a20456bab9cc522fa23f6ba3a349c16a2b335229 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/timestream-query/2018-11-01/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "Query": { + "input_token": "NextToken", + "limit_key": "MaxRows", + "non_aggregate_keys": [ + "ColumnInfo", + "QueryId", + "QueryStatus", + "QueryInsightsResponse" + ], + "output_token": "NextToken", + "result_key": "Rows" + }, + "ListScheduledQueries": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ScheduledQueries" + }, + "ListTagsForResource": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Tags" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/translate/2017-07-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/translate/2017-07-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/translate/2017-07-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/translate/2017-07-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/translate/2017-07-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..6898cd44cf3e9e99d6cced8397b35cca4a8a2246 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/translate/2017-07-01/paginators-1.json @@ -0,0 +1,10 @@ +{ + "pagination": { + "ListTerminologies": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "TerminologyPropertiesList" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/verifiedpermissions/2021-12-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/verifiedpermissions/2021-12-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..4314d715de4197c362f1754f67a17c9d524d9857 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/verifiedpermissions/2021-12-01/paginators-1.json @@ -0,0 +1,28 @@ +{ + "pagination": { + "ListIdentitySources": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "identitySources" + }, + "ListPolicies": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "policies" + }, + "ListPolicyStores": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "policyStores" + }, + "ListPolicyTemplates": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "policyTemplates" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/verifiedpermissions/2021-12-01/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/verifiedpermissions/2021-12-01/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/verifiedpermissions/2021-12-01/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/voice-id/2021-09-27/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/voice-id/2021-09-27/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/voice-id/2021-09-27/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/voice-id/2021-09-27/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/voice-id/2021-09-27/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..49dd7ccabb367671d3b5e02f257fafbc7b8853df --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/voice-id/2021-09-27/paginators-1.json @@ -0,0 +1,40 @@ +{ + "pagination": { + "ListDomains": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "DomainSummaries" + }, + "ListFraudsterRegistrationJobs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "JobSummaries" + }, + "ListSpeakerEnrollmentJobs": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "JobSummaries" + }, + "ListSpeakers": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "SpeakerSummaries" + }, + "ListFraudsters": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "FraudsterSummaries" + }, + "ListWatchlists": { + "input_token": "NextToken", + "output_token": "NextToken", + "limit_key": "MaxResults", + "result_key": "WatchlistSummaries" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/vpc-lattice/2022-11-30/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/vpc-lattice/2022-11-30/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..7bb8082a892217e35c17d101b3dcafdcbdfb1da0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/vpc-lattice/2022-11-30/paginators-1.json @@ -0,0 +1,94 @@ +{ + "pagination": { + "ListAccessLogSubscriptions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListListeners": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListRules": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListServiceNetworkServiceAssociations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListServiceNetworkVpcAssociations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListServiceNetworks": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListServices": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListTargetGroups": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListTargets": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListResourceConfigurations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListResourceEndpointAssociations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListResourceGateways": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListServiceNetworkResourceAssociations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListServiceNetworkVpcEndpointAssociations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + }, + "ListDomainVerifications": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/vpc-lattice/2022-11-30/waiters-2.json b/.venv/lib/python3.13/site-packages/botocore/data/vpc-lattice/2022-11-30/waiters-2.json new file mode 100644 index 0000000000000000000000000000000000000000..13f60ee66be6a3d75208653e2bd7b563561adacc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/vpc-lattice/2022-11-30/waiters-2.json @@ -0,0 +1,5 @@ +{ + "version": 2, + "waiters": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/waf-regional/2016-11-28/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/waf-regional/2016-11-28/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..eee5b6f4ff135a62424ba859ca701638529008a1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/waf-regional/2016-11-28/examples-1.json @@ -0,0 +1,1017 @@ +{ + "version": "1.0", + "examples": { + "CreateIPSet": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "Name": "MyIPSetFriendlyName" + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "IPSet": { + "IPSetDescriptors": [ + { + "Type": "IPV4", + "Value": "192.0.2.44/32" + } + ], + "IPSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5", + "Name": "MyIPSetFriendlyName" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example creates an IP match set named MyIPSetFriendlyName.", + "id": "createipset-1472501003122", + "title": "To create an IP set" + } + ], + "CreateRule": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "MetricName": "WAFByteHeaderRule", + "Name": "WAFByteHeaderRule" + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "Rule": { + "MetricName": "WAFByteHeaderRule", + "Name": "WAFByteHeaderRule", + "Predicates": [ + { + "DataId": "MyByteMatchSetID", + "Negated": false, + "Type": "ByteMatch" + } + ], + "RuleId": "WAFRule-1-Example" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example creates a rule named WAFByteHeaderRule.", + "id": "createrule-1474072675555", + "title": "To create a rule" + } + ], + "CreateSizeConstraintSet": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "Name": "MySampleSizeConstraintSet" + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "SizeConstraintSet": { + "Name": "MySampleSizeConstraintSet", + "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5", + "SizeConstraints": [ + { + "ComparisonOperator": "GT", + "FieldToMatch": { + "Type": "QUERY_STRING" + }, + "Size": 0, + "TextTransformation": "NONE" + } + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example creates size constraint set named MySampleSizeConstraintSet.", + "id": "createsizeconstraint-1474299140754", + "title": "To create a size constraint" + } + ], + "CreateSqlInjectionMatchSet": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "Name": "MySQLInjectionMatchSet" + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "SqlInjectionMatchSet": { + "Name": "MySQLInjectionMatchSet", + "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5", + "SqlInjectionMatchTuples": [ + { + "FieldToMatch": { + "Type": "QUERY_STRING" + }, + "TextTransformation": "URL_DECODE" + } + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example creates a SQL injection match set named MySQLInjectionMatchSet.", + "id": "createsqlinjectionmatchset-1474492796105", + "title": "To create a SQL injection match set" + } + ], + "CreateWebACL": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "DefaultAction": { + "Type": "ALLOW" + }, + "MetricName": "CreateExample", + "Name": "CreateExample" + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "WebACL": { + "DefaultAction": { + "Type": "ALLOW" + }, + "MetricName": "CreateExample", + "Name": "CreateExample", + "Rules": [ + { + "Action": { + "Type": "ALLOW" + }, + "Priority": 1, + "RuleId": "WAFRule-1-Example" + } + ], + "WebACLId": "example-46da-4444-5555-example" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example creates a web ACL named CreateExample.", + "id": "createwebacl-1472061481310", + "title": "To create a web ACL" + } + ], + "CreateXssMatchSet": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "Name": "MySampleXssMatchSet" + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "XssMatchSet": { + "Name": "MySampleXssMatchSet", + "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5", + "XssMatchTuples": [ + { + "FieldToMatch": { + "Type": "QUERY_STRING" + }, + "TextTransformation": "URL_DECODE" + } + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example creates an XSS match set named MySampleXssMatchSet.", + "id": "createxssmatchset-1474560868500", + "title": "To create an XSS match set" + } + ], + "DeleteByteMatchSet": [ + { + "input": { + "ByteMatchSetId": "exampleIDs3t-46da-4fdb-b8d5-abc321j569j5", + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes a byte match set with the ID exampleIDs3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "deletebytematchset-1473367566229", + "title": "To delete a byte match set" + } + ], + "DeleteIPSet": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "IPSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5" + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes an IP match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "deleteipset-1472767434306", + "title": "To delete an IP set" + } + ], + "DeleteRule": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "RuleId": "WAFRule-1-Example" + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes a rule with the ID WAFRule-1-Example.", + "id": "deleterule-1474073108749", + "title": "To delete a rule" + } + ], + "DeleteSizeConstraintSet": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5" + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes a size constraint set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "deletesizeconstraintset-1474299857905", + "title": "To delete a size constraint set" + } + ], + "DeleteSqlInjectionMatchSet": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5" + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes a SQL injection match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "deletesqlinjectionmatchset-1474493373197", + "title": "To delete a SQL injection match set" + } + ], + "DeleteWebACL": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "WebACLId": "example-46da-4444-5555-example" + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes a web ACL with the ID example-46da-4444-5555-example.", + "id": "deletewebacl-1472767755931", + "title": "To delete a web ACL" + } + ], + "DeleteXssMatchSet": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5" + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes an XSS match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "deletexssmatchset-1474561302618", + "title": "To delete an XSS match set" + } + ], + "GetByteMatchSet": [ + { + "input": { + "ByteMatchSetId": "exampleIDs3t-46da-4fdb-b8d5-abc321j569j5" + }, + "output": { + "ByteMatchSet": { + "ByteMatchSetId": "exampleIDs3t-46da-4fdb-b8d5-abc321j569j5", + "ByteMatchTuples": [ + { + "FieldToMatch": { + "Data": "referer", + "Type": "HEADER" + }, + "PositionalConstraint": "CONTAINS", + "TargetString": "badrefer1", + "TextTransformation": "NONE" + } + ], + "Name": "ByteMatchNameExample" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns the details of a byte match set with the ID exampleIDs3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "getbytematchset-1473273311532", + "title": "To get a byte match set" + } + ], + "GetChangeToken": [ + { + "input": { + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns a change token to use for a create, update or delete operation.", + "id": "get-change-token-example-1471635120794", + "title": "To get a change token" + } + ], + "GetChangeTokenStatus": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "output": { + "ChangeTokenStatus": "PENDING" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns the status of a change token with the ID abcd12f2-46da-4fdb-b8d5-fbd4c466928f.", + "id": "getchangetokenstatus-1474658417107", + "title": "To get the change token status" + } + ], + "GetIPSet": [ + { + "input": { + "IPSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5" + }, + "output": { + "IPSet": { + "IPSetDescriptors": [ + { + "Type": "IPV4", + "Value": "192.0.2.44/32" + } + ], + "IPSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5", + "Name": "MyIPSetFriendlyName" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns the details of an IP match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "getipset-1474658688675", + "title": "To get an IP set" + } + ], + "GetRule": [ + { + "input": { + "RuleId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5" + }, + "output": { + "Rule": { + "MetricName": "WAFByteHeaderRule", + "Name": "WAFByteHeaderRule", + "Predicates": [ + { + "DataId": "MyByteMatchSetID", + "Negated": false, + "Type": "ByteMatch" + } + ], + "RuleId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns the details of a rule with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "getrule-1474659238790", + "title": "To get a rule" + } + ], + "GetSampledRequests": [ + { + "input": { + "MaxItems": 100, + "RuleId": "WAFRule-1-Example", + "TimeWindow": { + "EndTime": "2016-09-27T15:50Z", + "StartTime": "2016-09-27T15:50Z" + }, + "WebAclId": "createwebacl-1472061481310" + }, + "output": { + "PopulationSize": 50, + "SampledRequests": [ + { + "Action": "BLOCK", + "Request": { + "ClientIP": "192.0.2.44", + "Country": "US", + "HTTPVersion": "HTTP/1.1", + "Headers": [ + { + "Name": "User-Agent", + "Value": "BadBot " + } + ], + "Method": "HEAD" + }, + "Timestamp": "2016-09-27T14:55Z", + "Weight": 1 + } + ], + "TimeWindow": { + "EndTime": "2016-09-27T15:50Z", + "StartTime": "2016-09-27T14:50Z" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns detailed information about 100 requests --a sample-- that AWS WAF randomly selects from among the first 5,000 requests that your AWS resource received between the time period 2016-09-27T15:50Z to 2016-09-27T15:50Z.", + "id": "getsampledrequests-1474927997195", + "title": "To get a sampled requests" + } + ], + "GetSizeConstraintSet": [ + { + "input": { + "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5" + }, + "output": { + "SizeConstraintSet": { + "Name": "MySampleSizeConstraintSet", + "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5", + "SizeConstraints": [ + { + "ComparisonOperator": "GT", + "FieldToMatch": { + "Type": "QUERY_STRING" + }, + "Size": 0, + "TextTransformation": "NONE" + } + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns the details of a size constraint match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "getsizeconstraintset-1475005422493", + "title": "To get a size constraint set" + } + ], + "GetSqlInjectionMatchSet": [ + { + "input": { + "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5" + }, + "output": { + "SqlInjectionMatchSet": { + "Name": "MySQLInjectionMatchSet", + "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5", + "SqlInjectionMatchTuples": [ + { + "FieldToMatch": { + "Type": "QUERY_STRING" + }, + "TextTransformation": "URL_DECODE" + } + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns the details of a SQL injection match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "getsqlinjectionmatchset-1475005940137", + "title": "To get a SQL injection match set" + } + ], + "GetWebACL": [ + { + "input": { + "WebACLId": "createwebacl-1472061481310" + }, + "output": { + "WebACL": { + "DefaultAction": { + "Type": "ALLOW" + }, + "MetricName": "CreateExample", + "Name": "CreateExample", + "Rules": [ + { + "Action": { + "Type": "ALLOW" + }, + "Priority": 1, + "RuleId": "WAFRule-1-Example" + } + ], + "WebACLId": "createwebacl-1472061481310" + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns the details of a web ACL with the ID createwebacl-1472061481310.", + "id": "getwebacl-1475006348525", + "title": "To get a web ACL" + } + ], + "GetXssMatchSet": [ + { + "input": { + "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5" + }, + "output": { + "XssMatchSet": { + "Name": "MySampleXssMatchSet", + "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5", + "XssMatchTuples": [ + { + "FieldToMatch": { + "Type": "QUERY_STRING" + }, + "TextTransformation": "URL_DECODE" + } + ] + } + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns the details of an XSS match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "getxssmatchset-1475187879017", + "title": "To get an XSS match set" + } + ], + "ListIPSets": [ + { + "input": { + "Limit": 100 + }, + "output": { + "IPSets": [ + { + "IPSetId": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "Name": "MyIPSetFriendlyName" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns an array of up to 100 IP match sets.", + "id": "listipsets-1472235676229", + "title": "To list IP sets" + } + ], + "ListRules": [ + { + "input": { + "Limit": 100 + }, + "output": { + "Rules": [ + { + "Name": "WAFByteHeaderRule", + "RuleId": "WAFRule-1-Example" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns an array of up to 100 rules.", + "id": "listrules-1475258406433", + "title": "To list rules" + } + ], + "ListSizeConstraintSets": [ + { + "input": { + "Limit": 100 + }, + "output": { + "SizeConstraintSets": [ + { + "Name": "MySampleSizeConstraintSet", + "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns an array of up to 100 size contraint match sets.", + "id": "listsizeconstraintsets-1474300067597", + "title": "To list a size constraint sets" + } + ], + "ListSqlInjectionMatchSets": [ + { + "input": { + "Limit": 100 + }, + "output": { + "SqlInjectionMatchSets": [ + { + "Name": "MySQLInjectionMatchSet", + "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns an array of up to 100 SQL injection match sets.", + "id": "listsqlinjectionmatchset-1474493560103", + "title": "To list SQL injection match sets" + } + ], + "ListWebACLs": [ + { + "input": { + "Limit": 100 + }, + "output": { + "WebACLs": [ + { + "Name": "WebACLexample", + "WebACLId": "webacl-1472061481310" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns an array of up to 100 web ACLs.", + "id": "listwebacls-1475258732691", + "title": "To list Web ACLs" + } + ], + "ListXssMatchSets": [ + { + "input": { + "Limit": 100 + }, + "output": { + "XssMatchSets": [ + { + "Name": "MySampleXssMatchSet", + "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5" + } + ] + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example returns an array of up to 100 XSS match sets.", + "id": "listxssmatchsets-1474561481168", + "title": "To list XSS match sets" + } + ], + "UpdateByteMatchSet": [ + { + "input": { + "ByteMatchSetId": "exampleIDs3t-46da-4fdb-b8d5-abc321j569j5", + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "Updates": [ + { + "Action": "DELETE", + "ByteMatchTuple": { + "FieldToMatch": { + "Data": "referer", + "Type": "HEADER" + }, + "PositionalConstraint": "CONTAINS", + "TargetString": "badrefer1", + "TextTransformation": "NONE" + } + } + ] + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes a ByteMatchTuple object (filters) in an byte match set with the ID exampleIDs3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "updatebytematchset-1475259074558", + "title": "To update a byte match set" + } + ], + "UpdateIPSet": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "IPSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5", + "Updates": [ + { + "Action": "DELETE", + "IPSetDescriptor": { + "Type": "IPV4", + "Value": "192.0.2.44/32" + } + } + ] + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes an IPSetDescriptor object in an IP match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "updateipset-1475259733625", + "title": "To update an IP set" + } + ], + "UpdateRule": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "RuleId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5", + "Updates": [ + { + "Action": "DELETE", + "Predicate": { + "DataId": "MyByteMatchSetID", + "Negated": false, + "Type": "ByteMatch" + } + } + ] + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes a Predicate object in a rule with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "updaterule-1475260064720", + "title": "To update a rule" + } + ], + "UpdateSizeConstraintSet": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "SizeConstraintSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5", + "Updates": [ + { + "Action": "DELETE", + "SizeConstraint": { + "ComparisonOperator": "GT", + "FieldToMatch": { + "Type": "QUERY_STRING" + }, + "Size": 0, + "TextTransformation": "NONE" + } + } + ] + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes a SizeConstraint object (filters) in a size constraint set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "updatesizeconstraintset-1475531697891", + "title": "To update a size constraint set" + } + ], + "UpdateSqlInjectionMatchSet": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "SqlInjectionMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5", + "Updates": [ + { + "Action": "DELETE", + "SqlInjectionMatchTuple": { + "FieldToMatch": { + "Type": "QUERY_STRING" + }, + "TextTransformation": "URL_DECODE" + } + } + ] + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes a SqlInjectionMatchTuple object (filters) in a SQL injection match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "updatesqlinjectionmatchset-1475532094686", + "title": "To update a SQL injection match set" + } + ], + "UpdateWebACL": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "DefaultAction": { + "Type": "ALLOW" + }, + "Updates": [ + { + "Action": "DELETE", + "ActivatedRule": { + "Action": { + "Type": "ALLOW" + }, + "Priority": 1, + "RuleId": "WAFRule-1-Example" + } + } + ], + "WebACLId": "webacl-1472061481310" + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes an ActivatedRule object in a WebACL with the ID webacl-1472061481310.", + "id": "updatewebacl-1475533627385", + "title": "To update a Web ACL" + } + ], + "UpdateXssMatchSet": [ + { + "input": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f", + "Updates": [ + { + "Action": "DELETE", + "XssMatchTuple": { + "FieldToMatch": { + "Type": "QUERY_STRING" + }, + "TextTransformation": "URL_DECODE" + } + } + ], + "XssMatchSetId": "example1ds3t-46da-4fdb-b8d5-abc321j569j5" + }, + "output": { + "ChangeToken": "abcd12f2-46da-4fdb-b8d5-fbd4c466928f" + }, + "comments": { + "input": { + }, + "output": { + } + }, + "description": "The following example deletes an XssMatchTuple object (filters) in an XssMatchSet with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.", + "id": "updatexssmatchset-1475534098881", + "title": "To update an XSS match set" + } + ] + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/waf-regional/2016-11-28/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/waf-regional/2016-11-28/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/waf-regional/2016-11-28/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/wellarchitected/2020-03-31/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/wellarchitected/2020-03-31/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/wellarchitected/2020-03-31/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/wellarchitected/2020-03-31/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/wellarchitected/2020-03-31/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ea142457a6a77d6e6a54942329f1199bc2f2a60c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/wellarchitected/2020-03-31/paginators-1.json @@ -0,0 +1,3 @@ +{ + "pagination": {} +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/wisdom/2020-10-19/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/wisdom/2020-10-19/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/wisdom/2020-10-19/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/wisdom/2020-10-19/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/wisdom/2020-10-19/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..60b1dca5d5a2dcda0bcba13e929ddb9dd516756d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/wisdom/2020-10-19/paginators-1.json @@ -0,0 +1,64 @@ +{ + "pagination": { + "ListAssistantAssociations": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "assistantAssociationSummaries" + }, + "ListAssistants": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "assistantSummaries" + }, + "ListContents": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "contentSummaries" + }, + "ListKnowledgeBases": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "knowledgeBaseSummaries" + }, + "QueryAssistant": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "results" + }, + "SearchContent": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "contentSummaries" + }, + "SearchSessions": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "sessionSummaries" + }, + "ListImportJobs": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "importJobSummaries" + }, + "ListQuickResponses": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "quickResponseSummaries" + }, + "SearchQuickResponses": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "results" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/workdocs/2016-05-01/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/workdocs/2016-05-01/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/workdocs/2016-05-01/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/workdocs/2016-05-01/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/workdocs/2016-05-01/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..ff2f410a92ee2c5d7e09edd708d2edf2527f8f1e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/workdocs/2016-05-01/paginators-1.json @@ -0,0 +1,67 @@ +{ + "pagination": { + "DescribeDocumentVersions": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "DocumentVersions" + }, + "DescribeFolderContents": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": [ + "Folders", + "Documents" + ] + }, + "DescribeUsers": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "Users" + }, + "DescribeActivities": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "UserActivities" + }, + "DescribeComments": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "Comments" + }, + "DescribeGroups": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "Groups" + }, + "DescribeNotificationSubscriptions": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "Subscriptions" + }, + "DescribeResourcePermissions": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "Principals" + }, + "DescribeRootFolders": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "Folders" + }, + "SearchResources": { + "input_token": "Marker", + "limit_key": "Limit", + "output_token": "Marker", + "result_key": "Items" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/workspaces-thin-client/2023-08-22/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/workspaces-thin-client/2023-08-22/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..9fe21a485705afb8fb5346c56eea58ad5918abfe --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/workspaces-thin-client/2023-08-22/paginators-1.json @@ -0,0 +1,22 @@ +{ + "pagination": { + "ListDevices": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "devices" + }, + "ListEnvironments": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "environments" + }, + "ListSoftwareSets": { + "input_token": "nextToken", + "output_token": "nextToken", + "limit_key": "maxResults", + "result_key": "softwareSets" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/workspaces/2015-04-08/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/workspaces/2015-04-08/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/workspaces/2015-04-08/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/workspaces/2015-04-08/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/workspaces/2015-04-08/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..01176ffbc705dbe19dc7cb609cc84460221d7220 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/workspaces/2015-04-08/paginators-1.json @@ -0,0 +1,54 @@ +{ + "pagination": { + "DescribeWorkspaceBundles": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Bundles" + }, + "DescribeWorkspaceDirectories": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Directories" + }, + "DescribeWorkspaces": { + "limit_key": "Limit", + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Workspaces" + }, + "DescribeAccountModifications": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "AccountModifications" + }, + "DescribeIpGroups": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Result" + }, + "DescribeWorkspaceImages": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "Images" + }, + "DescribeWorkspacesConnectionStatus": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "WorkspacesConnectionStatus" + }, + "ListAvailableManagementCidrRanges": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "ManagementCidrRanges" + }, + "ListAccountLinks": { + "input_token": "NextToken", + "limit_key": "MaxResults", + "output_token": "NextToken", + "result_key": "AccountLinks" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/xray/2016-04-12/examples-1.json b/.venv/lib/python3.13/site-packages/botocore/data/xray/2016-04-12/examples-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0ea7e3b0bbe917eb027880396ac01509becd1fa0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/xray/2016-04-12/examples-1.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "examples": { + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/data/xray/2016-04-12/paginators-1.json b/.venv/lib/python3.13/site-packages/botocore/data/xray/2016-04-12/paginators-1.json new file mode 100644 index 0000000000000000000000000000000000000000..0f65898f26406133ddc20a8f520dbb5aeee3f724 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/data/xray/2016-04-12/paginators-1.json @@ -0,0 +1,69 @@ +{ + "pagination": { + "BatchGetTraces": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Traces", + "non_aggregate_keys": [ + "UnprocessedTraceIds" + ] + }, + "GetServiceGraph": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Services", + "non_aggregate_keys": [ + "StartTime", + "EndTime", + "ContainsOldGroupVersions" + ] + }, + "GetTraceGraph": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Services" + }, + "GetTraceSummaries": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "TraceSummaries", + "non_aggregate_keys": [ + "TracesProcessedCount", + "ApproximateTime" + ] + }, + "GetGroups": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Groups" + }, + "GetSamplingRules": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "SamplingRuleRecords" + }, + "GetSamplingStatisticSummaries": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "SamplingStatisticSummaries" + }, + "GetTimeSeriesServiceStatistics": { + "input_token": "NextToken", + "non_aggregate_keys": [ + "ContainsOldGroupVersions" + ], + "output_token": "NextToken", + "result_key": "TimeSeriesServiceStatistics" + }, + "ListResourcePolicies": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "ResourcePolicies" + }, + "ListTagsForResource": { + "input_token": "NextToken", + "output_token": "NextToken", + "result_key": "Tags" + } + } +} diff --git a/.venv/lib/python3.13/site-packages/botocore/docs/__init__.py b/.venv/lib/python3.13/site-packages/botocore/docs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..844f5de59b05a334d9142fdbf087d6870e94970d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/docs/__init__.py @@ -0,0 +1,54 @@ +# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +import os + +from botocore.docs.service import ServiceDocumenter + +DEPRECATED_SERVICE_NAMES = {'sms-voice'} + + +def generate_docs(root_dir, session): + """Generates the reference documentation for botocore + + This will go through every available AWS service and output ReSTructured + text files documenting each service. + + :param root_dir: The directory to write the reference files to. Each + service's reference documentation is loacated at + root_dir/reference/services/service-name.rst + """ + # Create the root directory where all service docs live. + services_dir_path = os.path.join(root_dir, 'reference', 'services') + if not os.path.exists(services_dir_path): + os.makedirs(services_dir_path) + + # Prevents deprecated service names from being generated in docs. + available_services = [ + service + for service in session.get_available_services() + if service not in DEPRECATED_SERVICE_NAMES + ] + + # Generate reference docs and write them out. + for service_name in available_services: + docs = ServiceDocumenter( + service_name, session, services_dir_path + ).document_service() + + # Write the main service documentation page. + # Path: /reference/services//index.rst + service_file_path = os.path.join( + services_dir_path, f'{service_name}.rst' + ) + with open(service_file_path, 'wb') as f: + f.write(docs) diff --git a/.venv/lib/python3.13/site-packages/botocore/docs/client.py b/.venv/lib/python3.13/site-packages/botocore/docs/client.py new file mode 100644 index 0000000000000000000000000000000000000000..41e37426ec8f8d713f52a8678763f6f77b61dac1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/docs/client.py @@ -0,0 +1,453 @@ +# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +import os + +from botocore import xform_name +from botocore.compat import OrderedDict +from botocore.docs.bcdoc.restdoc import DocumentStructure +from botocore.docs.example import ResponseExampleDocumenter +from botocore.docs.method import ( + document_custom_method, + document_model_driven_method, + get_instance_public_methods, +) +from botocore.docs.params import ResponseParamsDocumenter +from botocore.docs.sharedexample import document_shared_examples +from botocore.docs.utils import DocumentedShape, get_official_service_name + + +def _allowlist_generate_presigned_url(method_name, service_name, **kwargs): + if method_name != 'generate_presigned_url': + return None + return service_name in ['s3'] + + +class ClientDocumenter: + _CLIENT_METHODS_FILTERS = [ + _allowlist_generate_presigned_url, + ] + + def __init__(self, client, root_docs_path, shared_examples=None): + self._client = client + self._client_class_name = self._client.__class__.__name__ + self._root_docs_path = root_docs_path + self._shared_examples = shared_examples + if self._shared_examples is None: + self._shared_examples = {} + self._service_name = self._client.meta.service_model.service_name + + def document_client(self, section): + """Documents a client and its methods + + :param section: The section to write to. + """ + self._add_title(section) + self._add_class_signature(section) + client_methods = self._get_client_methods() + self._add_client_intro(section, client_methods) + self._add_client_methods(client_methods) + + def _get_client_methods(self): + client_methods = get_instance_public_methods(self._client) + return self._filter_client_methods(client_methods) + + def _filter_client_methods(self, client_methods): + filtered_methods = {} + for method_name, method in client_methods.items(): + include = self._filter_client_method( + method=method, + method_name=method_name, + service_name=self._service_name, + ) + if include: + filtered_methods[method_name] = method + return filtered_methods + + def _filter_client_method(self, **kwargs): + # Apply each filter to the method + for filter in self._CLIENT_METHODS_FILTERS: + filter_include = filter(**kwargs) + # Use the first non-None value returned by any of the filters + if filter_include is not None: + return filter_include + # Otherwise default to including it + return True + + def _add_title(self, section): + section.style.h2('Client') + + def _add_client_intro(self, section, client_methods): + section = section.add_new_section('intro') + # Write out the top level description for the client. + official_service_name = get_official_service_name( + self._client.meta.service_model + ) + section.write( + f"A low-level client representing {official_service_name}" + ) + section.style.new_line() + section.include_doc_string( + self._client.meta.service_model.documentation + ) + + # Write out the client example instantiation. + self._add_client_creation_example(section) + + # List out all of the possible client methods. + section.style.dedent() + section.style.new_paragraph() + section.writeln('These are the available methods:') + section.style.toctree() + for method_name in sorted(client_methods): + section.style.tocitem(f'{self._service_name}/client/{method_name}') + + def _add_class_signature(self, section): + section.style.start_sphinx_py_class( + class_name=f'{self._client_class_name}.Client' + ) + + def _add_client_creation_example(self, section): + section.style.start_codeblock() + section.style.new_line() + section.write( + f'client = session.create_client(\'{self._service_name}\')' + ) + section.style.end_codeblock() + + def _add_client_methods(self, client_methods): + for method_name in sorted(client_methods): + # Create a new DocumentStructure for each client method and add contents. + method_doc_structure = DocumentStructure( + method_name, target='html' + ) + self._add_client_method( + method_doc_structure, method_name, client_methods[method_name] + ) + # Write client methods in individual/nested files. + # Path: /reference/services//client/.rst + client_dir_path = os.path.join( + self._root_docs_path, self._service_name, 'client' + ) + method_doc_structure.write_to_file(client_dir_path, method_name) + + def _add_client_method(self, section, method_name, method): + breadcrumb_section = section.add_new_section('breadcrumb') + breadcrumb_section.style.ref( + self._client_class_name, f'../../{self._service_name}' + ) + breadcrumb_section.write(f' / Client / {method_name}') + section.add_title_section(method_name) + method_section = section.add_new_section( + method_name, + context={'qualifier': f'{self._client_class_name}.Client.'}, + ) + if self._is_custom_method(method_name): + self._add_custom_method( + method_section, + method_name, + method, + ) + else: + self._add_model_driven_method(method_section, method_name) + + def _is_custom_method(self, method_name): + return method_name not in self._client.meta.method_to_api_mapping + + def _add_custom_method(self, section, method_name, method): + document_custom_method(section, method_name, method) + + def _add_method_exceptions_list(self, section, operation_model): + error_section = section.add_new_section('exceptions') + error_section.style.new_line() + error_section.style.bold('Exceptions') + error_section.style.new_line() + for error in operation_model.error_shapes: + class_name = ( + f'{self._client_class_name}.Client.exceptions.{error.name}' + ) + error_section.style.li(f':py:class:`{class_name}`') + + def _add_model_driven_method(self, section, method_name): + service_model = self._client.meta.service_model + operation_name = self._client.meta.method_to_api_mapping[method_name] + operation_model = service_model.operation_model(operation_name) + + example_prefix = f'response = client.{method_name}' + full_method_name = ( + f"{section.context.get('qualifier', '')}{method_name}" + ) + document_model_driven_method( + section, + full_method_name, + operation_model, + event_emitter=self._client.meta.events, + method_description=operation_model.documentation, + example_prefix=example_prefix, + ) + + # Add any modeled exceptions + if operation_model.error_shapes: + self._add_method_exceptions_list(section, operation_model) + + # Add the shared examples + shared_examples = self._shared_examples.get(operation_name) + if shared_examples: + document_shared_examples( + section, operation_model, example_prefix, shared_examples + ) + + +class ClientExceptionsDocumenter: + _USER_GUIDE_LINK = ( + 'https://boto3.amazonaws.com/' + 'v1/documentation/api/latest/guide/error-handling.html' + ) + _GENERIC_ERROR_SHAPE = DocumentedShape( + name='Error', + type_name='structure', + documentation=('Normalized access to common exception attributes.'), + members=OrderedDict( + [ + ( + 'Code', + DocumentedShape( + name='Code', + type_name='string', + documentation=( + 'An identifier specifying the exception type.' + ), + ), + ), + ( + 'Message', + DocumentedShape( + name='Message', + type_name='string', + documentation=( + 'A descriptive message explaining why the exception ' + 'occured.' + ), + ), + ), + ] + ), + ) + + def __init__(self, client, root_docs_path): + self._client = client + self._client_class_name = self._client.__class__.__name__ + self._service_name = self._client.meta.service_model.service_name + self._root_docs_path = root_docs_path + + def document_exceptions(self, section): + self._add_title(section) + self._add_overview(section) + self._add_exceptions_list(section) + self._add_exception_classes() + + def _add_title(self, section): + section.style.h2('Client Exceptions') + + def _add_overview(self, section): + section.style.new_line() + section.write( + 'Client exceptions are available on a client instance ' + 'via the ``exceptions`` property. For more detailed instructions ' + 'and examples on the exact usage of client exceptions, see the ' + 'error handling ' + ) + section.style.external_link( + title='user guide', + link=self._USER_GUIDE_LINK, + ) + section.write('.') + section.style.new_line() + + def _exception_class_name(self, shape): + return f'{self._client_class_name}.Client.exceptions.{shape.name}' + + def _add_exceptions_list(self, section): + error_shapes = self._client.meta.service_model.error_shapes + if not error_shapes: + section.style.new_line() + section.write('This client has no modeled exception classes.') + section.style.new_line() + return + section.style.new_line() + section.writeln('The available client exceptions are:') + section.style.toctree() + for shape in error_shapes: + section.style.tocitem( + f'{self._service_name}/client/exceptions/{shape.name}' + ) + + def _add_exception_classes(self): + for shape in self._client.meta.service_model.error_shapes: + # Create a new DocumentStructure for each exception method and add contents. + exception_doc_structure = DocumentStructure( + shape.name, target='html' + ) + self._add_exception_class(exception_doc_structure, shape) + # Write exceptions in individual/nested files. + # Path: /reference/services//client/exceptions/.rst + exception_dir_path = os.path.join( + self._root_docs_path, + self._service_name, + 'client', + 'exceptions', + ) + exception_doc_structure.write_to_file( + exception_dir_path, shape.name + ) + + def _add_exception_class(self, section, shape): + breadcrumb_section = section.add_new_section('breadcrumb') + breadcrumb_section.style.ref( + self._client_class_name, f'../../../{self._service_name}' + ) + breadcrumb_section.write(f' / Client / exceptions / {shape.name}') + section.add_title_section(shape.name) + class_section = section.add_new_section(shape.name) + class_name = self._exception_class_name(shape) + class_section.style.start_sphinx_py_class(class_name=class_name) + self._add_top_level_documentation(class_section, shape) + self._add_exception_catch_example(class_section, shape) + self._add_response_attr(class_section, shape) + class_section.style.end_sphinx_py_class() + + def _add_top_level_documentation(self, section, shape): + if shape.documentation: + section.style.new_line() + section.include_doc_string(shape.documentation) + section.style.new_line() + + def _add_exception_catch_example(self, section, shape): + section.style.new_line() + section.style.bold('Example') + section.style.new_paragraph() + section.style.start_codeblock() + section.write('try:') + section.style.indent() + section.style.new_line() + section.write('...') + section.style.dedent() + section.style.new_line() + section.write(f'except client.exceptions.{shape.name} as e:') + section.style.indent() + section.style.new_line() + section.write('print(e.response)') + section.style.dedent() + section.style.end_codeblock() + + def _add_response_attr(self, section, shape): + response_section = section.add_new_section('response') + response_section.style.start_sphinx_py_attr('response') + self._add_response_attr_description(response_section) + self._add_response_example(response_section, shape) + self._add_response_params(response_section, shape) + response_section.style.end_sphinx_py_attr() + + def _add_response_attr_description(self, section): + section.style.new_line() + section.include_doc_string( + 'The parsed error response. All exceptions have a top level ' + '``Error`` key that provides normalized access to common ' + 'exception atrributes. All other keys are specific to this ' + 'service or exception class.' + ) + section.style.new_line() + + def _add_response_example(self, section, shape): + example_section = section.add_new_section('syntax') + example_section.style.new_line() + example_section.style.bold('Syntax') + example_section.style.new_paragraph() + documenter = ResponseExampleDocumenter( + service_name=self._service_name, + operation_name=None, + event_emitter=self._client.meta.events, + ) + documenter.document_example( + example_section, + shape, + include=[self._GENERIC_ERROR_SHAPE], + ) + + def _add_response_params(self, section, shape): + params_section = section.add_new_section('Structure') + params_section.style.new_line() + params_section.style.bold('Structure') + params_section.style.new_paragraph() + documenter = ResponseParamsDocumenter( + service_name=self._service_name, + operation_name=None, + event_emitter=self._client.meta.events, + ) + documenter.document_params( + params_section, + shape, + include=[self._GENERIC_ERROR_SHAPE], + ) + + +class ClientContextParamsDocumenter: + _CONFIG_GUIDE_LINK = ( + 'https://boto3.amazonaws.com/' + 'v1/documentation/api/latest/guide/configuration.html' + ) + + OMITTED_CONTEXT_PARAMS = { + 's3': ( + 'Accelerate', + 'DisableMultiRegionAccessPoints', + 'ForcePathStyle', + 'UseArnRegion', + ), + 's3control': ('UseArnRegion',), + } + + def __init__(self, service_name, context_params): + self._service_name = service_name + self._context_params = context_params + + def document_context_params(self, section): + self._add_title(section) + self._add_overview(section) + self._add_context_params_list(section) + + def _add_title(self, section): + section.style.h2('Client Context Parameters') + + def _add_overview(self, section): + section.style.new_line() + section.write( + 'Client context parameters are configurable on a client ' + 'instance via the ``client_context_params`` parameter in the ' + '``Config`` object. For more detailed instructions and examples ' + 'on the exact usage of context params see the ' + ) + section.style.external_link( + title='configuration guide', + link=self._CONFIG_GUIDE_LINK, + ) + section.write('.') + section.style.new_line() + + def _add_context_params_list(self, section): + section.style.new_line() + sn = f'``{self._service_name}``' + section.writeln(f'The available {sn} client context params are:') + for param in self._context_params: + section.style.new_line() + name = f'``{xform_name(param.name)}``' + section.write(f'* {name} ({param.type}) - {param.documentation}') diff --git a/.venv/lib/python3.13/site-packages/botocore/docs/docstring.py b/.venv/lib/python3.13/site-packages/botocore/docs/docstring.py new file mode 100644 index 0000000000000000000000000000000000000000..93b2e6b23cc5b295fe23a151ae3a0ffe797f0db6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/docs/docstring.py @@ -0,0 +1,97 @@ +# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +from botocore.docs.bcdoc.restdoc import DocumentStructure +from botocore.docs.method import document_model_driven_method +from botocore.docs.paginator import document_paginate_method +from botocore.docs.waiter import document_wait_method + + +class LazyLoadedDocstring(str): + """Used for lazily loading docstrings + + You can instantiate this class and assign it to a __doc__ value. + The docstring will not be generated till accessed via __doc__ or + help(). Note that all docstring classes **must** subclass from + this class. It cannot be used directly as a docstring. + """ + + def __init__(self, *args, **kwargs): + """ + The args and kwargs are the same as the underlying document + generation function. These just get proxied to the underlying + function. + """ + super().__init__() + self._gen_args = args + self._gen_kwargs = kwargs + self._docstring = None + + def __new__(cls, *args, **kwargs): + # Needed in order to sub class from str with args and kwargs + return super().__new__(cls) + + def _write_docstring(self, *args, **kwargs): + raise NotImplementedError( + '_write_docstring is not implemented. Please subclass from ' + 'this class and provide your own _write_docstring method' + ) + + def expandtabs(self, tabsize=8): + """Expands tabs to spaces + + So this is a big hack in order to get lazy loaded docstring work + for the ``help()``. In the ``help()`` function, ``pydoc`` and + ``inspect`` are used. At some point the ``inspect.cleandoc`` + method is called. To clean the docs ``expandtabs`` is called + and that is where we override the method to generate and return the + docstrings. + """ + if self._docstring is None: + self._generate() + return self._docstring.expandtabs(tabsize) + + def __str__(self): + return self._generate() + + # __doc__ of target will use either __repr__ or __str__ of this class. + __repr__ = __str__ + + def _generate(self): + # Generate the docstring if it is not already cached. + if self._docstring is None: + self._docstring = self._create_docstring() + return self._docstring + + def _create_docstring(self): + docstring_structure = DocumentStructure('docstring', target='html') + # Call the document method function with the args and kwargs + # passed to the class. + self._write_docstring( + docstring_structure, *self._gen_args, **self._gen_kwargs + ) + return docstring_structure.flush_structure().decode('utf-8') + + +class ClientMethodDocstring(LazyLoadedDocstring): + def _write_docstring(self, *args, **kwargs): + document_model_driven_method(*args, **kwargs) + + +class WaiterDocstring(LazyLoadedDocstring): + def _write_docstring(self, *args, **kwargs): + document_wait_method(*args, **kwargs) + + +class PaginatorDocstring(LazyLoadedDocstring): + def _write_docstring(self, *args, **kwargs): + document_paginate_method(*args, **kwargs) diff --git a/.venv/lib/python3.13/site-packages/botocore/docs/example.py b/.venv/lib/python3.13/site-packages/botocore/docs/example.py new file mode 100644 index 0000000000000000000000000000000000000000..cb43db550962030728a69d3b47ae50d40c15fa35 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/docs/example.py @@ -0,0 +1,236 @@ +# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +from botocore.docs.shape import ShapeDocumenter +from botocore.docs.utils import py_default + + +class BaseExampleDocumenter(ShapeDocumenter): + def document_example( + self, section, shape, prefix=None, include=None, exclude=None + ): + """Generates an example based on a shape + + :param section: The section to write the documentation to. + + :param shape: The shape of the operation. + + :param prefix: Anything to be included before the example + + :type include: Dictionary where keys are parameter names and + values are the shapes of the parameter names. + :param include: The parameter shapes to include in the documentation. + + :type exclude: List of the names of the parameters to exclude. + :param exclude: The names of the parameters to exclude from + documentation. + """ + history = [] + section.style.new_line() + section.style.start_codeblock() + if prefix is not None: + section.write(prefix) + self.traverse_and_document_shape( + section=section, + shape=shape, + history=history, + include=include, + exclude=exclude, + ) + final_blank_line_section = section.add_new_section('final-blank-line') + final_blank_line_section.style.new_line() + + def document_recursive_shape(self, section, shape, **kwargs): + section.write('{\'... recursive ...\'}') + + def document_shape_default( + self, section, shape, history, include=None, exclude=None, **kwargs + ): + py_type = self._get_special_py_default(shape) + if py_type is None: + py_type = py_default(shape.type_name) + + if self._context.get('streaming_shape') == shape: + py_type = 'StreamingBody()' + section.write(py_type) + + def document_shape_type_string( + self, section, shape, history, include=None, exclude=None, **kwargs + ): + if 'enum' in shape.metadata: + for i, enum in enumerate(shape.metadata['enum']): + section.write(f'\'{enum}\'') + if i < len(shape.metadata['enum']) - 1: + section.write('|') + else: + self.document_shape_default(section, shape, history) + + def document_shape_type_list( + self, section, shape, history, include=None, exclude=None, **kwargs + ): + param_shape = shape.member + list_section = section.add_new_section('list-value') + self._start_nested_param(list_section, '[') + param_section = list_section.add_new_section( + 'member', context={'shape': param_shape.name} + ) + self.traverse_and_document_shape( + section=param_section, shape=param_shape, history=history + ) + ending_comma_section = list_section.add_new_section('ending-comma') + ending_comma_section.write(',') + ending_bracket_section = list_section.add_new_section('ending-bracket') + self._end_nested_param(ending_bracket_section, ']') + + def document_shape_type_structure( + self, section, shape, history, include=None, exclude=None, **kwargs + ): + if not shape.members: + section.write('{}') + return + + section = section.add_new_section('structure-value') + self._start_nested_param(section, '{') + + input_members = self._add_members_to_shape(shape.members, include) + + for i, param in enumerate(input_members): + if exclude and param in exclude: + continue + param_section = section.add_new_section(param) + param_section.write(f'\'{param}\': ') + param_shape = input_members[param] + param_value_section = param_section.add_new_section( + 'member-value', context={'shape': param_shape.name} + ) + self.traverse_and_document_shape( + section=param_value_section, + shape=param_shape, + history=history, + name=param, + ) + if i < len(input_members) - 1: + ending_comma_section = param_section.add_new_section( + 'ending-comma' + ) + ending_comma_section.write(',') + ending_comma_section.style.new_line() + self._end_structure(section, '{', '}') + + def document_shape_type_map( + self, section, shape, history, include=None, exclude=None, **kwargs + ): + map_section = section.add_new_section('map-value') + self._start_nested_param(map_section, '{') + value_shape = shape.value + key_section = map_section.add_new_section( + 'key', context={'shape': shape.key.name} + ) + key_section.write('\'string\': ') + value_section = map_section.add_new_section( + 'value', context={'shape': value_shape.name} + ) + self.traverse_and_document_shape( + section=value_section, shape=value_shape, history=history + ) + end_bracket_section = map_section.add_new_section('ending-bracket') + self._end_nested_param(end_bracket_section, '}') + + def _add_members_to_shape(self, members, include): + if include: + members = members.copy() + for param in include: + members[param.name] = param + return members + + def _start_nested_param(self, section, start=None): + if start is not None: + section.write(start) + section.style.indent() + section.style.indent() + section.style.new_line() + + def _end_nested_param(self, section, end=None): + section.style.dedent() + section.style.dedent() + section.style.new_line() + if end is not None: + section.write(end) + + def _end_structure(self, section, start, end): + # If there are no members in the strucuture, then make sure the + # start and the end bracket are on the same line, by removing all + # previous text and writing the start and end. + if not section.available_sections: + section.clear_text() + section.write(start + end) + self._end_nested_param(section) + else: + end_bracket_section = section.add_new_section('ending-bracket') + self._end_nested_param(end_bracket_section, end) + + +class ResponseExampleDocumenter(BaseExampleDocumenter): + EVENT_NAME = 'response-example' + + def document_shape_type_event_stream( + self, section, shape, history, **kwargs + ): + section.write('EventStream(') + self.document_shape_type_structure(section, shape, history, **kwargs) + end_section = section.add_new_section('event-stream-end') + end_section.write(')') + + +class RequestExampleDocumenter(BaseExampleDocumenter): + EVENT_NAME = 'request-example' + + def document_shape_type_structure( + self, section, shape, history, include=None, exclude=None, **kwargs + ): + param_format = '\'%s\'' + operator = ': ' + start = '{' + end = '}' + + if len(history) <= 1: + operator = '=' + start = '(' + end = ')' + param_format = '%s' + section = section.add_new_section('structure-value') + self._start_nested_param(section, start) + input_members = self._add_members_to_shape(shape.members, include) + + for i, param in enumerate(input_members): + if exclude and param in exclude: + continue + param_section = section.add_new_section(param) + param_section.write(param_format % param) + param_section.write(operator) + param_shape = input_members[param] + param_value_section = param_section.add_new_section( + 'member-value', context={'shape': param_shape.name} + ) + self.traverse_and_document_shape( + section=param_value_section, + shape=param_shape, + history=history, + name=param, + ) + if i < len(input_members) - 1: + ending_comma_section = param_section.add_new_section( + 'ending-comma' + ) + ending_comma_section.write(',') + ending_comma_section.style.new_line() + self._end_structure(section, start, end) diff --git a/.venv/lib/python3.13/site-packages/botocore/docs/method.py b/.venv/lib/python3.13/site-packages/botocore/docs/method.py new file mode 100644 index 0000000000000000000000000000000000000000..5db906c8ddd5c1278620bcf7479d78b6cf6ea903 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/docs/method.py @@ -0,0 +1,328 @@ +# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +import inspect +import types + +from botocore.docs.example import ( + RequestExampleDocumenter, + ResponseExampleDocumenter, +) +from botocore.docs.params import ( + RequestParamsDocumenter, + ResponseParamsDocumenter, +) + +AWS_DOC_BASE = 'https://docs.aws.amazon.com/goto/WebAPI' + + +def get_instance_public_methods(instance): + """Retrieves an objects public methods + + :param instance: The instance of the class to inspect + :rtype: dict + :returns: A dictionary that represents an instance's methods where + the keys are the name of the methods and the + values are the handler to the method. + """ + instance_members = inspect.getmembers(instance) + instance_methods = {} + for name, member in instance_members: + if not name.startswith('_'): + if inspect.ismethod(member): + instance_methods[name] = member + return instance_methods + + +def document_model_driven_signature( + section, name, operation_model, include=None, exclude=None +): + """Documents the signature of a model-driven method + + :param section: The section to write the documentation to. + + :param name: The name of the method + + :param operation_model: The operation model for the method + + :type include: Dictionary where keys are parameter names and + values are the shapes of the parameter names. + :param include: The parameter shapes to include in the documentation. + + :type exclude: List of the names of the parameters to exclude. + :param exclude: The names of the parameters to exclude from + documentation. + """ + params = {} + if operation_model.input_shape: + params = operation_model.input_shape.members + + parameter_names = list(params.keys()) + + if include is not None: + for member in include: + parameter_names.append(member.name) + + if exclude is not None: + for member in exclude: + if member in parameter_names: + parameter_names.remove(member) + + signature_params = '' + if parameter_names: + signature_params = '**kwargs' + section.style.start_sphinx_py_method(name, signature_params) + + +def document_custom_signature( + section, name, method, include=None, exclude=None +): + """Documents the signature of a custom method + + :param section: The section to write the documentation to. + + :param name: The name of the method + + :param method: The handle to the method being documented + + :type include: Dictionary where keys are parameter names and + values are the shapes of the parameter names. + :param include: The parameter shapes to include in the documentation. + + :type exclude: List of the names of the parameters to exclude. + :param exclude: The names of the parameters to exclude from + documentation. + """ + signature = inspect.signature(method) + # "raw" class methods are FunctionType and they include "self" param + # object methods are MethodType and they skip the "self" param + if isinstance(method, types.FunctionType): + self_param = next(iter(signature.parameters)) + self_kind = signature.parameters[self_param].kind + # safety check that we got the right parameter + assert self_kind == inspect.Parameter.POSITIONAL_OR_KEYWORD + new_params = signature.parameters.copy() + del new_params[self_param] + signature = signature.replace(parameters=new_params.values()) + signature_params = str(signature).lstrip('(') + signature_params = signature_params.rstrip(')') + section.style.start_sphinx_py_method(name, signature_params) + + +def document_custom_method(section, method_name, method): + """Documents a non-data driven method + + :param section: The section to write the documentation to. + + :param method_name: The name of the method + + :param method: The handle to the method being documented + """ + full_method_name = f"{section.context.get('qualifier', '')}{method_name}" + document_custom_signature(section, full_method_name, method) + method_intro_section = section.add_new_section('method-intro') + method_intro_section.writeln('') + doc_string = inspect.getdoc(method) + if doc_string is not None: + method_intro_section.style.write_py_doc_string(doc_string) + + +def document_model_driven_method( + section, + method_name, + operation_model, + event_emitter, + method_description=None, + example_prefix=None, + include_input=None, + include_output=None, + exclude_input=None, + exclude_output=None, + document_output=True, + include_signature=True, +): + """Documents an individual method + + :param section: The section to write to + + :param method_name: The name of the method + + :param operation_model: The model of the operation + + :param event_emitter: The event emitter to use to emit events + + :param example_prefix: The prefix to use in the method example. + + :type include_input: Dictionary where keys are parameter names and + values are the shapes of the parameter names. + :param include_input: The parameter shapes to include in the + input documentation. + + :type include_output: Dictionary where keys are parameter names and + values are the shapes of the parameter names. + :param include_input: The parameter shapes to include in the + output documentation. + + :type exclude_input: List of the names of the parameters to exclude. + :param exclude_input: The names of the parameters to exclude from + input documentation. + + :type exclude_output: List of the names of the parameters to exclude. + :param exclude_input: The names of the parameters to exclude from + output documentation. + + :param document_output: A boolean flag to indicate whether to + document the output. + + :param include_signature: Whether or not to include the signature. + It is useful for generating docstrings. + """ + # Add the signature if specified. + if include_signature: + document_model_driven_signature( + section, + method_name, + operation_model, + include=include_input, + exclude=exclude_input, + ) + + # Add the description for the method. + method_intro_section = section.add_new_section('method-intro') + method_intro_section.include_doc_string(method_description) + if operation_model.deprecated: + method_intro_section.style.start_danger() + method_intro_section.writeln( + 'This operation is deprecated and may not function as ' + 'expected. This operation should not be used going forward ' + 'and is only kept for the purpose of backwards compatiblity.' + ) + method_intro_section.style.end_danger() + service_uid = operation_model.service_model.metadata.get('uid') + if service_uid is not None: + method_intro_section.style.new_paragraph() + method_intro_section.write("See also: ") + link = f"{AWS_DOC_BASE}/{service_uid}/{operation_model.name}" + method_intro_section.style.external_link( + title="AWS API Documentation", link=link + ) + method_intro_section.writeln('') + + # Add the example section. + example_section = section.add_new_section('request-example') + example_section.style.new_paragraph() + example_section.style.bold('Request Syntax') + + context = { + 'special_shape_types': { + 'streaming_input_shape': operation_model.get_streaming_input(), + 'streaming_output_shape': operation_model.get_streaming_output(), + 'eventstream_output_shape': operation_model.get_event_stream_output(), + }, + } + + if operation_model.input_shape: + RequestExampleDocumenter( + service_name=operation_model.service_model.service_name, + operation_name=operation_model.name, + event_emitter=event_emitter, + context=context, + ).document_example( + example_section, + operation_model.input_shape, + prefix=example_prefix, + include=include_input, + exclude=exclude_input, + ) + else: + example_section.style.new_paragraph() + example_section.style.start_codeblock() + example_section.write(example_prefix + '()') + + # Add the request parameter documentation. + request_params_section = section.add_new_section('request-params') + if operation_model.input_shape: + RequestParamsDocumenter( + service_name=operation_model.service_model.service_name, + operation_name=operation_model.name, + event_emitter=event_emitter, + context=context, + ).document_params( + request_params_section, + operation_model.input_shape, + include=include_input, + exclude=exclude_input, + ) + + # Add the return value documentation + return_section = section.add_new_section('return') + return_section.style.new_line() + if operation_model.output_shape is not None and document_output: + return_section.write(':rtype: dict') + return_section.style.new_line() + return_section.write(':returns: ') + return_section.style.indent() + return_section.style.new_line() + + # If the operation is an event stream, describe the tagged union + event_stream_output = operation_model.get_event_stream_output() + if event_stream_output: + event_section = return_section.add_new_section('event-stream') + event_section.style.new_paragraph() + event_section.write( + 'The response of this operation contains an ' + ':class:`.EventStream` member. When iterated the ' + ':class:`.EventStream` will yield events based on the ' + 'structure below, where only one of the top level keys ' + 'will be present for any given event.' + ) + event_section.style.new_line() + + # Add an example return value + return_example_section = return_section.add_new_section( + 'response-example' + ) + return_example_section.style.new_line() + return_example_section.style.bold('Response Syntax') + return_example_section.style.new_paragraph() + ResponseExampleDocumenter( + service_name=operation_model.service_model.service_name, + operation_name=operation_model.name, + event_emitter=event_emitter, + context=context, + ).document_example( + return_example_section, + operation_model.output_shape, + include=include_output, + exclude=exclude_output, + ) + + # Add a description for the return value + return_description_section = return_section.add_new_section( + 'description' + ) + return_description_section.style.new_line() + return_description_section.style.bold('Response Structure') + return_description_section.style.new_paragraph() + ResponseParamsDocumenter( + service_name=operation_model.service_model.service_name, + operation_name=operation_model.name, + event_emitter=event_emitter, + context=context, + ).document_params( + return_description_section, + operation_model.output_shape, + include=include_output, + exclude=exclude_output, + ) + else: + return_section.write(':returns: None') diff --git a/.venv/lib/python3.13/site-packages/botocore/docs/paginator.py b/.venv/lib/python3.13/site-packages/botocore/docs/paginator.py new file mode 100644 index 0000000000000000000000000000000000000000..2c9b30034f8c4feb64a8e01de86f476488edac63 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/docs/paginator.py @@ -0,0 +1,241 @@ +# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +import os + +from botocore import xform_name +from botocore.compat import OrderedDict +from botocore.docs.bcdoc.restdoc import DocumentStructure +from botocore.docs.method import document_model_driven_method +from botocore.docs.utils import DocumentedShape +from botocore.utils import get_service_module_name + + +class PaginatorDocumenter: + def __init__(self, client, service_paginator_model, root_docs_path): + self._client = client + self._client_class_name = self._client.__class__.__name__ + self._service_name = self._client.meta.service_model.service_name + self._service_paginator_model = service_paginator_model + self._root_docs_path = root_docs_path + self._USER_GUIDE_LINK = ( + 'https://boto3.amazonaws.com/' + 'v1/documentation/api/latest/guide/paginators.html' + ) + + def document_paginators(self, section): + """Documents the various paginators for a service + + param section: The section to write to. + """ + section.style.h2('Paginators') + self._add_overview(section) + section.style.new_line() + section.writeln('The available paginators are:') + section.style.toctree() + + paginator_names = sorted( + self._service_paginator_model._paginator_config + ) + + # List the available paginators and then document each paginator. + for paginator_name in paginator_names: + section.style.tocitem( + f'{self._service_name}/paginator/{paginator_name}' + ) + # Create a new DocumentStructure for each paginator and add contents. + paginator_doc_structure = DocumentStructure( + paginator_name, target='html' + ) + self._add_paginator(paginator_doc_structure, paginator_name) + # Write paginators in individual/nested files. + # Path: /reference/services//paginator/.rst + paginator_dir_path = os.path.join( + self._root_docs_path, self._service_name, 'paginator' + ) + paginator_doc_structure.write_to_file( + paginator_dir_path, paginator_name + ) + + def _add_paginator(self, section, paginator_name): + breadcrumb_section = section.add_new_section('breadcrumb') + breadcrumb_section.style.ref( + self._client_class_name, f'../../{self._service_name}' + ) + breadcrumb_section.write(f' / Paginator / {paginator_name}') + section.add_title_section(paginator_name) + + # Docment the paginator class + paginator_section = section.add_new_section(paginator_name) + paginator_section.style.start_sphinx_py_class( + class_name=( + f'{self._client_class_name}.Paginator.{paginator_name}' + ) + ) + paginator_section.style.start_codeblock() + paginator_section.style.new_line() + + # Document how to instantiate the paginator. + paginator_section.write( + f"paginator = client.get_paginator('{xform_name(paginator_name)}')" + ) + paginator_section.style.end_codeblock() + paginator_section.style.new_line() + # Get the pagination model for the particular paginator. + paginator_config = self._service_paginator_model.get_paginator( + paginator_name + ) + document_paginate_method( + section=paginator_section, + paginator_name=paginator_name, + event_emitter=self._client.meta.events, + service_model=self._client.meta.service_model, + paginator_config=paginator_config, + ) + + def _add_overview(self, section): + section.style.new_line() + section.write( + 'Paginators are available on a client instance ' + 'via the ``get_paginator`` method. For more detailed instructions ' + 'and examples on the usage of paginators, see the ' + 'paginators ' + ) + section.style.external_link( + title='user guide', + link=self._USER_GUIDE_LINK, + ) + section.write('.') + section.style.new_line() + + +def document_paginate_method( + section, + paginator_name, + event_emitter, + service_model, + paginator_config, + include_signature=True, +): + """Documents the paginate method of a paginator + + :param section: The section to write to + + :param paginator_name: The name of the paginator. It is snake cased. + + :param event_emitter: The event emitter to use to emit events + + :param service_model: The service model + + :param paginator_config: The paginator config associated to a particular + paginator. + + :param include_signature: Whether or not to include the signature. + It is useful for generating docstrings. + """ + # Retrieve the operation model of the underlying operation. + operation_model = service_model.operation_model(paginator_name) + + # Add representations of the request and response parameters + # we want to include in the description of the paginate method. + # These are parameters we expose via the botocore interface. + pagination_config_members = OrderedDict() + + pagination_config_members['MaxItems'] = DocumentedShape( + name='MaxItems', + type_name='integer', + documentation=( + '

The total number of items to return. If the total ' + 'number of items available is more than the value ' + 'specified in max-items then a NextToken ' + 'will be provided in the output that you can use to ' + 'resume pagination.

' + ), + ) + + if paginator_config.get('limit_key', None): + pagination_config_members['PageSize'] = DocumentedShape( + name='PageSize', + type_name='integer', + documentation='

The size of each page.

', + ) + + pagination_config_members['StartingToken'] = DocumentedShape( + name='StartingToken', + type_name='string', + documentation=( + '

A token to specify where to start paginating. ' + 'This is the NextToken from a previous ' + 'response.

' + ), + ) + + botocore_pagination_params = [ + DocumentedShape( + name='PaginationConfig', + type_name='structure', + documentation=( + '

A dictionary that provides parameters to control ' + 'pagination.

' + ), + members=pagination_config_members, + ) + ] + + botocore_pagination_response_params = [ + DocumentedShape( + name='NextToken', + type_name='string', + documentation=('

A token to resume pagination.

'), + ) + ] + + service_pagination_params = [] + + # Add the normal input token of the method to a list + # of input paramters that we wish to hide since we expose our own. + if isinstance(paginator_config['input_token'], list): + service_pagination_params += paginator_config['input_token'] + else: + service_pagination_params.append(paginator_config['input_token']) + + # Hide the limit key in the documentation. + if paginator_config.get('limit_key', None): + service_pagination_params.append(paginator_config['limit_key']) + + # Hide the output tokens in the documentation. + service_pagination_response_params = [] + if isinstance(paginator_config['output_token'], list): + service_pagination_response_params += paginator_config['output_token'] + else: + service_pagination_response_params.append( + paginator_config['output_token'] + ) + + paginate_description = ( + 'Creates an iterator that will paginate through responses ' + f'from :py:meth:`{get_service_module_name(service_model)}.Client.{xform_name(paginator_name)}`.' + ) + + document_model_driven_method( + section, + 'paginate', + operation_model, + event_emitter=event_emitter, + method_description=paginate_description, + example_prefix='response_iterator = paginator.paginate', + include_input=botocore_pagination_params, + include_output=botocore_pagination_response_params, + exclude_input=service_pagination_params, + exclude_output=service_pagination_response_params, + include_signature=include_signature, + ) diff --git a/.venv/lib/python3.13/site-packages/botocore/docs/params.py b/.venv/lib/python3.13/site-packages/botocore/docs/params.py new file mode 100644 index 0000000000000000000000000000000000000000..7e0f398b09f9552d4053edab2335c7e7c96bb1be --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/docs/params.py @@ -0,0 +1,302 @@ +# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +from botocore.docs.shape import ShapeDocumenter +from botocore.docs.utils import py_type_name + + +class BaseParamsDocumenter(ShapeDocumenter): + def document_params(self, section, shape, include=None, exclude=None): + """Fills out the documentation for a section given a model shape. + + :param section: The section to write the documentation to. + + :param shape: The shape of the operation. + + :type include: Dictionary where keys are parameter names and + values are the shapes of the parameter names. + :param include: The parameter shapes to include in the documentation. + + :type exclude: List of the names of the parameters to exclude. + :param exclude: The names of the parameters to exclude from + documentation. + """ + history = [] + self.traverse_and_document_shape( + section=section, + shape=shape, + history=history, + name=None, + include=include, + exclude=exclude, + ) + + def document_recursive_shape(self, section, shape, **kwargs): + self._add_member_documentation(section, shape, **kwargs) + + def document_shape_default( + self, section, shape, history, include=None, exclude=None, **kwargs + ): + self._add_member_documentation(section, shape, **kwargs) + + def document_shape_type_list( + self, section, shape, history, include=None, exclude=None, **kwargs + ): + self._add_member_documentation(section, shape, **kwargs) + param_shape = shape.member + param_section = section.add_new_section( + param_shape.name, context={'shape': shape.member.name} + ) + self._start_nested_param(param_section) + self.traverse_and_document_shape( + section=param_section, + shape=param_shape, + history=history, + name=None, + ) + section = section.add_new_section('end-list') + self._end_nested_param(section) + + def document_shape_type_map( + self, section, shape, history, include=None, exclude=None, **kwargs + ): + self._add_member_documentation(section, shape, **kwargs) + + key_section = section.add_new_section( + 'key', context={'shape': shape.key.name} + ) + self._start_nested_param(key_section) + self._add_member_documentation(key_section, shape.key) + + param_section = section.add_new_section( + shape.value.name, context={'shape': shape.value.name} + ) + param_section.style.indent() + self._start_nested_param(param_section) + self.traverse_and_document_shape( + section=param_section, + shape=shape.value, + history=history, + name=None, + ) + + end_section = section.add_new_section('end-map') + self._end_nested_param(end_section) + self._end_nested_param(end_section) + + def document_shape_type_structure( + self, + section, + shape, + history, + include=None, + exclude=None, + name=None, + **kwargs, + ): + members = self._add_members_to_shape(shape.members, include) + self._add_member_documentation(section, shape, name=name) + for param in members: + if exclude and param in exclude: + continue + param_shape = members[param] + param_section = section.add_new_section( + param, context={'shape': param_shape.name} + ) + self._start_nested_param(param_section) + self.traverse_and_document_shape( + section=param_section, + shape=param_shape, + history=history, + name=param, + ) + section = section.add_new_section('end-structure') + self._end_nested_param(section) + + def _add_member_documentation(self, section, shape, **kwargs): + pass + + def _add_members_to_shape(self, members, include): + if include: + members = members.copy() + for param in include: + members[param.name] = param + return members + + def _document_non_top_level_param_type(self, type_section, shape): + special_py_type = self._get_special_py_type_name(shape) + py_type = py_type_name(shape.type_name) + + type_format = '(%s) --' + if special_py_type is not None: + # Special type can reference a linked class. + # Italicizing it blows away the link. + type_section.write(type_format % special_py_type) + else: + type_section.style.italics(type_format % py_type) + type_section.write(' ') + + def _start_nested_param(self, section): + section.style.indent() + section.style.new_line() + + def _end_nested_param(self, section): + section.style.dedent() + section.style.new_line() + + +class ResponseParamsDocumenter(BaseParamsDocumenter): + """Generates the description for the response parameters""" + + EVENT_NAME = 'response-params' + + def _add_member_documentation(self, section, shape, name=None, **kwargs): + name_section = section.add_new_section('param-name') + name_section.write('- ') + if name is not None: + name_section.style.bold(f'{name}') + name_section.write(' ') + type_section = section.add_new_section('param-type') + self._document_non_top_level_param_type(type_section, shape) + + documentation_section = section.add_new_section('param-documentation') + if shape.documentation: + documentation_section.style.indent() + if getattr(shape, 'is_tagged_union', False): + tagged_union_docs = section.add_new_section( + 'param-tagged-union-docs' + ) + note = ( + '.. note::' + ' This is a Tagged Union structure. Only one of the ' + ' following top level keys will be set: %s. ' + ' If a client receives an unknown member it will ' + ' set ``SDK_UNKNOWN_MEMBER`` as the top level key, ' + ' which maps to the name or tag of the unknown ' + ' member. The structure of ``SDK_UNKNOWN_MEMBER`` is ' + ' as follows' + ) + tagged_union_members_str = ', '.join( + [f'``{key}``' for key in shape.members.keys()] + ) + unknown_code_example = ( + '\'SDK_UNKNOWN_MEMBER\': {\'name\': \'UnknownMemberName\'}' + ) + tagged_union_docs.write(note % (tagged_union_members_str)) + example = section.add_new_section('param-unknown-example') + example.style.codeblock(unknown_code_example) + documentation_section.include_doc_string(shape.documentation) + section.style.new_paragraph() + + def document_shape_type_event_stream( + self, section, shape, history, **kwargs + ): + self.document_shape_type_structure(section, shape, history, **kwargs) + + +class RequestParamsDocumenter(BaseParamsDocumenter): + """Generates the description for the request parameters""" + + EVENT_NAME = 'request-params' + + def document_shape_type_structure( + self, section, shape, history, include=None, exclude=None, **kwargs + ): + if len(history) > 1: + self._add_member_documentation(section, shape, **kwargs) + section.style.indent() + members = self._add_members_to_shape(shape.members, include) + for i, param in enumerate(members): + if exclude and param in exclude: + continue + param_shape = members[param] + param_section = section.add_new_section( + param, context={'shape': param_shape.name} + ) + param_section.style.new_line() + is_required = param in shape.required_members + self.traverse_and_document_shape( + section=param_section, + shape=param_shape, + history=history, + name=param, + is_required=is_required, + ) + section = section.add_new_section('end-structure') + if len(history) > 1: + section.style.dedent() + section.style.new_line() + + def _add_member_documentation( + self, + section, + shape, + name=None, + is_top_level_param=False, + is_required=False, + **kwargs, + ): + py_type = self._get_special_py_type_name(shape) + if py_type is None: + py_type = py_type_name(shape.type_name) + if is_top_level_param: + type_section = section.add_new_section('param-type') + type_section.write(f':type {name}: {py_type}') + end_type_section = type_section.add_new_section('end-param-type') + end_type_section.style.new_line() + name_section = section.add_new_section('param-name') + name_section.write(f':param {name}: ') + + else: + name_section = section.add_new_section('param-name') + name_section.write('- ') + if name is not None: + name_section.style.bold(f'{name}') + name_section.write(' ') + type_section = section.add_new_section('param-type') + self._document_non_top_level_param_type(type_section, shape) + + if is_required: + is_required_section = section.add_new_section('is-required') + is_required_section.style.indent() + is_required_section.style.bold('[REQUIRED]') + is_required_section.write(' ') + if shape.documentation: + documentation_section = section.add_new_section( + 'param-documentation' + ) + documentation_section.style.indent() + if getattr(shape, 'is_tagged_union', False): + tagged_union_docs = section.add_new_section( + 'param-tagged-union-docs' + ) + note = ( + '.. note::' + ' This is a Tagged Union structure. Only one of the ' + ' following top level keys can be set: %s. ' + ) + tagged_union_members_str = ', '.join( + [f'``{key}``' for key in shape.members.keys()] + ) + tagged_union_docs.write(note % (tagged_union_members_str)) + documentation_section.include_doc_string(shape.documentation) + self._add_special_trait_documentation(documentation_section, shape) + end_param_section = section.add_new_section('end-param') + end_param_section.style.new_paragraph() + + def _add_special_trait_documentation(self, section, shape): + if 'idempotencyToken' in shape.metadata: + self._append_idempotency_documentation(section) + + def _append_idempotency_documentation(self, section): + docstring = 'This field is autopopulated if not provided.' + section.write(docstring) diff --git a/.venv/lib/python3.13/site-packages/botocore/docs/service.py b/.venv/lib/python3.13/site-packages/botocore/docs/service.py new file mode 100644 index 0000000000000000000000000000000000000000..d20a889dc955a71eb3b40e1a4b7eabc549941367 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/docs/service.py @@ -0,0 +1,133 @@ +# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +from botocore.docs.bcdoc.restdoc import DocumentStructure +from botocore.docs.client import ( + ClientContextParamsDocumenter, + ClientDocumenter, + ClientExceptionsDocumenter, +) +from botocore.docs.paginator import PaginatorDocumenter +from botocore.docs.waiter import WaiterDocumenter +from botocore.exceptions import DataNotFoundError + + +class ServiceDocumenter: + def __init__(self, service_name, session, root_docs_path): + self._session = session + self._service_name = service_name + self._root_docs_path = root_docs_path + + self._client = self._session.create_client( + service_name, + region_name='us-east-1', + aws_access_key_id='foo', + aws_secret_access_key='bar', + ) + self._event_emitter = self._client.meta.events + + self.sections = [ + 'title', + 'client-api', + 'client-exceptions', + 'paginator-api', + 'waiter-api', + 'client-context-params', + ] + + def document_service(self): + """Documents an entire service. + + :returns: The reStructured text of the documented service. + """ + doc_structure = DocumentStructure( + self._service_name, section_names=self.sections, target='html' + ) + self.title(doc_structure.get_section('title')) + self.client_api(doc_structure.get_section('client-api')) + self.client_exceptions(doc_structure.get_section('client-exceptions')) + self.paginator_api(doc_structure.get_section('paginator-api')) + self.waiter_api(doc_structure.get_section('waiter-api')) + context_params_section = doc_structure.get_section( + 'client-context-params' + ) + self.client_context_params(context_params_section) + return doc_structure.flush_structure() + + def title(self, section): + section.style.h1(self._client.__class__.__name__) + self._event_emitter.emit( + f"docs.title.{self._service_name}", section=section + ) + + def table_of_contents(self, section): + section.style.table_of_contents(title='Table of Contents', depth=2) + + def client_api(self, section): + examples = None + try: + examples = self.get_examples(self._service_name) + except DataNotFoundError: + pass + + ClientDocumenter( + self._client, self._root_docs_path, examples + ).document_client(section) + + def client_exceptions(self, section): + ClientExceptionsDocumenter( + self._client, self._root_docs_path + ).document_exceptions(section) + + def paginator_api(self, section): + try: + service_paginator_model = self._session.get_paginator_model( + self._service_name + ) + except DataNotFoundError: + return + if service_paginator_model._paginator_config: + paginator_documenter = PaginatorDocumenter( + self._client, service_paginator_model, self._root_docs_path + ) + paginator_documenter.document_paginators(section) + + def waiter_api(self, section): + if self._client.waiter_names: + service_waiter_model = self._session.get_waiter_model( + self._service_name + ) + waiter_documenter = WaiterDocumenter( + self._client, service_waiter_model, self._root_docs_path + ) + waiter_documenter.document_waiters(section) + + def get_examples(self, service_name, api_version=None): + loader = self._session.get_component('data_loader') + examples = loader.load_service_model( + service_name, 'examples-1', api_version + ) + return examples['examples'] + + def client_context_params(self, section): + omitted_params = ClientContextParamsDocumenter.OMITTED_CONTEXT_PARAMS + params_to_omit = omitted_params.get(self._service_name, []) + service_model = self._client.meta.service_model + raw_context_params = service_model.client_context_parameters + context_params = [ + p for p in raw_context_params if p.name not in params_to_omit + ] + if context_params: + context_param_documenter = ClientContextParamsDocumenter( + self._service_name, context_params + ) + context_param_documenter.document_context_params(section) diff --git a/.venv/lib/python3.13/site-packages/botocore/docs/shape.py b/.venv/lib/python3.13/site-packages/botocore/docs/shape.py new file mode 100644 index 0000000000000000000000000000000000000000..640a5d18ef390b9c4456d24233d863974144c947 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/docs/shape.py @@ -0,0 +1,135 @@ +# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. + + +# NOTE: This class should not be instantiated and its +# ``traverse_and_document_shape`` method called directly. It should be +# inherited from a Documenter class with the appropriate methods +# and attributes. +from botocore.utils import is_json_value_header + + +class ShapeDocumenter: + EVENT_NAME = '' + + def __init__( + self, service_name, operation_name, event_emitter, context=None + ): + self._service_name = service_name + self._operation_name = operation_name + self._event_emitter = event_emitter + self._context = context + if context is None: + self._context = {'special_shape_types': {}} + + def traverse_and_document_shape( + self, + section, + shape, + history, + include=None, + exclude=None, + name=None, + is_required=False, + ): + """Traverses and documents a shape + + Will take a self class and call its appropriate methods as a shape + is traversed. + + :param section: The section to document. + + :param history: A list of the names of the shapes that have been + traversed. + + :type include: Dictionary where keys are parameter names and + values are the shapes of the parameter names. + :param include: The parameter shapes to include in the documentation. + + :type exclude: List of the names of the parameters to exclude. + :param exclude: The names of the parameters to exclude from + documentation. + + :param name: The name of the shape. + + :param is_required: If the shape is a required member. + """ + param_type = shape.type_name + if getattr(shape, 'serialization', {}).get('eventstream'): + param_type = 'event_stream' + if shape.name in history: + self.document_recursive_shape(section, shape, name=name) + else: + history.append(shape.name) + is_top_level_param = len(history) == 2 + if hasattr(shape, 'is_document_type') and shape.is_document_type: + param_type = 'document' + getattr( + self, + f"document_shape_type_{param_type}", + self.document_shape_default, + )( + section, + shape, + history=history, + name=name, + include=include, + exclude=exclude, + is_top_level_param=is_top_level_param, + is_required=is_required, + ) + if is_top_level_param: + self._event_emitter.emit( + f"docs.{self.EVENT_NAME}.{self._service_name}.{self._operation_name}.{name}", + section=section, + ) + at_overlying_method_section = len(history) == 1 + if at_overlying_method_section: + self._event_emitter.emit( + f"docs.{self.EVENT_NAME}.{self._service_name}.{self._operation_name}.complete-section", + section=section, + ) + history.pop() + + def _get_special_py_default(self, shape): + special_defaults = { + 'document_type': '{...}|[...]|123|123.4|\'string\'|True|None', + 'jsonvalue_header': '{...}|[...]|123|123.4|\'string\'|True|None', + 'streaming_input_shape': 'b\'bytes\'|file', + 'streaming_output_shape': 'StreamingBody()', + 'eventstream_output_shape': 'EventStream()', + } + return self._get_value_for_special_type(shape, special_defaults) + + def _get_special_py_type_name(self, shape): + special_type_names = { + 'document_type': ':ref:`document`', + 'jsonvalue_header': 'JSON serializable', + 'streaming_input_shape': 'bytes or seekable file-like object', + 'streaming_output_shape': ':class:`.StreamingBody`', + 'eventstream_output_shape': ':class:`.EventStream`', + } + return self._get_value_for_special_type(shape, special_type_names) + + def _get_value_for_special_type(self, shape, special_type_map): + if is_json_value_header(shape): + return special_type_map['jsonvalue_header'] + if hasattr(shape, 'is_document_type') and shape.is_document_type: + return special_type_map['document_type'] + for special_type, marked_shape in self._context[ + 'special_shape_types' + ].items(): + if special_type in special_type_map: + if shape == marked_shape: + return special_type_map[special_type] + return None diff --git a/.venv/lib/python3.13/site-packages/botocore/docs/sharedexample.py b/.venv/lib/python3.13/site-packages/botocore/docs/sharedexample.py new file mode 100644 index 0000000000000000000000000000000000000000..29d3df5fc969daf26bba380b571897195387ad78 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/docs/sharedexample.py @@ -0,0 +1,227 @@ +# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +import numbers +import re + +from botocore.docs.utils import escape_controls +from botocore.utils import parse_timestamp + + +class SharedExampleDocumenter: + def document_shared_example( + self, example, prefix, section, operation_model + ): + """Documents a single shared example based on its definition. + + :param example: The model of the example + + :param prefix: The prefix to use in the method example. + + :param section: The section to write to. + + :param operation_model: The model of the operation used in the example + """ + section.style.new_paragraph() + section.write(example.get('description')) + section.style.new_line() + self.document_input( + section, example, prefix, operation_model.input_shape + ) + self.document_output(section, example, operation_model.output_shape) + + def document_input(self, section, example, prefix, shape): + input_section = section.add_new_section('input') + input_section.style.start_codeblock() + if prefix is not None: + input_section.write(prefix) + params = example.get('input', {}) + comments = example.get('comments') + if comments: + comments = comments.get('input') + param_section = input_section.add_new_section('parameters') + self._document_params(param_section, params, comments, [], shape) + closing_section = input_section.add_new_section('input-close') + closing_section.style.new_line() + closing_section.style.new_line() + closing_section.write('print(response)') + closing_section.style.end_codeblock() + + def document_output(self, section, example, shape): + output_section = section.add_new_section('output') + output_section.style.new_line() + output_section.write('Expected Output:') + output_section.style.new_line() + output_section.style.start_codeblock() + params = example.get('output', {}) + + # There might not be an output, but we will return metadata anyway + params['ResponseMetadata'] = {"...": "..."} + comments = example.get('comments') + if comments: + comments = comments.get('output') + self._document_dict(output_section, params, comments, [], shape, True) + closing_section = output_section.add_new_section('output-close') + closing_section.style.end_codeblock() + + def _document(self, section, value, comments, path, shape): + """ + :param section: The section to add the docs to. + + :param value: The input / output values representing the parameters that + are included in the example. + + :param comments: The dictionary containing all the comments to be + applied to the example. + + :param path: A list describing where the documenter is in traversing the + parameters. This is used to find the equivalent location + in the comments dictionary. + """ + if isinstance(value, dict): + self._document_dict(section, value, comments, path, shape) + elif isinstance(value, list): + self._document_list(section, value, comments, path, shape) + elif isinstance(value, numbers.Number): + self._document_number(section, value, path) + elif shape and shape.type_name == 'timestamp': + self._document_datetime(section, value, path) + else: + self._document_str(section, value, path) + + def _document_dict( + self, section, value, comments, path, shape, top_level=False + ): + dict_section = section.add_new_section('dict-value') + self._start_nested_value(dict_section, '{') + for key, val in value.items(): + path.append(f'.{key}') + item_section = dict_section.add_new_section(key) + item_section.style.new_line() + item_comment = self._get_comment(path, comments) + if item_comment: + item_section.write(item_comment) + item_section.style.new_line() + item_section.write(f"'{key}': ") + + # Shape could be none if there is no output besides ResponseMetadata + item_shape = None + if shape: + if shape.type_name == 'structure': + item_shape = shape.members.get(key) + elif shape.type_name == 'map': + item_shape = shape.value + self._document(item_section, val, comments, path, item_shape) + path.pop() + dict_section_end = dict_section.add_new_section('ending-brace') + self._end_nested_value(dict_section_end, '}') + if not top_level: + dict_section_end.write(',') + + def _document_params(self, section, value, comments, path, shape): + param_section = section.add_new_section('param-values') + self._start_nested_value(param_section, '(') + for key, val in value.items(): + path.append(f'.{key}') + item_section = param_section.add_new_section(key) + item_section.style.new_line() + item_comment = self._get_comment(path, comments) + if item_comment: + item_section.write(item_comment) + item_section.style.new_line() + item_section.write(key + '=') + + # Shape could be none if there are no input parameters + item_shape = None + if shape: + item_shape = shape.members.get(key) + self._document(item_section, val, comments, path, item_shape) + path.pop() + param_section_end = param_section.add_new_section('ending-parenthesis') + self._end_nested_value(param_section_end, ')') + + def _document_list(self, section, value, comments, path, shape): + list_section = section.add_new_section('list-section') + self._start_nested_value(list_section, '[') + item_shape = shape.member + for index, val in enumerate(value): + item_section = list_section.add_new_section(index) + item_section.style.new_line() + path.append(f'[{index}]') + item_comment = self._get_comment(path, comments) + if item_comment: + item_section.write(item_comment) + item_section.style.new_line() + self._document(item_section, val, comments, path, item_shape) + path.pop() + list_section_end = list_section.add_new_section('ending-bracket') + self._end_nested_value(list_section_end, '],') + + def _document_str(self, section, value, path): + # We do the string conversion because this might accept a type that + # we don't specifically address. + safe_value = escape_controls(value) + section.write(f"'{safe_value}',") + + def _document_number(self, section, value, path): + section.write(f"{str(value)},") + + def _document_datetime(self, section, value, path): + datetime_tuple = parse_timestamp(value).timetuple() + datetime_str = str(datetime_tuple[0]) + for i in range(1, len(datetime_tuple)): + datetime_str += ", " + str(datetime_tuple[i]) + section.write(f"datetime({datetime_str}),") + + def _get_comment(self, path, comments): + key = re.sub(r'^\.', '', ''.join(path)) + if comments and key in comments: + return '# ' + comments[key] + else: + return '' + + def _start_nested_value(self, section, start): + section.write(start) + section.style.indent() + section.style.indent() + + def _end_nested_value(self, section, end): + section.style.dedent() + section.style.dedent() + section.style.new_line() + section.write(end) + + +def document_shared_examples( + section, operation_model, example_prefix, shared_examples +): + """Documents the shared examples + + :param section: The section to write to. + + :param operation_model: The model of the operation. + + :param example_prefix: The prefix to use in the method example. + + :param shared_examples: The shared JSON examples from the model. + """ + container_section = section.add_new_section('shared-examples') + container_section.style.new_paragraph() + container_section.style.bold('Examples') + documenter = SharedExampleDocumenter() + for example in shared_examples: + documenter.document_shared_example( + example=example, + section=container_section.add_new_section(example['id']), + prefix=example_prefix, + operation_model=operation_model, + ) diff --git a/.venv/lib/python3.13/site-packages/botocore/docs/translator.py b/.venv/lib/python3.13/site-packages/botocore/docs/translator.py new file mode 100644 index 0000000000000000000000000000000000000000..0b0a308930c6d3d525ceb5cc63abbe43b5c7559e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/docs/translator.py @@ -0,0 +1,62 @@ +# Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +from docutils import nodes +from sphinx.locale import admonitionlabels +from sphinx.writers.html5 import HTML5Translator as SphinxHTML5Translator + + +class BotoHTML5Translator(SphinxHTML5Translator): + """Extension of Sphinx's ``HTML5Translator`` for Botocore documentation.""" + + IGNORE_IMPLICIT_HEADINGS = [ + '[REQUIRED]', + ] + + def visit_admonition(self, node, name=""): + """Uses the h3 tag for admonition titles instead of the p tag.""" + self.body.append( + self.starttag(node, "div", CLASS=("admonition " + name)) + ) + if name: + title = ( + f"

{admonitionlabels[name]}

" + ) + self.body.append(title) + + def is_implicit_heading(self, node): + """Determines if a node is an implicit heading. + + An implicit heading is represented by a paragraph node whose only + child is a strong node with text that isnt in `IGNORE_IMPLICIT_HEADINGS`. + """ + return ( + len(node) == 1 + and isinstance(node[0], nodes.strong) + and len(node[0]) == 1 + and isinstance(node[0][0], nodes.Text) + and node[0][0].astext() not in self.IGNORE_IMPLICIT_HEADINGS + ) + + def visit_paragraph(self, node): + """Visit a paragraph HTML element. + + Replaces implicit headings with an h3 tag and defers to default + behavior for normal paragraph elements. + """ + if self.is_implicit_heading(node): + text = node[0][0] + self.body.append(f'

{text}

\n') + # Do not visit the current nodes children or call its depart method. + raise nodes.SkipNode + else: + super().visit_paragraph(node) diff --git a/.venv/lib/python3.13/site-packages/botocore/docs/utils.py b/.venv/lib/python3.13/site-packages/botocore/docs/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..161e260229155bbc38b4503475240bc4295fdf4c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/docs/utils.py @@ -0,0 +1,225 @@ +# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +import re +from collections import namedtuple + + +def py_type_name(type_name): + """Get the Python type name for a given model type. + + >>> py_type_name('list') + 'list' + >>> py_type_name('structure') + 'dict' + + :rtype: string + """ + return { + 'blob': 'bytes', + 'character': 'string', + 'double': 'float', + 'long': 'integer', + 'map': 'dict', + 'structure': 'dict', + 'timestamp': 'datetime', + }.get(type_name, type_name) + + +def py_default(type_name): + """Get the Python default value for a given model type. + + >>> py_default('string') + '\'string\'' + >>> py_default('list') + '[...]' + >>> py_default('unknown') + '...' + + :rtype: string + """ + return { + 'double': '123.0', + 'long': '123', + 'integer': '123', + 'string': "'string'", + 'blob': "b'bytes'", + 'boolean': 'True|False', + 'list': '[...]', + 'map': '{...}', + 'structure': '{...}', + 'timestamp': 'datetime(2015, 1, 1)', + }.get(type_name, '...') + + +def get_official_service_name(service_model): + """Generate the official name of an AWS Service + + :param service_model: The service model representing the service + """ + official_name = service_model.metadata.get('serviceFullName') + short_name = service_model.metadata.get('serviceAbbreviation', '') + if short_name.startswith('Amazon'): + short_name = short_name[7:] + if short_name.startswith('AWS'): + short_name = short_name[4:] + if short_name and short_name.lower() not in official_name.lower(): + official_name += f' ({short_name})' + return official_name + + +_DocumentedShape = namedtuple( + 'DocumentedShape', + [ + 'name', + 'type_name', + 'documentation', + 'metadata', + 'members', + 'required_members', + ], +) + + +class DocumentedShape(_DocumentedShape): + """Use this class to inject new shapes into a model for documentation""" + + def __new__( + cls, + name, + type_name, + documentation, + metadata=None, + members=None, + required_members=None, + ): + if metadata is None: + metadata = [] + if members is None: + members = [] + if required_members is None: + required_members = [] + return super().__new__( + cls, + name, + type_name, + documentation, + metadata, + members, + required_members, + ) + + +class AutoPopulatedParam: + def __init__(self, name, param_description=None): + self.name = name + self.param_description = param_description + if param_description is None: + self.param_description = ( + 'Please note that this parameter is automatically populated ' + 'if it is not provided. Including this parameter is not ' + 'required\n' + ) + + def document_auto_populated_param(self, event_name, section, **kwargs): + """Documents auto populated parameters + + It will remove any required marks for the parameter, remove the + parameter from the example, and add a snippet about the parameter + being autopopulated in the description. + """ + if event_name.startswith('docs.request-params'): + if self.name in section.available_sections: + section = section.get_section(self.name) + if 'is-required' in section.available_sections: + section.delete_section('is-required') + description_section = section.get_section( + 'param-documentation' + ) + description_section.writeln(self.param_description) + elif event_name.startswith('docs.request-example'): + section = section.get_section('structure-value') + if self.name in section.available_sections: + section.delete_section(self.name) + + +class HideParamFromOperations: + """Hides a single parameter from multiple operations. + + This method will remove a parameter from documentation and from + examples. This method is typically used for things that are + automatically populated because a user would be unable to provide + a value (e.g., a checksum of a serialized XML request body).""" + + def __init__(self, service_name, parameter_name, operation_names): + """ + :type service_name: str + :param service_name: Name of the service to modify. + + :type parameter_name: str + :param parameter_name: Name of the parameter to modify. + + :type operation_names: list + :param operation_names: Operation names to modify. + """ + self._parameter_name = parameter_name + self._params_events = set() + self._example_events = set() + # Build up the sets of relevant event names. + param_template = 'docs.request-params.%s.%s.complete-section' + example_template = 'docs.request-example.%s.%s.complete-section' + for name in operation_names: + self._params_events.add(param_template % (service_name, name)) + self._example_events.add(example_template % (service_name, name)) + + def hide_param(self, event_name, section, **kwargs): + if event_name in self._example_events: + # Modify the structure value for example events. + section = section.get_section('structure-value') + elif event_name not in self._params_events: + return + if self._parameter_name in section.available_sections: + section.delete_section(self._parameter_name) + + +class AppendParamDocumentation: + """Appends documentation to a specific parameter""" + + def __init__(self, parameter_name, doc_string): + self._parameter_name = parameter_name + self._doc_string = doc_string + + def append_documentation(self, event_name, section, **kwargs): + if self._parameter_name in section.available_sections: + section = section.get_section(self._parameter_name) + description_section = section.get_section('param-documentation') + description_section.writeln(self._doc_string) + + +_CONTROLS = { + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', + '\b': '\\b', + '\f': '\\f', +} +# Combines all CONTROLS keys into a big or regular expression +_ESCAPE_CONTROLS_RE = re.compile('|'.join(map(re.escape, _CONTROLS))) + + +# Based on the match get the appropriate replacement from CONTROLS +def _CONTROLS_MATCH_HANDLER(match): + return _CONTROLS[match.group(0)] + + +def escape_controls(value): + return _ESCAPE_CONTROLS_RE.sub(_CONTROLS_MATCH_HANDLER, value) diff --git a/.venv/lib/python3.13/site-packages/botocore/docs/waiter.py b/.venv/lib/python3.13/site-packages/botocore/docs/waiter.py new file mode 100644 index 0000000000000000000000000000000000000000..2918602d2f471be53be47357bd2cf4326fa53dab --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/docs/waiter.py @@ -0,0 +1,180 @@ +# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +import os + +from botocore import xform_name +from botocore.compat import OrderedDict +from botocore.docs.bcdoc.restdoc import DocumentStructure +from botocore.docs.method import document_model_driven_method +from botocore.docs.utils import DocumentedShape +from botocore.utils import get_service_module_name + + +class WaiterDocumenter: + def __init__(self, client, service_waiter_model, root_docs_path): + self._client = client + self._client_class_name = self._client.__class__.__name__ + self._service_name = self._client.meta.service_model.service_name + self._service_waiter_model = service_waiter_model + self._root_docs_path = root_docs_path + self._USER_GUIDE_LINK = ( + 'https://boto3.amazonaws.com/' + 'v1/documentation/api/latest/guide/clients.html#waiters' + ) + + def document_waiters(self, section): + """Documents the various waiters for a service. + + :param section: The section to write to. + """ + section.style.h2('Waiters') + self._add_overview(section) + section.style.new_line() + section.writeln('The available waiters are:') + section.style.toctree() + for waiter_name in self._service_waiter_model.waiter_names: + section.style.tocitem(f'{self._service_name}/waiter/{waiter_name}') + # Create a new DocumentStructure for each waiter and add contents. + waiter_doc_structure = DocumentStructure( + waiter_name, target='html' + ) + self._add_single_waiter(waiter_doc_structure, waiter_name) + # Write waiters in individual/nested files. + # Path: /reference/services//waiter/.rst + waiter_dir_path = os.path.join( + self._root_docs_path, self._service_name, 'waiter' + ) + waiter_doc_structure.write_to_file(waiter_dir_path, waiter_name) + + def _add_single_waiter(self, section, waiter_name): + breadcrumb_section = section.add_new_section('breadcrumb') + breadcrumb_section.style.ref( + self._client_class_name, f'../../{self._service_name}' + ) + breadcrumb_section.write(f' / Waiter / {waiter_name}') + section.add_title_section(waiter_name) + waiter_section = section.add_new_section(waiter_name) + waiter_section.style.start_sphinx_py_class( + class_name=f"{self._client_class_name}.Waiter.{waiter_name}" + ) + + # Add example on how to instantiate waiter. + waiter_section.style.start_codeblock() + waiter_section.style.new_line() + waiter_section.write( + f'waiter = client.get_waiter(\'{xform_name(waiter_name)}\')' + ) + waiter_section.style.end_codeblock() + + # Add information on the wait() method + waiter_section.style.new_line() + document_wait_method( + section=waiter_section, + waiter_name=waiter_name, + event_emitter=self._client.meta.events, + service_model=self._client.meta.service_model, + service_waiter_model=self._service_waiter_model, + ) + + def _add_overview(self, section): + section.style.new_line() + section.write( + 'Waiters are available on a client instance ' + 'via the ``get_waiter`` method. For more detailed instructions ' + 'and examples on the usage or waiters, see the ' + 'waiters ' + ) + section.style.external_link( + title='user guide', + link=self._USER_GUIDE_LINK, + ) + section.write('.') + section.style.new_line() + + +def document_wait_method( + section, + waiter_name, + event_emitter, + service_model, + service_waiter_model, + include_signature=True, +): + """Documents a the wait method of a waiter + + :param section: The section to write to + + :param waiter_name: The name of the waiter + + :param event_emitter: The event emitter to use to emit events + + :param service_model: The service model + + :param service_waiter_model: The waiter model associated to the service + + :param include_signature: Whether or not to include the signature. + It is useful for generating docstrings. + """ + waiter_model = service_waiter_model.get_waiter(waiter_name) + operation_model = service_model.operation_model(waiter_model.operation) + + waiter_config_members = OrderedDict() + + waiter_config_members['Delay'] = DocumentedShape( + name='Delay', + type_name='integer', + documentation=( + '

The amount of time in seconds to wait between ' + f'attempts. Default: {waiter_model.delay}

' + ), + ) + + waiter_config_members['MaxAttempts'] = DocumentedShape( + name='MaxAttempts', + type_name='integer', + documentation=( + '

The maximum number of attempts to be made. ' + f'Default: {waiter_model.max_attempts}

' + ), + ) + + botocore_waiter_params = [ + DocumentedShape( + name='WaiterConfig', + type_name='structure', + documentation=( + '

A dictionary that provides parameters to control ' + 'waiting behavior.

' + ), + members=waiter_config_members, + ) + ] + + wait_description = ( + f'Polls :py:meth:`{get_service_module_name(service_model)}.Client.' + f'{xform_name(waiter_model.operation)}` every {waiter_model.delay} ' + 'seconds until a successful state is reached. An error is ' + f'raised after {waiter_model.max_attempts} failed checks.' + ) + + document_model_driven_method( + section, + 'wait', + operation_model, + event_emitter=event_emitter, + method_description=wait_description, + example_prefix='waiter.wait', + include_input=botocore_waiter_params, + document_output=False, + include_signature=include_signature, + ) diff --git a/.venv/lib/python3.13/site-packages/botocore/retries/__init__.py b/.venv/lib/python3.13/site-packages/botocore/retries/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b377dfcdf246972c05659673308cfa40db37 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/retries/__init__.py @@ -0,0 +1,6 @@ +"""New retry v2 handlers. + +This package obsoletes the botocore/retryhandler.py module and contains +new retry logic. + +""" diff --git a/.venv/lib/python3.13/site-packages/botocore/retries/adaptive.py b/.venv/lib/python3.13/site-packages/botocore/retries/adaptive.py new file mode 100644 index 0000000000000000000000000000000000000000..5e638ddb7b8cc46b2fd12eb37bc9fbc68a744da7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/retries/adaptive.py @@ -0,0 +1,132 @@ +import logging +import math +import threading + +from botocore.retries import bucket, standard, throttling + +logger = logging.getLogger(__name__) + + +def register_retry_handler(client): + clock = bucket.Clock() + rate_adjustor = throttling.CubicCalculator( + starting_max_rate=0, start_time=clock.current_time() + ) + token_bucket = bucket.TokenBucket(max_rate=1, clock=clock) + rate_clocker = RateClocker(clock) + throttling_detector = standard.ThrottlingErrorDetector( + retry_event_adapter=standard.RetryEventAdapter(), + ) + limiter = ClientRateLimiter( + rate_adjustor=rate_adjustor, + rate_clocker=rate_clocker, + token_bucket=token_bucket, + throttling_detector=throttling_detector, + clock=clock, + ) + client.meta.events.register( + 'before-send', + limiter.on_sending_request, + ) + client.meta.events.register( + 'needs-retry', + limiter.on_receiving_response, + ) + return limiter + + +class ClientRateLimiter: + _MAX_RATE_ADJUST_SCALE = 2.0 + + def __init__( + self, + rate_adjustor, + rate_clocker, + token_bucket, + throttling_detector, + clock, + ): + self._rate_adjustor = rate_adjustor + self._rate_clocker = rate_clocker + self._token_bucket = token_bucket + self._throttling_detector = throttling_detector + self._clock = clock + self._enabled = False + self._lock = threading.Lock() + + def on_sending_request(self, request, **kwargs): + if self._enabled: + self._token_bucket.acquire() + + # Hooked up to needs-retry. + def on_receiving_response(self, **kwargs): + measured_rate = self._rate_clocker.record() + timestamp = self._clock.current_time() + with self._lock: + if not self._throttling_detector.is_throttling_error(**kwargs): + new_rate = self._rate_adjustor.success_received(timestamp) + else: + if not self._enabled: + rate_to_use = measured_rate + else: + rate_to_use = min( + measured_rate, self._token_bucket.max_rate + ) + new_rate = self._rate_adjustor.error_received( + rate_to_use, timestamp + ) + logger.debug( + "Throttling response received, new send rate: %s " + "measured rate: %s, token bucket capacity " + "available: %s", + new_rate, + measured_rate, + self._token_bucket.available_capacity, + ) + self._enabled = True + self._token_bucket.max_rate = min( + new_rate, self._MAX_RATE_ADJUST_SCALE * measured_rate + ) + + +class RateClocker: + """Tracks the rate at which a client is sending a request.""" + + _DEFAULT_SMOOTHING = 0.8 + # Update the rate every _TIME_BUCKET_RANGE seconds. + _TIME_BUCKET_RANGE = 0.5 + + def __init__( + self, + clock, + smoothing=_DEFAULT_SMOOTHING, + time_bucket_range=_TIME_BUCKET_RANGE, + ): + self._clock = clock + self._measured_rate = 0 + self._smoothing = smoothing + self._last_bucket = math.floor(self._clock.current_time()) + self._time_bucket_scale = 1 / self._TIME_BUCKET_RANGE + self._count = 0 + self._lock = threading.Lock() + + def record(self, amount=1): + with self._lock: + t = self._clock.current_time() + bucket = ( + math.floor(t * self._time_bucket_scale) + / self._time_bucket_scale + ) + self._count += amount + if bucket > self._last_bucket: + current_rate = self._count / float(bucket - self._last_bucket) + self._measured_rate = (current_rate * self._smoothing) + ( + self._measured_rate * (1 - self._smoothing) + ) + self._count = 0 + self._last_bucket = bucket + return self._measured_rate + + @property + def measured_rate(self): + return self._measured_rate diff --git a/.venv/lib/python3.13/site-packages/botocore/retries/base.py b/.venv/lib/python3.13/site-packages/botocore/retries/base.py new file mode 100644 index 0000000000000000000000000000000000000000..108bfed6901ae6f21e66a3e45d95176a0a18e8ff --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/retries/base.py @@ -0,0 +1,26 @@ +class BaseRetryBackoff: + def delay_amount(self, context): + """Calculate how long we should delay before retrying. + + :type context: RetryContext + + """ + raise NotImplementedError("delay_amount") + + +class BaseRetryableChecker: + """Base class for determining if a retry should happen. + + This base class checks for specific retryable conditions. + A single retryable checker doesn't necessarily indicate a retry + will happen. It's up to the ``RetryPolicy`` to use its + ``BaseRetryableCheckers`` to make the final decision on whether a retry + should happen. + """ + + def is_retryable(self, context): + """Returns True if retryable, False if not. + + :type context: RetryContext + """ + raise NotImplementedError("is_retryable") diff --git a/.venv/lib/python3.13/site-packages/botocore/retries/bucket.py b/.venv/lib/python3.13/site-packages/botocore/retries/bucket.py new file mode 100644 index 0000000000000000000000000000000000000000..09d33c77d0afb5ccf8a76af8f5316bed9d292c6b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/retries/bucket.py @@ -0,0 +1,115 @@ +"""This module implements token buckets used for client side throttling.""" + +import threading +import time + +from botocore.exceptions import CapacityNotAvailableError + + +class Clock: + def __init__(self): + pass + + def sleep(self, amount): + time.sleep(amount) + + def current_time(self): + return time.time() + + +class TokenBucket: + _MIN_RATE = 0.5 + + def __init__(self, max_rate, clock, min_rate=_MIN_RATE): + self._fill_rate = None + self._max_capacity = None + self._current_capacity = 0 + self._clock = clock + self._last_timestamp = None + self._min_rate = min_rate + self._lock = threading.Lock() + self._new_fill_rate_condition = threading.Condition(self._lock) + self.max_rate = max_rate + + @property + def max_rate(self): + return self._fill_rate + + @max_rate.setter + def max_rate(self, value): + with self._new_fill_rate_condition: + # Before we can change the rate we need to fill any pending + # tokens we might have based on the current rate. If we don't + # do this it means everything since the last recorded timestamp + # will accumulate at the rate we're about to set which isn't + # correct. + self._refill() + self._fill_rate = max(value, self._min_rate) + if value >= 1: + self._max_capacity = value + else: + self._max_capacity = 1 + # If we're scaling down, we also can't have a capacity that's + # more than our max_capacity. + self._current_capacity = min( + self._current_capacity, self._max_capacity + ) + self._new_fill_rate_condition.notify() + + @property + def max_capacity(self): + return self._max_capacity + + @property + def available_capacity(self): + return self._current_capacity + + def acquire(self, amount=1, block=True): + """Acquire token or return amount of time until next token available. + + If block is True, then this method will block until there's sufficient + capacity to acquire the desired amount. + + If block is False, then this method will return True is capacity + was successfully acquired, False otherwise. + + """ + with self._new_fill_rate_condition: + return self._acquire(amount=amount, block=block) + + def _acquire(self, amount, block): + self._refill() + if amount <= self._current_capacity: + self._current_capacity -= amount + return True + else: + if not block: + raise CapacityNotAvailableError() + # Not enough capacity. + sleep_amount = self._sleep_amount(amount) + while sleep_amount > 0: + # Until python3.2, wait() always returned None so we can't + # tell if a timeout occurred waiting on the cond var. + # Because of this we'll unconditionally call _refill(). + # The downside to this is that we were waken up via + # a notify(), we're calling unnecessarily calling _refill() an + # extra time. + self._new_fill_rate_condition.wait(sleep_amount) + self._refill() + sleep_amount = self._sleep_amount(amount) + self._current_capacity -= amount + return True + + def _sleep_amount(self, amount): + return (amount - self._current_capacity) / self._fill_rate + + def _refill(self): + timestamp = self._clock.current_time() + if self._last_timestamp is None: + self._last_timestamp = timestamp + return + current_capacity = self._current_capacity + fill_amount = (timestamp - self._last_timestamp) * self._fill_rate + new_capacity = min(self._max_capacity, current_capacity + fill_amount) + self._current_capacity = new_capacity + self._last_timestamp = timestamp diff --git a/.venv/lib/python3.13/site-packages/botocore/retries/quota.py b/.venv/lib/python3.13/site-packages/botocore/retries/quota.py new file mode 100644 index 0000000000000000000000000000000000000000..f03942912a16aafcd964f0f2c89c7732035ab193 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/retries/quota.py @@ -0,0 +1,54 @@ +"""Retry quota implementation.""" + +import threading + + +class RetryQuota: + INITIAL_CAPACITY = 500 + + def __init__(self, initial_capacity=INITIAL_CAPACITY, lock=None): + self._max_capacity = initial_capacity + self._available_capacity = initial_capacity + if lock is None: + lock = threading.Lock() + self._lock = lock + + def acquire(self, capacity_amount): + """Attempt to aquire a certain amount of capacity. + + If there's not sufficient amount of capacity available, ``False`` + is returned. Otherwise, ``True`` is returned, which indicates that + capacity was successfully allocated. + + """ + # The acquire() is only called when we encounter a retryable + # response so we aren't worried about locking the entire method. + with self._lock: + if capacity_amount > self._available_capacity: + return False + self._available_capacity -= capacity_amount + return True + + def release(self, capacity_amount): + """Release capacity back to the retry quota. + + The capacity being released will be truncated if necessary + to ensure the max capacity is never exceeded. + + """ + # Implementation note: The release() method is called as part + # of the "after-call" event, which means it gets invoked for + # every API call. In the common case where the request is + # successful and we're at full capacity, we can avoid locking. + # We can't exceed max capacity so there's no work we have to do. + if self._max_capacity == self._available_capacity: + return + with self._lock: + amount = min( + self._max_capacity - self._available_capacity, capacity_amount + ) + self._available_capacity += amount + + @property + def available_capacity(self): + return self._available_capacity diff --git a/.venv/lib/python3.13/site-packages/botocore/retries/special.py b/.venv/lib/python3.13/site-packages/botocore/retries/special.py new file mode 100644 index 0000000000000000000000000000000000000000..9b782601da6040cbbb19a5c8af4fd4de939cc0db --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/retries/special.py @@ -0,0 +1,51 @@ +"""Special cased retries. + +These are additional retry cases we still have to handle from the legacy +retry handler. They don't make sense as part of the standard mode retry +module. Ideally we should be able to remove this module. + +""" + +import logging +from binascii import crc32 + +from botocore.retries.base import BaseRetryableChecker + +logger = logging.getLogger(__name__) + + +# TODO: This is an ideal candidate for the retryable trait once that's +# available. +class RetryIDPCommunicationError(BaseRetryableChecker): + _SERVICE_NAME = 'sts' + + def is_retryable(self, context): + service_name = context.operation_model.service_model.service_name + if service_name != self._SERVICE_NAME: + return False + error_code = context.get_error_code() + return error_code == 'IDPCommunicationError' + + +class RetryDDBChecksumError(BaseRetryableChecker): + _CHECKSUM_HEADER = 'x-amz-crc32' + _SERVICE_NAME = 'dynamodb' + + def is_retryable(self, context): + service_name = context.operation_model.service_model.service_name + if service_name != self._SERVICE_NAME: + return False + if context.http_response is None: + return False + checksum = context.http_response.headers.get(self._CHECKSUM_HEADER) + if checksum is None: + return False + actual_crc32 = crc32(context.http_response.content) & 0xFFFFFFFF + if actual_crc32 != int(checksum): + logger.debug( + "DynamoDB crc32 checksum does not match, " + "expected: %s, actual: %s", + checksum, + actual_crc32, + ) + return True diff --git a/.venv/lib/python3.13/site-packages/botocore/retries/standard.py b/.venv/lib/python3.13/site-packages/botocore/retries/standard.py new file mode 100644 index 0000000000000000000000000000000000000000..8801530b000df3d371fed6c15b00a067c9045995 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/retries/standard.py @@ -0,0 +1,532 @@ +"""Standard retry behavior. + +This contains the default standard retry behavior. +It provides consistent behavior with other AWS SDKs. + +The key base classes uses for retries: + + * ``BaseRetryableChecker`` - Use to check a specific condition that + indicates a retry should happen. This can include things like + max attempts, HTTP status code checks, error code checks etc. + * ``RetryBackoff`` - Use to determine how long we should backoff until + we retry a request. This is the class that will implement delay such + as exponential backoff. + * ``RetryPolicy`` - Main class that determines if a retry should + happen. It can combine data from a various BaseRetryableCheckers + to make a final call as to whether or not a retry should happen. + It then uses a ``BaseRetryBackoff`` to determine how long to delay. + * ``RetryHandler`` - The bridge between botocore's event system + used by endpoint.py to manage retries and the interfaces defined + in this module. + +This allows us to define an API that has minimal coupling to the event +based API used by botocore. + +""" + +import logging +import random + +from botocore.exceptions import ( + ConnectionError, + ConnectTimeoutError, + HTTPClientError, + ReadTimeoutError, +) +from botocore.retries import quota, special +from botocore.retries.base import BaseRetryableChecker, BaseRetryBackoff + +DEFAULT_MAX_ATTEMPTS = 3 +logger = logging.getLogger(__name__) + + +def register_retry_handler(client, max_attempts=DEFAULT_MAX_ATTEMPTS): + retry_quota = RetryQuotaChecker(quota.RetryQuota()) + + service_id = client.meta.service_model.service_id + service_event_name = service_id.hyphenize() + client.meta.events.register( + f'after-call.{service_event_name}', retry_quota.release_retry_quota + ) + + handler = RetryHandler( + retry_policy=RetryPolicy( + retry_checker=StandardRetryConditions(max_attempts=max_attempts), + retry_backoff=ExponentialBackoff(), + ), + retry_event_adapter=RetryEventAdapter(), + retry_quota=retry_quota, + ) + + unique_id = f'retry-config-{service_event_name}' + client.meta.events.register( + f'needs-retry.{service_event_name}', + handler.needs_retry, + unique_id=unique_id, + ) + return handler + + +class RetryHandler: + """Bridge between botocore's event system and this module. + + This class is intended to be hooked to botocore's event system + as an event handler. + """ + + def __init__(self, retry_policy, retry_event_adapter, retry_quota): + self._retry_policy = retry_policy + self._retry_event_adapter = retry_event_adapter + self._retry_quota = retry_quota + + def needs_retry(self, **kwargs): + """Connect as a handler to the needs-retry event.""" + retry_delay = None + context = self._retry_event_adapter.create_retry_context(**kwargs) + if self._retry_policy.should_retry(context): + # Before we can retry we need to ensure we have sufficient + # capacity in our retry quota. + if self._retry_quota.acquire_retry_quota(context): + retry_delay = self._retry_policy.compute_retry_delay(context) + logger.debug( + "Retry needed, retrying request after delay of: %s", + retry_delay, + ) + else: + logger.debug( + "Retry needed but retry quota reached, " + "not retrying request." + ) + else: + logger.debug("Not retrying request.") + self._retry_event_adapter.adapt_retry_response_from_context(context) + return retry_delay + + +class RetryEventAdapter: + """Adapter to existing retry interface used in the endpoints layer. + + This existing interface for determining if a retry needs to happen + is event based and used in ``botocore.endpoint``. The interface has + grown organically over the years and could use some cleanup. This + adapter converts that interface into the interface used by the + new retry strategies. + + """ + + def create_retry_context(self, **kwargs): + """Create context based on needs-retry kwargs.""" + response = kwargs['response'] + if response is None: + # If response is None it means that an exception was raised + # because we never received a response from the service. This + # could be something like a ConnectionError we get from our + # http layer. + http_response = None + parsed_response = None + else: + http_response, parsed_response = response + # This provides isolation between the kwargs emitted in the + # needs-retry event, and what this module uses to check for + # retries. + context = RetryContext( + attempt_number=kwargs['attempts'], + operation_model=kwargs['operation'], + http_response=http_response, + parsed_response=parsed_response, + caught_exception=kwargs['caught_exception'], + request_context=kwargs['request_dict']['context'], + ) + return context + + def adapt_retry_response_from_context(self, context): + """Modify response back to user back from context.""" + # This will mutate attributes that are returned back to the end + # user. We do it this way so that all the various retry classes + # don't mutate any input parameters from the needs-retry event. + metadata = context.get_retry_metadata() + if context.parsed_response is not None: + context.parsed_response.setdefault('ResponseMetadata', {}).update( + metadata + ) + + +# Implementation note: this is meant to encapsulate all the misc stuff +# that gets sent in the needs-retry event. This is mapped so that params +# are more clear and explicit. +class RetryContext: + """Normalize a response that we use to check if a retry should occur. + + This class smoothes over the different types of responses we may get + from a service including: + + * A modeled error response from the service that contains a service + code and error message. + * A raw HTTP response that doesn't contain service protocol specific + error keys. + * An exception received while attempting to retrieve a response. + This could be a ConnectionError we receive from our HTTP layer which + could represent that we weren't able to receive a response from + the service. + + This class guarantees that at least one of the above attributes will be + non None. + + This class is meant to provide a read-only view into the properties + associated with a possible retryable response. None of the properties + are meant to be modified directly. + + """ + + def __init__( + self, + attempt_number, + operation_model=None, + parsed_response=None, + http_response=None, + caught_exception=None, + request_context=None, + ): + # 1-based attempt number. + self.attempt_number = attempt_number + self.operation_model = operation_model + # This is the parsed response dictionary we get from parsing + # the HTTP response from the service. + self.parsed_response = parsed_response + # This is an instance of botocore.awsrequest.AWSResponse. + self.http_response = http_response + # This is a subclass of Exception that will be non None if + # an exception was raised when retrying to retrieve a response. + self.caught_exception = caught_exception + # This is the request context dictionary that's added to the + # request dict. This is used to story any additional state + # about the request. We use this for storing retry quota + # capacity. + if request_context is None: + request_context = {} + self.request_context = request_context + self._retry_metadata = {} + + # These are misc helper methods to avoid duplication in the various + # checkers. + def get_error_code(self): + """Check if there was a parsed response with an error code. + + If we could not find any error codes, ``None`` is returned. + + """ + if self.parsed_response is None: + return + error = self.parsed_response.get('Error', {}) + if not isinstance(error, dict): + return + return error.get('Code') + + def add_retry_metadata(self, **kwargs): + """Add key/value pairs to the retry metadata. + + This allows any objects during the retry process to add + metadata about any checks/validations that happened. + + This gets added to the response metadata in the retry handler. + + """ + self._retry_metadata.update(**kwargs) + + def get_retry_metadata(self): + return self._retry_metadata.copy() + + +class RetryPolicy: + def __init__(self, retry_checker, retry_backoff): + self._retry_checker = retry_checker + self._retry_backoff = retry_backoff + + def should_retry(self, context): + return self._retry_checker.is_retryable(context) + + def compute_retry_delay(self, context): + return self._retry_backoff.delay_amount(context) + + +class ExponentialBackoff(BaseRetryBackoff): + _BASE = 2 + _MAX_BACKOFF = 20 + + def __init__(self, max_backoff=20, random=random.random): + self._base = self._BASE + self._max_backoff = max_backoff + self._random = random + + def delay_amount(self, context): + """Calculates delay based on exponential backoff. + + This class implements truncated binary exponential backoff + with jitter:: + + t_i = rand(0, 1) * min(2 ** attempt, MAX_BACKOFF) + + where ``i`` is the request attempt (0 based). + + """ + # The context.attempt_number is a 1-based value, but we have + # to calculate the delay based on i based a 0-based value. We + # want the first delay to just be ``rand(0, 1)``. + return self._random() * min( + (self._base ** (context.attempt_number - 1)), + self._max_backoff, + ) + + +class MaxAttemptsChecker(BaseRetryableChecker): + def __init__(self, max_attempts): + self._max_attempts = max_attempts + + def is_retryable(self, context): + under_max_attempts = context.attempt_number < self._max_attempts + retries_context = context.request_context.get('retries') + if retries_context: + retries_context['max'] = max( + retries_context.get('max', 0), self._max_attempts + ) + if not under_max_attempts: + logger.debug("Max attempts of %s reached.", self._max_attempts) + context.add_retry_metadata(MaxAttemptsReached=True) + return under_max_attempts + + +class TransientRetryableChecker(BaseRetryableChecker): + _TRANSIENT_ERROR_CODES = [ + 'RequestTimeout', + 'RequestTimeoutException', + 'PriorRequestNotComplete', + ] + _TRANSIENT_STATUS_CODES = [500, 502, 503, 504] + _TRANSIENT_EXCEPTION_CLS = ( + ConnectionError, + HTTPClientError, + ) + + def __init__( + self, + transient_error_codes=None, + transient_status_codes=None, + transient_exception_cls=None, + ): + if transient_error_codes is None: + transient_error_codes = self._TRANSIENT_ERROR_CODES[:] + if transient_status_codes is None: + transient_status_codes = self._TRANSIENT_STATUS_CODES[:] + if transient_exception_cls is None: + transient_exception_cls = self._TRANSIENT_EXCEPTION_CLS + self._transient_error_codes = transient_error_codes + self._transient_status_codes = transient_status_codes + self._transient_exception_cls = transient_exception_cls + + def is_retryable(self, context): + if context.get_error_code() in self._transient_error_codes: + return True + if context.http_response is not None: + if ( + context.http_response.status_code + in self._transient_status_codes + ): + return True + if context.caught_exception is not None: + return isinstance( + context.caught_exception, self._transient_exception_cls + ) + return False + + +class ThrottledRetryableChecker(BaseRetryableChecker): + # This is the union of all error codes we've seen that represent + # a throttled error. + _THROTTLED_ERROR_CODES = [ + 'Throttling', + 'ThrottlingException', + 'ThrottledException', + 'RequestThrottledException', + 'TooManyRequestsException', + 'ProvisionedThroughputExceededException', + 'TransactionInProgressException', + 'RequestLimitExceeded', + 'BandwidthLimitExceeded', + 'LimitExceededException', + 'RequestThrottled', + 'SlowDown', + 'PriorRequestNotComplete', + 'EC2ThrottledException', + ] + + def __init__(self, throttled_error_codes=None): + if throttled_error_codes is None: + throttled_error_codes = self._THROTTLED_ERROR_CODES[:] + self._throttled_error_codes = throttled_error_codes + + def is_retryable(self, context): + # Only the error code from a parsed service response is used + # to determine if the response is a throttled response. + return context.get_error_code() in self._throttled_error_codes + + +class ModeledRetryableChecker(BaseRetryableChecker): + """Check if an error has been modeled as retryable.""" + + def __init__(self): + self._error_detector = ModeledRetryErrorDetector() + + def is_retryable(self, context): + error_code = context.get_error_code() + if error_code is None: + return False + return self._error_detector.detect_error_type(context) is not None + + +class ModeledRetryErrorDetector: + """Checks whether or not an error is a modeled retryable error.""" + + # There are return values from the detect_error_type() method. + TRANSIENT_ERROR = 'TRANSIENT_ERROR' + THROTTLING_ERROR = 'THROTTLING_ERROR' + # This class is lower level than ModeledRetryableChecker, which + # implements BaseRetryableChecker. This object allows you to distinguish + # between the various types of retryable errors. + + def detect_error_type(self, context): + """Detect the error type associated with an error code and model. + + This will either return: + + * ``self.TRANSIENT_ERROR`` - If the error is a transient error + * ``self.THROTTLING_ERROR`` - If the error is a throttling error + * ``None`` - If the error is neither type of error. + + """ + error_code = context.get_error_code() + op_model = context.operation_model + if op_model is None or not op_model.error_shapes: + return + for shape in op_model.error_shapes: + if shape.metadata.get('retryable') is not None: + # Check if this error code matches the shape. This can + # be either by name or by a modeled error code. + error_code_to_check = ( + shape.metadata.get('error', {}).get('code') or shape.name + ) + if error_code == error_code_to_check: + if shape.metadata['retryable'].get('throttling'): + return self.THROTTLING_ERROR + return self.TRANSIENT_ERROR + + +class ThrottlingErrorDetector: + def __init__(self, retry_event_adapter): + self._modeled_error_detector = ModeledRetryErrorDetector() + self._fixed_error_code_detector = ThrottledRetryableChecker() + self._retry_event_adapter = retry_event_adapter + + # This expects the kwargs from needs-retry to be passed through. + def is_throttling_error(self, **kwargs): + context = self._retry_event_adapter.create_retry_context(**kwargs) + if self._fixed_error_code_detector.is_retryable(context): + return True + error_type = self._modeled_error_detector.detect_error_type(context) + return error_type == self._modeled_error_detector.THROTTLING_ERROR + + +class StandardRetryConditions(BaseRetryableChecker): + """Concrete class that implements the standard retry policy checks. + + Specifically: + + not max_attempts and (transient or throttled or modeled_retry) + + """ + + def __init__(self, max_attempts=DEFAULT_MAX_ATTEMPTS): + # Note: This class is for convenience so you can have the + # standard retry condition in a single class. + self._max_attempts_checker = MaxAttemptsChecker(max_attempts) + self._additional_checkers = OrRetryChecker( + [ + TransientRetryableChecker(), + ThrottledRetryableChecker(), + ModeledRetryableChecker(), + OrRetryChecker( + [ + special.RetryIDPCommunicationError(), + special.RetryDDBChecksumError(), + ] + ), + ] + ) + + def is_retryable(self, context): + return self._max_attempts_checker.is_retryable( + context + ) and self._additional_checkers.is_retryable(context) + + +class OrRetryChecker(BaseRetryableChecker): + def __init__(self, checkers): + self._checkers = checkers + + def is_retryable(self, context): + return any(checker.is_retryable(context) for checker in self._checkers) + + +class RetryQuotaChecker: + _RETRY_COST = 5 + _NO_RETRY_INCREMENT = 1 + _TIMEOUT_RETRY_REQUEST = 10 + _TIMEOUT_EXCEPTIONS = (ConnectTimeoutError, ReadTimeoutError) + + # Implementation note: We're not making this a BaseRetryableChecker + # because this isn't just a check if we can retry. This also changes + # state so we have to careful when/how we call this. Making it + # a BaseRetryableChecker implies you can call .is_retryable(context) + # as many times as you want and not affect anything. + + def __init__(self, quota): + self._quota = quota + # This tracks the last amount + self._last_amount_acquired = None + + def acquire_retry_quota(self, context): + if self._is_timeout_error(context): + capacity_amount = self._TIMEOUT_RETRY_REQUEST + else: + capacity_amount = self._RETRY_COST + success = self._quota.acquire(capacity_amount) + if success: + # We add the capacity amount to the request context so we know + # how much to release later. The capacity amount can vary based + # on the error. + context.request_context['retry_quota_capacity'] = capacity_amount + return True + context.add_retry_metadata(RetryQuotaReached=True) + return False + + def _is_timeout_error(self, context): + return isinstance(context.caught_exception, self._TIMEOUT_EXCEPTIONS) + + # This is intended to be hooked up to ``after-call``. + def release_retry_quota(self, context, http_response, **kwargs): + # There's three possible options. + # 1. The HTTP response did not have a 2xx response. In that case we + # give no quota back. + # 2. The HTTP request was successful and was never retried. In + # that case we give _NO_RETRY_INCREMENT back. + # 3. The API call had retries, and we eventually receive an HTTP + # response with a 2xx status code. In that case we give back + # whatever quota was associated with the last acquisition. + if http_response is None: + return + status_code = http_response.status_code + if 200 <= status_code < 300: + if 'retry_quota_capacity' not in context: + self._quota.release(self._NO_RETRY_INCREMENT) + else: + capacity_amount = context['retry_quota_capacity'] + self._quota.release(capacity_amount) diff --git a/.venv/lib/python3.13/site-packages/botocore/retries/throttling.py b/.venv/lib/python3.13/site-packages/botocore/retries/throttling.py new file mode 100644 index 0000000000000000000000000000000000000000..34ab417299767553718f9070dcf8fecad4dbe551 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/retries/throttling.py @@ -0,0 +1,55 @@ +from collections import namedtuple + +CubicParams = namedtuple('CubicParams', ['w_max', 'k', 'last_fail']) + + +class CubicCalculator: + _SCALE_CONSTANT = 0.4 + _BETA = 0.7 + + def __init__( + self, + starting_max_rate, + start_time, + scale_constant=_SCALE_CONSTANT, + beta=_BETA, + ): + self._w_max = starting_max_rate + self._scale_constant = scale_constant + self._beta = beta + self._k = self._calculate_zero_point() + self._last_fail = start_time + + def _calculate_zero_point(self): + scaled_value = (self._w_max * (1 - self._beta)) / self._scale_constant + k = scaled_value ** (1 / 3.0) + return k + + def success_received(self, timestamp): + dt = timestamp - self._last_fail + new_rate = self._scale_constant * (dt - self._k) ** 3 + self._w_max + return new_rate + + def error_received(self, current_rate, timestamp): + # Consider not having this be the current measured rate. + + # We have a new max rate, which is the current rate we were sending + # at when we received an error response. + self._w_max = current_rate + self._k = self._calculate_zero_point() + self._last_fail = timestamp + return current_rate * self._beta + + def get_params_snapshot(self): + """Return a read-only object of the current cubic parameters. + + These parameters are intended to be used for debug/troubleshooting + purposes. These object is a read-only snapshot and cannot be used + to modify the behavior of the CUBIC calculations. + + New parameters may be added to this object in the future. + + """ + return CubicParams( + w_max=self._w_max, k=self._k, last_fail=self._last_fail + ) diff --git a/.venv/lib/python3.13/site-packages/botocore/vendored/__init__.py b/.venv/lib/python3.13/site-packages/botocore/vendored/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/lib/python3.13/site-packages/botocore/vendored/__pycache__/__init__.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/vendored/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f809fe18cf1c631422346e4834128b19929e6580 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/vendored/__pycache__/__init__.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/vendored/__pycache__/six.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/vendored/__pycache__/six.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b24b3c3dbb695048a3000fc914472ce0cbbfce8a Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/vendored/__pycache__/six.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/vendored/requests/__init__.py b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0ada6e0f4ce9dfcd0e902357606e48ba154e1862 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/__init__.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- + +# __ +# /__) _ _ _ _ _/ _ +# / ( (- (/ (/ (- _) / _) +# / +from .exceptions import ( + RequestException, Timeout, URLRequired, + TooManyRedirects, HTTPError, ConnectionError +) diff --git a/.venv/lib/python3.13/site-packages/botocore/vendored/requests/__pycache__/__init__.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f39642dce6d96c15c500843b3be8e8cc6ef8841 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/__pycache__/__init__.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/vendored/requests/__pycache__/exceptions.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/__pycache__/exceptions.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b442c863ba1987c101c4c292982d2c85b9ba1215 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/__pycache__/exceptions.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/vendored/requests/exceptions.py b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..89135a802eb1a87e15aa5d3e8a94ed0fce50273b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/exceptions.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- + +""" +requests.exceptions +~~~~~~~~~~~~~~~~~~~ + +This module contains the set of Requests' exceptions. + +""" +from .packages.urllib3.exceptions import HTTPError as BaseHTTPError + + +class RequestException(IOError): + """There was an ambiguous exception that occurred while handling your + request.""" + + def __init__(self, *args, **kwargs): + """ + Initialize RequestException with `request` and `response` objects. + """ + response = kwargs.pop('response', None) + self.response = response + self.request = kwargs.pop('request', None) + if (response is not None and not self.request and + hasattr(response, 'request')): + self.request = self.response.request + super(RequestException, self).__init__(*args, **kwargs) + + +class HTTPError(RequestException): + """An HTTP error occurred.""" + + +class ConnectionError(RequestException): + """A Connection error occurred.""" + + +class ProxyError(ConnectionError): + """A proxy error occurred.""" + + +class SSLError(ConnectionError): + """An SSL error occurred.""" + + +class Timeout(RequestException): + """The request timed out. + + Catching this error will catch both + :exc:`~requests.exceptions.ConnectTimeout` and + :exc:`~requests.exceptions.ReadTimeout` errors. + """ + + +class ConnectTimeout(ConnectionError, Timeout): + """The request timed out while trying to connect to the remote server. + + Requests that produced this error are safe to retry. + """ + + +class ReadTimeout(Timeout): + """The server did not send any data in the allotted amount of time.""" + + +class URLRequired(RequestException): + """A valid URL is required to make a request.""" + + +class TooManyRedirects(RequestException): + """Too many redirects.""" + + +class MissingSchema(RequestException, ValueError): + """The URL schema (e.g. http or https) is missing.""" + + +class InvalidSchema(RequestException, ValueError): + """See defaults.py for valid schemas.""" + + +class InvalidURL(RequestException, ValueError): + """ The URL provided was somehow invalid. """ + + +class ChunkedEncodingError(RequestException): + """The server declared chunked encoding but sent an invalid chunk.""" + + +class ContentDecodingError(RequestException, BaseHTTPError): + """Failed to decode response content""" + + +class StreamConsumedError(RequestException, TypeError): + """The content for this response was already consumed""" + + +class RetryError(RequestException): + """Custom retries logic failed""" diff --git a/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/__init__.py b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d62c4b7111b3d547f853379e4840b44cb96c6000 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/__init__.py @@ -0,0 +1,3 @@ +from __future__ import absolute_import + +from . import urllib3 diff --git a/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/__pycache__/__init__.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0aeea08ccba4afd96471d2ff96dc498b5d6fe9e1 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/__pycache__/__init__.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/urllib3/__init__.py b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/urllib3/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..88697016b41f8da46f726a38ac8ac914ebc65bbc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/urllib3/__init__.py @@ -0,0 +1,10 @@ +""" +urllib3 - Thread-safe connection pooling and re-using. +""" + +__author__ = 'Andrey Petrov (andrey.petrov@shazow.net)' +__license__ = 'MIT' +__version__ = '' + + +from . import exceptions diff --git a/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/urllib3/__pycache__/__init__.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/urllib3/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c12bcef4893076c7d47576b3a7f5b637fc88e13a Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/urllib3/__pycache__/__init__.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/urllib3/__pycache__/exceptions.cpython-313.pyc b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/urllib3/__pycache__/exceptions.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e326ee6952f7d9aa01ba2015eaf3e2da992d3f75 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/urllib3/__pycache__/exceptions.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/urllib3/exceptions.py b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/urllib3/exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..31bda1c07ed3d1335635ec856611bd1dde66b7af --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/vendored/requests/packages/urllib3/exceptions.py @@ -0,0 +1,169 @@ + +## Base Exceptions + +class HTTPError(Exception): + "Base exception used by this module." + pass + +class HTTPWarning(Warning): + "Base warning used by this module." + pass + + + +class PoolError(HTTPError): + "Base exception for errors caused within a pool." + def __init__(self, pool, message): + self.pool = pool + HTTPError.__init__(self, "%s: %s" % (pool, message)) + + def __reduce__(self): + # For pickling purposes. + return self.__class__, (None, None) + + +class RequestError(PoolError): + "Base exception for PoolErrors that have associated URLs." + def __init__(self, pool, url, message): + self.url = url + PoolError.__init__(self, pool, message) + + def __reduce__(self): + # For pickling purposes. + return self.__class__, (None, self.url, None) + + +class SSLError(HTTPError): + "Raised when SSL certificate fails in an HTTPS connection." + pass + + +class ProxyError(HTTPError): + "Raised when the connection to a proxy fails." + pass + + +class DecodeError(HTTPError): + "Raised when automatic decoding based on Content-Type fails." + pass + + +class ProtocolError(HTTPError): + "Raised when something unexpected happens mid-request/response." + pass + + +#: Renamed to ProtocolError but aliased for backwards compatibility. +ConnectionError = ProtocolError + + +## Leaf Exceptions + +class MaxRetryError(RequestError): + """Raised when the maximum number of retries is exceeded. + + :param pool: The connection pool + :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool` + :param string url: The requested Url + :param exceptions.Exception reason: The underlying error + + """ + + def __init__(self, pool, url, reason=None): + self.reason = reason + + message = "Max retries exceeded with url: %s (Caused by %r)" % ( + url, reason) + + RequestError.__init__(self, pool, url, message) + + +class HostChangedError(RequestError): + "Raised when an existing pool gets a request for a foreign host." + + def __init__(self, pool, url, retries=3): + message = "Tried to open a foreign host with url: %s" % url + RequestError.__init__(self, pool, url, message) + self.retries = retries + + +class TimeoutStateError(HTTPError): + """ Raised when passing an invalid state to a timeout """ + pass + + +class TimeoutError(HTTPError): + """ Raised when a socket timeout error occurs. + + Catching this error will catch both :exc:`ReadTimeoutErrors + ` and :exc:`ConnectTimeoutErrors `. + """ + pass + + +class ReadTimeoutError(TimeoutError, RequestError): + "Raised when a socket timeout occurs while receiving data from a server" + pass + + +# This timeout error does not have a URL attached and needs to inherit from the +# base HTTPError +class ConnectTimeoutError(TimeoutError): + "Raised when a socket timeout occurs while connecting to a server" + pass + + +class EmptyPoolError(PoolError): + "Raised when a pool runs out of connections and no more are allowed." + pass + + +class ClosedPoolError(PoolError): + "Raised when a request enters a pool after the pool has been closed." + pass + + +class LocationValueError(ValueError, HTTPError): + "Raised when there is something wrong with a given URL input." + pass + + +class LocationParseError(LocationValueError): + "Raised when get_host or similar fails to parse the URL input." + + def __init__(self, location): + message = "Failed to parse: %s" % location + HTTPError.__init__(self, message) + + self.location = location + + +class ResponseError(HTTPError): + "Used as a container for an error reason supplied in a MaxRetryError." + GENERIC_ERROR = 'too many error responses' + SPECIFIC_ERROR = 'too many {status_code} error responses' + + +class SecurityWarning(HTTPWarning): + "Warned when perfoming security reducing actions" + pass + + +class InsecureRequestWarning(SecurityWarning): + "Warned when making an unverified HTTPS request." + pass + + +class SystemTimeWarning(SecurityWarning): + "Warned when system time is suspected to be wrong" + pass + + +class InsecurePlatformWarning(SecurityWarning): + "Warned when certain SSL configuration is not available on a platform." + pass + + +class ResponseNotChunked(ProtocolError, ValueError): + "Response needs to be chunked in order to read it as chunks." + pass diff --git a/.venv/lib/python3.13/site-packages/botocore/vendored/six.py b/.venv/lib/python3.13/site-packages/botocore/vendored/six.py new file mode 100644 index 0000000000000000000000000000000000000000..4e15675d8b5caa33255fe37271700f587bd26671 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/botocore/vendored/six.py @@ -0,0 +1,998 @@ +# Copyright (c) 2010-2020 Benjamin Peterson +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +"""Utilities for writing code that runs on Python 2 and 3""" + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson " +__version__ = "1.16.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +PY34 = sys.version_info[0:2] >= (3, 4) + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + +if PY34: + from importlib.util import spec_from_loader +else: + spec_from_loader = None + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def find_spec(self, fullname, path, target=None): + if fullname in self.known_modules: + return spec_from_loader(fullname, self) + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + Required, if is_package is implemented""" + self.__get_module(fullname) # eventually raises ImportError + return None + get_source = get_code # same as get_code + + def create_module(self, spec): + return self.load_module(spec.name) + + def exec_module(self, module): + pass + +_importer = _SixMetaPathImporter(__name__) + + +class _MovedItems(_LazyModule): + + """Lazy loading of moved objects""" + __path__ = [] # mark as package + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("intern", "__builtin__", "sys"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), + MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), + MovedAttribute("getoutput", "commands", "subprocess"), + MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + MovedAttribute("UserString", "UserString", "collections"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread" if sys.version_info < (3, 9) else "_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), + MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), + MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("splitvalue", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +del attr + +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes + +_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), + "moves.urllib_parse", "moves.urllib.parse") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +del attr + +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes + +_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), + "moves.urllib_error", "moves.urllib.error") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), + MovedAttribute("parse_http_list", "urllib2", "urllib.request"), + MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +del attr + +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes + +_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), + "moves.urllib_request", "moves.urllib.request") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +del attr + +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes + +_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), + "moves.urllib_response", "moves.urllib.response") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +] +for attr in _urllib_robotparser_moved_attributes: + setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +del attr + +Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes + +_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), + "moves.urllib_robotparser", "moves.urllib.robotparser") + + +class Module_six_moves_urllib(types.ModuleType): + + """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + __path__ = [] # mark as package + parse = _importer._get_module("moves.urllib_parse") + error = _importer._get_module("moves.urllib_error") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + +try: + callable = callable +except NameError: + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) + + +if PY3: + def get_unbound_function(unbound): + return unbound + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + return types.MethodType(func, None, cls) + + class Iterator(object): + + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") +_add_doc(itervalues, "Return an iterator over the values of a dictionary.") +_add_doc(iteritems, + "Return an iterator over the (key, value) pairs of a dictionary.") +_add_doc(iterlists, + "Return an iterator over the (key, [values]) pairs of a dictionary.") + + +if PY3: + def b(s): + return s.encode("latin-1") + + def u(s): + return s + unichr = chr + import struct + int2byte = struct.Struct(">B").pack + del struct + byte2int = operator.itemgetter(0) + indexbytes = operator.getitem + iterbytes = iter + import io + StringIO = io.StringIO + BytesIO = io.BytesIO + del io + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + _assertNotRegex = "assertNotRegexpMatches" + else: + _assertRaisesRegex = "assertRaisesRegex" + _assertRegex = "assertRegex" + _assertNotRegex = "assertNotRegex" +else: + def b(s): + return s + # Workaround for standalone backslash + + def u(s): + return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + _assertNotRegex = "assertNotRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +def assertNotRegex(self, *args, **kwargs): + return getattr(self, _assertNotRegex)(*args, **kwargs) + + +if PY3: + exec_ = getattr(moves.builtins, "exec") + + def reraise(tp, value, tb=None): + try: + if value is None: + value = tp() + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + finally: + value = None + tb = None + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + exec_("""def reraise(tp, value, tb=None): + try: + raise tp, value, tb + finally: + tb = None +""") + + +if sys.version_info[:2] > (3,): + exec_("""def raise_from(value, from_value): + try: + raise value from from_value + finally: + value = None +""") +else: + def raise_from(value, from_value): + raise value + + +print_ = getattr(moves.builtins, "print", None) +if print_ is None: + def print_(*args, **kwargs): + """The new-style print function for Python 2.4 and 2.5.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + + def write(data): + if not isinstance(data, basestring): + data = str(data) + # If the file has an encoding, encode unicode with it. + if (isinstance(fp, file) and + isinstance(data, unicode) and + fp.encoding is not None): + errors = getattr(fp, "errors", None) + if errors is None: + errors = "strict" + data = data.encode(fp.encoding, errors) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + if flush and fp is not None: + fp.flush() + +_add_doc(reraise, """Reraise an exception.""") + +if sys.version_info[0:2] < (3, 4): + # This does exactly the same what the :func:`py3:functools.update_wrapper` + # function does on Python versions after 3.2. It sets the ``__wrapped__`` + # attribute on ``wrapper`` object and it doesn't raise an error if any of + # the attributes mentioned in ``assigned`` and ``updated`` are missing on + # ``wrapped`` object. + def _update_wrapper(wrapper, wrapped, + assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + for attr in assigned: + try: + value = getattr(wrapped, attr) + except AttributeError: + continue + else: + setattr(wrapper, attr, value) + for attr in updated: + getattr(wrapper, attr).update(getattr(wrapped, attr, {})) + wrapper.__wrapped__ = wrapped + return wrapper + _update_wrapper.__doc__ = functools.update_wrapper.__doc__ + + def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + return functools.partial(_update_wrapper, wrapped=wrapped, + assigned=assigned, updated=updated) + wraps.__doc__ = functools.wraps.__doc__ + +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(type): + + def __new__(cls, name, this_bases, d): + if sys.version_info[:2] >= (3, 7): + # This version introduced PEP 560 that requires a bit + # of extra care (we mimic what is done by __build_class__). + resolved_bases = types.resolve_bases(bases) + if resolved_bases is not bases: + d['__orig_bases__'] = bases + else: + resolved_bases = bases + return meta(name, resolved_bases, d) + + @classmethod + def __prepare__(cls, name, this_bases): + return meta.__prepare__(name, bases) + return type.__new__(metaclass, 'temporary_class', (), {}) + + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): + orig_vars = cls.__dict__.copy() + slots = orig_vars.get('__slots__') + if slots is not None: + if isinstance(slots, str): + slots = [slots] + for slots_var in slots: + orig_vars.pop(slots_var) + orig_vars.pop('__dict__', None) + orig_vars.pop('__weakref__', None) + if hasattr(cls, '__qualname__'): + orig_vars['__qualname__'] = cls.__qualname__ + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def ensure_binary(s, encoding='utf-8', errors='strict'): + """Coerce **s** to six.binary_type. + + For Python 2: + - `unicode` -> encoded to `str` + - `str` -> `str` + + For Python 3: + - `str` -> encoded to `bytes` + - `bytes` -> `bytes` + """ + if isinstance(s, binary_type): + return s + if isinstance(s, text_type): + return s.encode(encoding, errors) + raise TypeError("not expecting type '%s'" % type(s)) + + +def ensure_str(s, encoding='utf-8', errors='strict'): + """Coerce *s* to `str`. + + For Python 2: + - `unicode` -> encoded to `str` + - `str` -> `str` + + For Python 3: + - `str` -> `str` + - `bytes` -> decoded to `str` + """ + # Optimization: Fast return for the common case. + if type(s) is str: + return s + if PY2 and isinstance(s, text_type): + return s.encode(encoding, errors) + elif PY3 and isinstance(s, binary_type): + return s.decode(encoding, errors) + elif not isinstance(s, (text_type, binary_type)): + raise TypeError("not expecting type '%s'" % type(s)) + return s + + +def ensure_text(s, encoding='utf-8', errors='strict'): + """Coerce *s* to six.text_type. + + For Python 2: + - `unicode` -> `unicode` + - `str` -> `unicode` + + For Python 3: + - `str` -> `str` + - `bytes` -> decoded to `str` + """ + if isinstance(s, binary_type): + return s.decode(encoding, errors) + elif isinstance(s, text_type): + return s + else: + raise TypeError("not expecting type '%s'" % type(s)) + + +def python_2_unicode_compatible(klass): + """ + A class decorator that defines __unicode__ and __str__ methods under Python 2. + Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a __str__ method + returning text and apply this decorator to the class. + """ + if PY2: + if '__str__' not in klass.__dict__: + raise ValueError("@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % + klass.__name__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # be floating around. Therefore, we can't use isinstance() to check for + # the six meta path importer, since the other six instance will have + # inserted an importer with different class. + if (type(importer).__name__ == "_SixMetaPathImporter" and + importer.name == __name__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/.venv/lib/python3.13/site-packages/fontTools/cffLib/CFF2ToCFF.py b/.venv/lib/python3.13/site-packages/fontTools/cffLib/CFF2ToCFF.py new file mode 100644 index 0000000000000000000000000000000000000000..f33e48cc4c0e003ed907498b5d79d3eade23ccf5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/cffLib/CFF2ToCFF.py @@ -0,0 +1,258 @@ +"""CFF2 to CFF converter.""" + +from fontTools.ttLib import TTFont, newTable +from fontTools.misc.cliTools import makeOutputFileName +from fontTools.misc.psCharStrings import T2StackUseExtractor +from fontTools.cffLib import ( + TopDictIndex, + buildOrder, + buildDefaults, + topDictOperators, + privateDictOperators, + FDSelect, +) +from .transforms import desubroutinizeCharString +from .specializer import specializeProgram +from .width import optimizeWidths +from collections import defaultdict +import logging + + +__all__ = ["convertCFF2ToCFF", "main"] + + +log = logging.getLogger("fontTools.cffLib") + + +def _convertCFF2ToCFF(cff, otFont): + """Converts this object from CFF2 format to CFF format. This conversion + is done 'in-place'. The conversion cannot be reversed. + + The CFF2 font cannot be variable. (TODO Accept those and convert to the + default instance?) + + This assumes a decompiled CFF2 table. (i.e. that the object has been + filled via :meth:`decompile` and e.g. not loaded from XML.)""" + + cff.major = 1 + + topDictData = TopDictIndex(None) + for item in cff.topDictIndex: + # Iterate over, such that all are decompiled + item.cff2GetGlyphOrder = None + topDictData.append(item) + cff.topDictIndex = topDictData + topDict = topDictData[0] + + if hasattr(topDict, "VarStore"): + raise ValueError("Variable CFF2 font cannot be converted to CFF format.") + + opOrder = buildOrder(topDictOperators) + topDict.order = opOrder + for key in topDict.rawDict.keys(): + if key not in opOrder: + del topDict.rawDict[key] + if hasattr(topDict, key): + delattr(topDict, key) + + charStrings = topDict.CharStrings + + fdArray = topDict.FDArray + if not hasattr(topDict, "FDSelect"): + # FDSelect is optional in CFF2, but required in CFF. + fdSelect = topDict.FDSelect = FDSelect() + fdSelect.gidArray = [0] * len(charStrings.charStrings) + + defaults = buildDefaults(privateDictOperators) + order = buildOrder(privateDictOperators) + for fd in fdArray: + fd.setCFF2(False) + privateDict = fd.Private + privateDict.order = order + for key in order: + if key not in privateDict.rawDict and key in defaults: + privateDict.rawDict[key] = defaults[key] + for key in privateDict.rawDict.keys(): + if key not in order: + del privateDict.rawDict[key] + if hasattr(privateDict, key): + delattr(privateDict, key) + + # Add ending operators + for cs in charStrings.values(): + cs.decompile() + cs.program.append("endchar") + for subrSets in [cff.GlobalSubrs] + [ + getattr(fd.Private, "Subrs", []) for fd in fdArray + ]: + for cs in subrSets: + cs.program.append("return") + + # Add (optimal) width to CharStrings that need it. + widths = defaultdict(list) + metrics = otFont["hmtx"].metrics + for glyphName in charStrings.keys(): + cs, fdIndex = charStrings.getItemAndSelector(glyphName) + if fdIndex == None: + fdIndex = 0 + widths[fdIndex].append(metrics[glyphName][0]) + for fdIndex, widthList in widths.items(): + bestDefault, bestNominal = optimizeWidths(widthList) + private = fdArray[fdIndex].Private + private.defaultWidthX = bestDefault + private.nominalWidthX = bestNominal + for glyphName in charStrings.keys(): + cs, fdIndex = charStrings.getItemAndSelector(glyphName) + if fdIndex == None: + fdIndex = 0 + private = fdArray[fdIndex].Private + width = metrics[glyphName][0] + if width != private.defaultWidthX: + cs.program.insert(0, width - private.nominalWidthX) + + # Handle stack use since stack-depth is lower in CFF than in CFF2. + for glyphName in charStrings.keys(): + cs, fdIndex = charStrings.getItemAndSelector(glyphName) + if fdIndex is None: + fdIndex = 0 + private = fdArray[fdIndex].Private + extractor = T2StackUseExtractor( + getattr(private, "Subrs", []), cff.GlobalSubrs, private=private + ) + stackUse = extractor.execute(cs) + if stackUse > 48: # CFF stack depth is 48 + desubroutinizeCharString(cs) + cs.program = specializeProgram(cs.program) + + # Unused subroutines are still in CFF2 (ie. lacking 'return' operator) + # because they were not decompiled when we added the 'return'. + # Moreover, some used subroutines may have become unused after the + # stack-use fixup. So we remove all unused subroutines now. + cff.remove_unused_subroutines() + + mapping = { + name: ("cid" + str(n).zfill(5) if n else ".notdef") + for n, name in enumerate(topDict.charset) + } + topDict.charset = [ + "cid" + str(n).zfill(5) if n else ".notdef" for n in range(len(topDict.charset)) + ] + charStrings.charStrings = { + mapping[name]: v for name, v in charStrings.charStrings.items() + } + + topDict.ROS = ("Adobe", "Identity", 0) + + +def convertCFF2ToCFF(font, *, updatePostTable=True): + if "CFF2" not in font: + raise ValueError("Input font does not contain a CFF2 table.") + cff = font["CFF2"].cff + _convertCFF2ToCFF(cff, font) + del font["CFF2"] + table = font["CFF "] = newTable("CFF ") + table.cff = cff + + if updatePostTable and "post" in font: + # Only version supported for fonts with CFF table is 0x00030000 not 0x20000 + post = font["post"] + if post.formatType == 2.0: + post.formatType = 3.0 + + +def main(args=None): + """Convert CFF2 OTF font to CFF OTF font""" + if args is None: + import sys + + args = sys.argv[1:] + + import argparse + + parser = argparse.ArgumentParser( + "fonttools cffLib.CFF2ToCFF", + description="Convert a non-variable CFF2 font to CFF.", + ) + parser.add_argument( + "input", metavar="INPUT.ttf", help="Input OTF file with CFF table." + ) + parser.add_argument( + "-o", + "--output", + metavar="OUTPUT.ttf", + default=None, + help="Output instance OTF file (default: INPUT-CFF2.ttf).", + ) + parser.add_argument( + "--no-recalc-timestamp", + dest="recalc_timestamp", + action="store_false", + help="Don't set the output font's timestamp to the current time.", + ) + parser.add_argument( + "--remove-overlaps", + action="store_true", + help="Merge overlapping contours and components. Requires skia-pathops", + ) + parser.add_argument( + "--ignore-overlap-errors", + action="store_true", + help="Don't crash if the remove-overlaps operation fails for some glyphs.", + ) + loggingGroup = parser.add_mutually_exclusive_group(required=False) + loggingGroup.add_argument( + "-v", "--verbose", action="store_true", help="Run more verbosely." + ) + loggingGroup.add_argument( + "-q", "--quiet", action="store_true", help="Turn verbosity off." + ) + options = parser.parse_args(args) + + from fontTools import configLogger + + configLogger( + level=("DEBUG" if options.verbose else "ERROR" if options.quiet else "INFO") + ) + + import os + + infile = options.input + if not os.path.isfile(infile): + parser.error("No such file '{}'".format(infile)) + + outfile = ( + makeOutputFileName(infile, overWrite=True, suffix="-CFF") + if not options.output + else options.output + ) + + font = TTFont(infile, recalcTimestamp=options.recalc_timestamp, recalcBBoxes=False) + + convertCFF2ToCFF(font) + + if options.remove_overlaps: + from fontTools.ttLib.removeOverlaps import removeOverlaps + from io import BytesIO + + log.debug("Removing overlaps") + + stream = BytesIO() + font.save(stream) + stream.seek(0) + font = TTFont(stream, recalcTimestamp=False, recalcBBoxes=False) + removeOverlaps( + font, + ignoreErrors=options.ignore_overlap_errors, + ) + + log.info( + "Saving %s", + outfile, + ) + font.save(outfile) + + +if __name__ == "__main__": + import sys + + sys.exit(main(sys.argv[1:])) diff --git a/.venv/lib/python3.13/site-packages/fontTools/cffLib/CFFToCFF2.py b/.venv/lib/python3.13/site-packages/fontTools/cffLib/CFFToCFF2.py new file mode 100644 index 0000000000000000000000000000000000000000..2555f0b242591cde7738f46932fd1cbe2d0a6ccf --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/cffLib/CFFToCFF2.py @@ -0,0 +1,305 @@ +"""CFF to CFF2 converter.""" + +from fontTools.ttLib import TTFont, newTable +from fontTools.misc.cliTools import makeOutputFileName +from fontTools.misc.psCharStrings import T2WidthExtractor +from fontTools.cffLib import ( + TopDictIndex, + FDArrayIndex, + FontDict, + buildOrder, + topDictOperators, + privateDictOperators, + topDictOperators2, + privateDictOperators2, +) +from io import BytesIO +import logging + +__all__ = ["convertCFFToCFF2", "main"] + + +log = logging.getLogger("fontTools.cffLib") + + +class _NominalWidthUsedError(Exception): + def __add__(self, other): + raise self + + def __radd__(self, other): + raise self + + +def _convertCFFToCFF2(cff, otFont): + """Converts this object from CFF format to CFF2 format. This conversion + is done 'in-place'. The conversion cannot be reversed. + + This assumes a decompiled CFF table. (i.e. that the object has been + filled via :meth:`decompile` and e.g. not loaded from XML.)""" + + # Clean up T2CharStrings + + topDict = cff.topDictIndex[0] + fdArray = topDict.FDArray if hasattr(topDict, "FDArray") else None + charStrings = topDict.CharStrings + globalSubrs = cff.GlobalSubrs + localSubrs = ( + [getattr(fd.Private, "Subrs", []) for fd in fdArray] + if fdArray + else ( + [topDict.Private.Subrs] + if hasattr(topDict, "Private") and hasattr(topDict.Private, "Subrs") + else [] + ) + ) + + for glyphName in charStrings.keys(): + cs, fdIndex = charStrings.getItemAndSelector(glyphName) + cs.decompile() + + # Clean up subroutines first + for subrs in [globalSubrs] + localSubrs: + for subr in subrs: + program = subr.program + i = j = len(program) + try: + i = program.index("return") + except ValueError: + pass + try: + j = program.index("endchar") + except ValueError: + pass + program[min(i, j) :] = [] + + # Clean up glyph charstrings + removeUnusedSubrs = False + nominalWidthXError = _NominalWidthUsedError() + for glyphName in charStrings.keys(): + cs, fdIndex = charStrings.getItemAndSelector(glyphName) + program = cs.program + + thisLocalSubrs = ( + localSubrs[fdIndex] + if fdIndex is not None + else ( + getattr(topDict.Private, "Subrs", []) + if hasattr(topDict, "Private") + else [] + ) + ) + + # Intentionally use custom type for nominalWidthX, such that any + # CharString that has an explicit width encoded will throw back to us. + extractor = T2WidthExtractor( + thisLocalSubrs, + globalSubrs, + nominalWidthXError, + 0, + ) + try: + extractor.execute(cs) + except _NominalWidthUsedError: + # Program has explicit width. We want to drop it, but can't + # just pop the first number since it may be a subroutine call. + # Instead, when seeing that, we embed the subroutine and recurse. + # If this ever happened, we later prune unused subroutines. + while len(program) >= 2 and program[1] in ["callsubr", "callgsubr"]: + removeUnusedSubrs = True + subrNumber = program.pop(0) + assert isinstance(subrNumber, int), subrNumber + op = program.pop(0) + bias = extractor.localBias if op == "callsubr" else extractor.globalBias + subrNumber += bias + subrSet = thisLocalSubrs if op == "callsubr" else globalSubrs + subrProgram = subrSet[subrNumber].program + program[:0] = subrProgram + # Now pop the actual width + assert len(program) >= 1, program + program.pop(0) + + if program and program[-1] == "endchar": + program.pop() + + if removeUnusedSubrs: + cff.remove_unused_subroutines() + + # Upconvert TopDict + + cff.major = 2 + cff2GetGlyphOrder = cff.otFont.getGlyphOrder + topDictData = TopDictIndex(None, cff2GetGlyphOrder) + for item in cff.topDictIndex: + # Iterate over, such that all are decompiled + topDictData.append(item) + cff.topDictIndex = topDictData + topDict = topDictData[0] + if hasattr(topDict, "Private"): + privateDict = topDict.Private + else: + privateDict = None + opOrder = buildOrder(topDictOperators2) + topDict.order = opOrder + topDict.cff2GetGlyphOrder = cff2GetGlyphOrder + + if not hasattr(topDict, "FDArray"): + fdArray = topDict.FDArray = FDArrayIndex() + fdArray.strings = None + fdArray.GlobalSubrs = topDict.GlobalSubrs + topDict.GlobalSubrs.fdArray = fdArray + charStrings = topDict.CharStrings + if charStrings.charStringsAreIndexed: + charStrings.charStringsIndex.fdArray = fdArray + else: + charStrings.fdArray = fdArray + fontDict = FontDict() + fontDict.setCFF2(True) + fdArray.append(fontDict) + fontDict.Private = privateDict + privateOpOrder = buildOrder(privateDictOperators2) + if privateDict is not None: + for entry in privateDictOperators: + key = entry[1] + if key not in privateOpOrder: + if key in privateDict.rawDict: + # print "Removing private dict", key + del privateDict.rawDict[key] + if hasattr(privateDict, key): + delattr(privateDict, key) + # print "Removing privateDict attr", key + else: + # clean up the PrivateDicts in the fdArray + fdArray = topDict.FDArray + privateOpOrder = buildOrder(privateDictOperators2) + for fontDict in fdArray: + fontDict.setCFF2(True) + for key in list(fontDict.rawDict.keys()): + if key not in fontDict.order: + del fontDict.rawDict[key] + if hasattr(fontDict, key): + delattr(fontDict, key) + + privateDict = fontDict.Private + for entry in privateDictOperators: + key = entry[1] + if key not in privateOpOrder: + if key in list(privateDict.rawDict.keys()): + # print "Removing private dict", key + del privateDict.rawDict[key] + if hasattr(privateDict, key): + delattr(privateDict, key) + # print "Removing privateDict attr", key + + # Now delete up the deprecated topDict operators from CFF 1.0 + for entry in topDictOperators: + key = entry[1] + # We seem to need to keep the charset operator for now, + # or we fail to compile with some fonts, like AdditionFont.otf. + # I don't know which kind of CFF font those are. But keeping + # charset seems to work. It will be removed when we save and + # read the font again. + # + # AdditionFont.otf has . + if key == "charset": + continue + if key not in opOrder: + if key in topDict.rawDict: + del topDict.rawDict[key] + if hasattr(topDict, key): + delattr(topDict, key) + + # TODO(behdad): What does the following comment even mean? Both CFF and CFF2 + # use the same T2Charstring class. I *think* what it means is that the CharStrings + # were loaded for CFF1, and we need to reload them for CFF2 to set varstore, etc + # on them. At least that's what I understand. It's probably safe to remove this + # and just set vstore where needed. + # + # See comment above about charset as well. + + # At this point, the Subrs and Charstrings are all still T2Charstring class + # easiest to fix this by compiling, then decompiling again + file = BytesIO() + cff.compile(file, otFont, isCFF2=True) + file.seek(0) + cff.decompile(file, otFont, isCFF2=True) + + +def convertCFFToCFF2(font): + cff = font["CFF "].cff + del font["CFF "] + _convertCFFToCFF2(cff, font) + table = font["CFF2"] = newTable("CFF2") + table.cff = cff + + +def main(args=None): + """Convert CFF OTF font to CFF2 OTF font""" + if args is None: + import sys + + args = sys.argv[1:] + + import argparse + + parser = argparse.ArgumentParser( + "fonttools cffLib.CFFToCFF2", + description="Upgrade a CFF font to CFF2.", + ) + parser.add_argument( + "input", metavar="INPUT.ttf", help="Input OTF file with CFF table." + ) + parser.add_argument( + "-o", + "--output", + metavar="OUTPUT.ttf", + default=None, + help="Output instance OTF file (default: INPUT-CFF2.ttf).", + ) + parser.add_argument( + "--no-recalc-timestamp", + dest="recalc_timestamp", + action="store_false", + help="Don't set the output font's timestamp to the current time.", + ) + loggingGroup = parser.add_mutually_exclusive_group(required=False) + loggingGroup.add_argument( + "-v", "--verbose", action="store_true", help="Run more verbosely." + ) + loggingGroup.add_argument( + "-q", "--quiet", action="store_true", help="Turn verbosity off." + ) + options = parser.parse_args(args) + + from fontTools import configLogger + + configLogger( + level=("DEBUG" if options.verbose else "ERROR" if options.quiet else "INFO") + ) + + import os + + infile = options.input + if not os.path.isfile(infile): + parser.error("No such file '{}'".format(infile)) + + outfile = ( + makeOutputFileName(infile, overWrite=True, suffix="-CFF2") + if not options.output + else options.output + ) + + font = TTFont(infile, recalcTimestamp=options.recalc_timestamp, recalcBBoxes=False) + + convertCFFToCFF2(font) + + log.info( + "Saving %s", + outfile, + ) + font.save(outfile) + + +if __name__ == "__main__": + import sys + + sys.exit(main(sys.argv[1:])) diff --git a/.venv/lib/python3.13/site-packages/fontTools/cffLib/__init__.py b/.venv/lib/python3.13/site-packages/fontTools/cffLib/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..4ad724a27a812839d6c5e58314a5ff2f583d978c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/cffLib/__init__.py @@ -0,0 +1,3694 @@ +"""cffLib: read/write Adobe CFF fonts + +OpenType fonts with PostScript outlines embed a completely independent +font file in Adobe's *Compact Font Format*. So dealing with OpenType fonts +requires also dealing with CFF. This module allows you to read and write +fonts written in the CFF format. + +In 2016, OpenType 1.8 introduced the `CFF2 `_ +format which, along with other changes, extended the CFF format to deal with +the demands of variable fonts. This module parses both original CFF and CFF2. + +""" + +from fontTools.misc import sstruct +from fontTools.misc import psCharStrings +from fontTools.misc.arrayTools import unionRect, intRect +from fontTools.misc.textTools import ( + bytechr, + byteord, + bytesjoin, + tobytes, + tostr, + safeEval, +) +from fontTools.ttLib import TTFont +from fontTools.ttLib.tables.otBase import OTTableWriter +from fontTools.ttLib.tables.otBase import OTTableReader +from fontTools.ttLib.tables import otTables as ot +from io import BytesIO +import struct +import logging +import re + +# mute cffLib debug messages when running ttx in verbose mode +DEBUG = logging.DEBUG - 1 +log = logging.getLogger(__name__) + +cffHeaderFormat = """ + major: B + minor: B + hdrSize: B +""" + +maxStackLimit = 513 +# maxstack operator has been deprecated. max stack is now always 513. + + +class CFFFontSet(object): + """A CFF font "file" can contain more than one font, although this is + extremely rare (and not allowed within OpenType fonts). + + This class is the entry point for parsing a CFF table. To actually + manipulate the data inside the CFF font, you will want to access the + ``CFFFontSet``'s :class:`TopDict` object. To do this, a ``CFFFontSet`` + object can either be treated as a dictionary (with appropriate + ``keys()`` and ``values()`` methods) mapping font names to :class:`TopDict` + objects, or as a list. + + .. code:: python + + from fontTools import ttLib + tt = ttLib.TTFont("Tests/cffLib/data/LinLibertine_RBI.otf") + tt["CFF "].cff + # + tt["CFF "].cff[0] # Here's your actual font data + # + + """ + + def decompile(self, file, otFont, isCFF2=None): + """Parse a binary CFF file into an internal representation. ``file`` + should be a file handle object. ``otFont`` is the top-level + :py:class:`fontTools.ttLib.ttFont.TTFont` object containing this CFF file. + + If ``isCFF2`` is passed and set to ``True`` or ``False``, then the + library makes an assertion that the CFF header is of the appropriate + version. + """ + + self.otFont = otFont + sstruct.unpack(cffHeaderFormat, file.read(3), self) + if isCFF2 is not None: + # called from ttLib: assert 'major' as read from file matches the + # expected version + expected_major = 2 if isCFF2 else 1 + if self.major != expected_major: + raise ValueError( + "Invalid CFF 'major' version: expected %d, found %d" + % (expected_major, self.major) + ) + else: + # use 'major' version from file to determine if isCFF2 + assert self.major in (1, 2), "Unknown CFF format" + isCFF2 = self.major == 2 + if not isCFF2: + self.offSize = struct.unpack("B", file.read(1))[0] + file.seek(self.hdrSize) + self.fontNames = list(tostr(s) for s in Index(file, isCFF2=isCFF2)) + self.topDictIndex = TopDictIndex(file, isCFF2=isCFF2) + self.strings = IndexedStrings(file) + else: # isCFF2 + self.topDictSize = struct.unpack(">H", file.read(2))[0] + file.seek(self.hdrSize) + self.fontNames = ["CFF2Font"] + cff2GetGlyphOrder = otFont.getGlyphOrder + # in CFF2, offsetSize is the size of the TopDict data. + self.topDictIndex = TopDictIndex( + file, cff2GetGlyphOrder, self.topDictSize, isCFF2=isCFF2 + ) + self.strings = None + self.GlobalSubrs = GlobalSubrsIndex(file, isCFF2=isCFF2) + self.topDictIndex.strings = self.strings + self.topDictIndex.GlobalSubrs = self.GlobalSubrs + + def __len__(self): + return len(self.fontNames) + + def keys(self): + return list(self.fontNames) + + def values(self): + return self.topDictIndex + + def __getitem__(self, nameOrIndex): + """Return TopDict instance identified by name (str) or index (int + or any object that implements `__index__`). + """ + if hasattr(nameOrIndex, "__index__"): + index = nameOrIndex.__index__() + elif isinstance(nameOrIndex, str): + name = nameOrIndex + try: + index = self.fontNames.index(name) + except ValueError: + raise KeyError(nameOrIndex) + else: + raise TypeError(nameOrIndex) + return self.topDictIndex[index] + + def compile(self, file, otFont, isCFF2=None): + """Write the object back into binary representation onto the given file. + ``file`` should be a file handle object. ``otFont`` is the top-level + :py:class:`fontTools.ttLib.ttFont.TTFont` object containing this CFF file. + + If ``isCFF2`` is passed and set to ``True`` or ``False``, then the + library makes an assertion that the CFF header is of the appropriate + version. + """ + self.otFont = otFont + if isCFF2 is not None: + # called from ttLib: assert 'major' value matches expected version + expected_major = 2 if isCFF2 else 1 + if self.major != expected_major: + raise ValueError( + "Invalid CFF 'major' version: expected %d, found %d" + % (expected_major, self.major) + ) + else: + # use current 'major' value to determine output format + assert self.major in (1, 2), "Unknown CFF format" + isCFF2 = self.major == 2 + + if otFont.recalcBBoxes and not isCFF2: + for topDict in self.topDictIndex: + topDict.recalcFontBBox() + + if not isCFF2: + strings = IndexedStrings() + else: + strings = None + writer = CFFWriter(isCFF2) + topCompiler = self.topDictIndex.getCompiler(strings, self, isCFF2=isCFF2) + if isCFF2: + self.hdrSize = 5 + writer.add(sstruct.pack(cffHeaderFormat, self)) + # Note: topDictSize will most likely change in CFFWriter.toFile(). + self.topDictSize = topCompiler.getDataLength() + writer.add(struct.pack(">H", self.topDictSize)) + else: + self.hdrSize = 4 + self.offSize = 4 # will most likely change in CFFWriter.toFile(). + writer.add(sstruct.pack(cffHeaderFormat, self)) + writer.add(struct.pack("B", self.offSize)) + if not isCFF2: + fontNames = Index() + for name in self.fontNames: + fontNames.append(name) + writer.add(fontNames.getCompiler(strings, self, isCFF2=isCFF2)) + writer.add(topCompiler) + if not isCFF2: + writer.add(strings.getCompiler()) + writer.add(self.GlobalSubrs.getCompiler(strings, self, isCFF2=isCFF2)) + + for topDict in self.topDictIndex: + if not hasattr(topDict, "charset") or topDict.charset is None: + charset = otFont.getGlyphOrder() + topDict.charset = charset + children = topCompiler.getChildren(strings) + for child in children: + writer.add(child) + + writer.toFile(file) + + def toXML(self, xmlWriter): + """Write the object into XML representation onto the given + :class:`fontTools.misc.xmlWriter.XMLWriter`. + + .. code:: python + + writer = xmlWriter.XMLWriter(sys.stdout) + tt["CFF "].cff.toXML(writer) + + """ + + xmlWriter.simpletag("major", value=self.major) + xmlWriter.newline() + xmlWriter.simpletag("minor", value=self.minor) + xmlWriter.newline() + for fontName in self.fontNames: + xmlWriter.begintag("CFFFont", name=tostr(fontName)) + xmlWriter.newline() + font = self[fontName] + font.toXML(xmlWriter) + xmlWriter.endtag("CFFFont") + xmlWriter.newline() + xmlWriter.newline() + xmlWriter.begintag("GlobalSubrs") + xmlWriter.newline() + self.GlobalSubrs.toXML(xmlWriter) + xmlWriter.endtag("GlobalSubrs") + xmlWriter.newline() + + def fromXML(self, name, attrs, content, otFont=None): + """Reads data from the XML element into the ``CFFFontSet`` object.""" + self.otFont = otFont + + # set defaults. These will be replaced if there are entries for them + # in the XML file. + if not hasattr(self, "major"): + self.major = 1 + if not hasattr(self, "minor"): + self.minor = 0 + + if name == "CFFFont": + if self.major == 1: + if not hasattr(self, "offSize"): + # this will be recalculated when the cff is compiled. + self.offSize = 4 + if not hasattr(self, "hdrSize"): + self.hdrSize = 4 + if not hasattr(self, "GlobalSubrs"): + self.GlobalSubrs = GlobalSubrsIndex() + if not hasattr(self, "fontNames"): + self.fontNames = [] + self.topDictIndex = TopDictIndex() + fontName = attrs["name"] + self.fontNames.append(fontName) + topDict = TopDict(GlobalSubrs=self.GlobalSubrs) + topDict.charset = None # gets filled in later + elif self.major == 2: + if not hasattr(self, "hdrSize"): + self.hdrSize = 5 + if not hasattr(self, "GlobalSubrs"): + self.GlobalSubrs = GlobalSubrsIndex() + if not hasattr(self, "fontNames"): + self.fontNames = ["CFF2Font"] + cff2GetGlyphOrder = self.otFont.getGlyphOrder + topDict = TopDict( + GlobalSubrs=self.GlobalSubrs, cff2GetGlyphOrder=cff2GetGlyphOrder + ) + self.topDictIndex = TopDictIndex(None, cff2GetGlyphOrder) + self.topDictIndex.append(topDict) + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + topDict.fromXML(name, attrs, content) + + if hasattr(topDict, "VarStore") and topDict.FDArray[0].vstore is None: + fdArray = topDict.FDArray + for fontDict in fdArray: + if hasattr(fontDict, "Private"): + fontDict.Private.vstore = topDict.VarStore + + elif name == "GlobalSubrs": + subrCharStringClass = psCharStrings.T2CharString + if not hasattr(self, "GlobalSubrs"): + self.GlobalSubrs = GlobalSubrsIndex() + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + subr = subrCharStringClass() + subr.fromXML(name, attrs, content) + self.GlobalSubrs.append(subr) + elif name == "major": + self.major = int(attrs["value"]) + elif name == "minor": + self.minor = int(attrs["value"]) + + def convertCFFToCFF2(self, otFont): + from .CFFToCFF2 import _convertCFFToCFF2 + + _convertCFFToCFF2(self, otFont) + + def convertCFF2ToCFF(self, otFont): + from .CFF2ToCFF import _convertCFF2ToCFF + + _convertCFF2ToCFF(self, otFont) + + def desubroutinize(self): + from .transforms import desubroutinize + + desubroutinize(self) + + def remove_hints(self): + from .transforms import remove_hints + + remove_hints(self) + + def remove_unused_subroutines(self): + from .transforms import remove_unused_subroutines + + remove_unused_subroutines(self) + + +class CFFWriter(object): + """Helper class for serializing CFF data to binary. Used by + :meth:`CFFFontSet.compile`.""" + + def __init__(self, isCFF2): + self.data = [] + self.isCFF2 = isCFF2 + + def add(self, table): + self.data.append(table) + + def toFile(self, file): + lastPosList = None + count = 1 + while True: + log.log(DEBUG, "CFFWriter.toFile() iteration: %d", count) + count = count + 1 + pos = 0 + posList = [pos] + for item in self.data: + if hasattr(item, "getDataLength"): + endPos = pos + item.getDataLength() + if isinstance(item, TopDictIndexCompiler) and item.isCFF2: + self.topDictSize = item.getDataLength() + else: + endPos = pos + len(item) + if hasattr(item, "setPos"): + item.setPos(pos, endPos) + pos = endPos + posList.append(pos) + if posList == lastPosList: + break + lastPosList = posList + log.log(DEBUG, "CFFWriter.toFile() writing to file.") + begin = file.tell() + if self.isCFF2: + self.data[1] = struct.pack(">H", self.topDictSize) + else: + self.offSize = calcOffSize(lastPosList[-1]) + self.data[1] = struct.pack("B", self.offSize) + posList = [0] + for item in self.data: + if hasattr(item, "toFile"): + item.toFile(file) + else: + file.write(item) + posList.append(file.tell() - begin) + assert posList == lastPosList + + +def calcOffSize(largestOffset): + if largestOffset < 0x100: + offSize = 1 + elif largestOffset < 0x10000: + offSize = 2 + elif largestOffset < 0x1000000: + offSize = 3 + else: + offSize = 4 + return offSize + + +class IndexCompiler(object): + """Base class for writing CFF `INDEX data `_ + to binary.""" + + def __init__(self, items, strings, parent, isCFF2=None): + if isCFF2 is None and hasattr(parent, "isCFF2"): + isCFF2 = parent.isCFF2 + assert isCFF2 is not None + self.isCFF2 = isCFF2 + self.items = self.getItems(items, strings) + self.parent = parent + + def getItems(self, items, strings): + return items + + def getOffsets(self): + # An empty INDEX contains only the count field. + if self.items: + pos = 1 + offsets = [pos] + for item in self.items: + if hasattr(item, "getDataLength"): + pos = pos + item.getDataLength() + else: + pos = pos + len(item) + offsets.append(pos) + else: + offsets = [] + return offsets + + def getDataLength(self): + if self.isCFF2: + countSize = 4 + else: + countSize = 2 + + if self.items: + lastOffset = self.getOffsets()[-1] + offSize = calcOffSize(lastOffset) + dataLength = ( + countSize + + 1 # count + + (len(self.items) + 1) * offSize # offSize + + lastOffset # the offsets + - 1 # size of object data + ) + else: + # count. For empty INDEX tables, this is the only entry. + dataLength = countSize + + return dataLength + + def toFile(self, file): + offsets = self.getOffsets() + if self.isCFF2: + writeCard32(file, len(self.items)) + else: + writeCard16(file, len(self.items)) + # An empty INDEX contains only the count field. + if self.items: + offSize = calcOffSize(offsets[-1]) + writeCard8(file, offSize) + offSize = -offSize + pack = struct.pack + for offset in offsets: + binOffset = pack(">l", offset)[offSize:] + assert len(binOffset) == -offSize + file.write(binOffset) + for item in self.items: + if hasattr(item, "toFile"): + item.toFile(file) + else: + data = tobytes(item, encoding="latin1") + file.write(data) + + +class IndexedStringsCompiler(IndexCompiler): + def getItems(self, items, strings): + return items.strings + + +class TopDictIndexCompiler(IndexCompiler): + """Helper class for writing the TopDict to binary.""" + + def getItems(self, items, strings): + out = [] + for item in items: + out.append(item.getCompiler(strings, self)) + return out + + def getChildren(self, strings): + children = [] + for topDict in self.items: + children.extend(topDict.getChildren(strings)) + return children + + def getOffsets(self): + if self.isCFF2: + offsets = [0, self.items[0].getDataLength()] + return offsets + else: + return super(TopDictIndexCompiler, self).getOffsets() + + def getDataLength(self): + if self.isCFF2: + dataLength = self.items[0].getDataLength() + return dataLength + else: + return super(TopDictIndexCompiler, self).getDataLength() + + def toFile(self, file): + if self.isCFF2: + self.items[0].toFile(file) + else: + super(TopDictIndexCompiler, self).toFile(file) + + +class FDArrayIndexCompiler(IndexCompiler): + """Helper class for writing the + `Font DICT INDEX `_ + to binary.""" + + def getItems(self, items, strings): + out = [] + for item in items: + out.append(item.getCompiler(strings, self)) + return out + + def getChildren(self, strings): + children = [] + for fontDict in self.items: + children.extend(fontDict.getChildren(strings)) + return children + + def toFile(self, file): + offsets = self.getOffsets() + if self.isCFF2: + writeCard32(file, len(self.items)) + else: + writeCard16(file, len(self.items)) + offSize = calcOffSize(offsets[-1]) + writeCard8(file, offSize) + offSize = -offSize + pack = struct.pack + for offset in offsets: + binOffset = pack(">l", offset)[offSize:] + assert len(binOffset) == -offSize + file.write(binOffset) + for item in self.items: + if hasattr(item, "toFile"): + item.toFile(file) + else: + file.write(item) + + def setPos(self, pos, endPos): + self.parent.rawDict["FDArray"] = pos + + +class GlobalSubrsCompiler(IndexCompiler): + """Helper class for writing the `global subroutine INDEX `_ + to binary.""" + + def getItems(self, items, strings): + out = [] + for cs in items: + cs.compile(self.isCFF2) + out.append(cs.bytecode) + return out + + +class SubrsCompiler(GlobalSubrsCompiler): + """Helper class for writing the `local subroutine INDEX `_ + to binary.""" + + def setPos(self, pos, endPos): + offset = pos - self.parent.pos + self.parent.rawDict["Subrs"] = offset + + +class CharStringsCompiler(GlobalSubrsCompiler): + """Helper class for writing the `CharStrings INDEX `_ + to binary.""" + + def getItems(self, items, strings): + out = [] + for cs in items: + cs.compile(self.isCFF2) + out.append(cs.bytecode) + return out + + def setPos(self, pos, endPos): + self.parent.rawDict["CharStrings"] = pos + + +class Index(object): + """This class represents what the CFF spec calls an INDEX (an array of + variable-sized objects). `Index` items can be addressed and set using + Python list indexing.""" + + compilerClass = IndexCompiler + + def __init__(self, file=None, isCFF2=None): + self.items = [] + self.offsets = offsets = [] + name = self.__class__.__name__ + if file is None: + return + self._isCFF2 = isCFF2 + log.log(DEBUG, "loading %s at %s", name, file.tell()) + self.file = file + if isCFF2: + count = readCard32(file) + else: + count = readCard16(file) + if count == 0: + return + self.items = [None] * count + offSize = readCard8(file) + log.log(DEBUG, " index count: %s offSize: %s", count, offSize) + assert offSize <= 4, "offSize too large: %s" % offSize + pad = b"\0" * (4 - offSize) + for index in range(count + 1): + chunk = file.read(offSize) + chunk = pad + chunk + (offset,) = struct.unpack(">L", chunk) + offsets.append(int(offset)) + self.offsetBase = file.tell() - 1 + file.seek(self.offsetBase + offsets[-1]) # pretend we've read the whole lot + log.log(DEBUG, " end of %s at %s", name, file.tell()) + + def __len__(self): + return len(self.items) + + def __getitem__(self, index): + item = self.items[index] + if item is not None: + return item + offset = self.offsets[index] + self.offsetBase + size = self.offsets[index + 1] - self.offsets[index] + file = self.file + file.seek(offset) + data = file.read(size) + assert len(data) == size + item = self.produceItem(index, data, file, offset) + self.items[index] = item + return item + + def __setitem__(self, index, item): + self.items[index] = item + + def produceItem(self, index, data, file, offset): + return data + + def append(self, item): + """Add an item to an INDEX.""" + self.items.append(item) + + def getCompiler(self, strings, parent, isCFF2=None): + return self.compilerClass(self, strings, parent, isCFF2=isCFF2) + + def clear(self): + """Empty the INDEX.""" + del self.items[:] + + +class GlobalSubrsIndex(Index): + """This index contains all the global subroutines in the font. A global + subroutine is a set of ``CharString`` data which is accessible to any + glyph in the font, and are used to store repeated instructions - for + example, components may be encoded as global subroutines, but so could + hinting instructions. + + Remember that when interpreting a ``callgsubr`` instruction (or indeed + a ``callsubr`` instruction) that you will need to add the "subroutine + number bias" to number given: + + .. code:: python + + tt = ttLib.TTFont("Almendra-Bold.otf") + u = tt["CFF "].cff[0].CharStrings["udieresis"] + u.decompile() + + u.toXML(XMLWriter(sys.stdout)) + # + # -64 callgsubr <-- Subroutine which implements the dieresis mark + # + + tt["CFF "].cff[0].GlobalSubrs[-64] # <-- WRONG + # + + tt["CFF "].cff[0].GlobalSubrs[-64 + 107] # <-- RIGHT + # + + ("The bias applied depends on the number of subrs (gsubrs). If the number of + subrs (gsubrs) is less than 1240, the bias is 107. Otherwise if it is less + than 33900, it is 1131; otherwise it is 32768.", + `Subroutine Operators `) + """ + + compilerClass = GlobalSubrsCompiler + subrClass = psCharStrings.T2CharString + charStringClass = psCharStrings.T2CharString + + def __init__( + self, + file=None, + globalSubrs=None, + private=None, + fdSelect=None, + fdArray=None, + isCFF2=None, + ): + super(GlobalSubrsIndex, self).__init__(file, isCFF2=isCFF2) + self.globalSubrs = globalSubrs + self.private = private + if fdSelect: + self.fdSelect = fdSelect + if fdArray: + self.fdArray = fdArray + + def produceItem(self, index, data, file, offset): + if self.private is not None: + private = self.private + elif hasattr(self, "fdArray") and self.fdArray is not None: + if hasattr(self, "fdSelect") and self.fdSelect is not None: + fdIndex = self.fdSelect[index] + else: + fdIndex = 0 + private = self.fdArray[fdIndex].Private + else: + private = None + return self.subrClass(data, private=private, globalSubrs=self.globalSubrs) + + def toXML(self, xmlWriter): + """Write the subroutines index into XML representation onto the given + :class:`fontTools.misc.xmlWriter.XMLWriter`. + + .. code:: python + + writer = xmlWriter.XMLWriter(sys.stdout) + tt["CFF "].cff[0].GlobalSubrs.toXML(writer) + + """ + xmlWriter.comment( + "The 'index' attribute is only for humans; " "it is ignored when parsed." + ) + xmlWriter.newline() + for i in range(len(self)): + subr = self[i] + if subr.needsDecompilation(): + xmlWriter.begintag("CharString", index=i, raw=1) + else: + xmlWriter.begintag("CharString", index=i) + xmlWriter.newline() + subr.toXML(xmlWriter) + xmlWriter.endtag("CharString") + xmlWriter.newline() + + def fromXML(self, name, attrs, content): + if name != "CharString": + return + subr = self.subrClass() + subr.fromXML(name, attrs, content) + self.append(subr) + + def getItemAndSelector(self, index): + sel = None + if hasattr(self, "fdSelect"): + sel = self.fdSelect[index] + return self[index], sel + + +class SubrsIndex(GlobalSubrsIndex): + """This index contains a glyph's local subroutines. A local subroutine is a + private set of ``CharString`` data which is accessible only to the glyph to + which the index is attached.""" + + compilerClass = SubrsCompiler + + +class TopDictIndex(Index): + """This index represents the array of ``TopDict`` structures in the font + (again, usually only one entry is present). Hence the following calls are + equivalent: + + .. code:: python + + tt["CFF "].cff[0] + # + tt["CFF "].cff.topDictIndex[0] + # + + """ + + compilerClass = TopDictIndexCompiler + + def __init__(self, file=None, cff2GetGlyphOrder=None, topSize=0, isCFF2=None): + self.cff2GetGlyphOrder = cff2GetGlyphOrder + if file is not None and isCFF2: + self._isCFF2 = isCFF2 + self.items = [] + name = self.__class__.__name__ + log.log(DEBUG, "loading %s at %s", name, file.tell()) + self.file = file + count = 1 + self.items = [None] * count + self.offsets = [0, topSize] + self.offsetBase = file.tell() + # pretend we've read the whole lot + file.seek(self.offsetBase + topSize) + log.log(DEBUG, " end of %s at %s", name, file.tell()) + else: + super(TopDictIndex, self).__init__(file, isCFF2=isCFF2) + + def produceItem(self, index, data, file, offset): + top = TopDict( + self.strings, + file, + offset, + self.GlobalSubrs, + self.cff2GetGlyphOrder, + isCFF2=self._isCFF2, + ) + top.decompile(data) + return top + + def toXML(self, xmlWriter): + for i in range(len(self)): + xmlWriter.begintag("FontDict", index=i) + xmlWriter.newline() + self[i].toXML(xmlWriter) + xmlWriter.endtag("FontDict") + xmlWriter.newline() + + +class FDArrayIndex(Index): + compilerClass = FDArrayIndexCompiler + + def toXML(self, xmlWriter): + for i in range(len(self)): + xmlWriter.begintag("FontDict", index=i) + xmlWriter.newline() + self[i].toXML(xmlWriter) + xmlWriter.endtag("FontDict") + xmlWriter.newline() + + def produceItem(self, index, data, file, offset): + fontDict = FontDict( + self.strings, + file, + offset, + self.GlobalSubrs, + isCFF2=self._isCFF2, + vstore=self.vstore, + ) + fontDict.decompile(data) + return fontDict + + def fromXML(self, name, attrs, content): + if name != "FontDict": + return + fontDict = FontDict() + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + fontDict.fromXML(name, attrs, content) + self.append(fontDict) + + +class VarStoreData(object): + def __init__(self, file=None, otVarStore=None): + self.file = file + self.data = None + self.otVarStore = otVarStore + self.font = TTFont() # dummy font for the decompile function. + + def decompile(self): + if self.file: + # read data in from file. Assume position is correct. + length = readCard16(self.file) + # https://github.com/fonttools/fonttools/issues/3673 + if length == 65535: + self.data = self.file.read() + else: + self.data = self.file.read(length) + globalState = {} + reader = OTTableReader(self.data, globalState) + self.otVarStore = ot.VarStore() + self.otVarStore.decompile(reader, self.font) + self.data = None + return self + + def compile(self): + writer = OTTableWriter() + self.otVarStore.compile(writer, self.font) + # Note that this omits the initial Card16 length from the CFF2 + # VarStore data block + self.data = writer.getAllData() + + def writeXML(self, xmlWriter, name): + self.otVarStore.toXML(xmlWriter, self.font) + + def xmlRead(self, name, attrs, content, parent): + self.otVarStore = ot.VarStore() + for element in content: + if isinstance(element, tuple): + name, attrs, content = element + self.otVarStore.fromXML(name, attrs, content, self.font) + else: + pass + return None + + def __len__(self): + return len(self.data) + + def getNumRegions(self, vsIndex): + if vsIndex is None: + vsIndex = 0 + varData = self.otVarStore.VarData[vsIndex] + numRegions = varData.VarRegionCount + return numRegions + + +class FDSelect(object): + def __init__(self, file=None, numGlyphs=None, format=None): + if file: + # read data in from file + self.format = readCard8(file) + if self.format == 0: + from array import array + + self.gidArray = array("B", file.read(numGlyphs)).tolist() + elif self.format == 3: + gidArray = [None] * numGlyphs + nRanges = readCard16(file) + fd = None + prev = None + for i in range(nRanges): + first = readCard16(file) + if prev is not None: + for glyphID in range(prev, first): + gidArray[glyphID] = fd + prev = first + fd = readCard8(file) + if prev is not None: + first = readCard16(file) + for glyphID in range(prev, first): + gidArray[glyphID] = fd + self.gidArray = gidArray + elif self.format == 4: + gidArray = [None] * numGlyphs + nRanges = readCard32(file) + fd = None + prev = None + for i in range(nRanges): + first = readCard32(file) + if prev is not None: + for glyphID in range(prev, first): + gidArray[glyphID] = fd + prev = first + fd = readCard16(file) + if prev is not None: + first = readCard32(file) + for glyphID in range(prev, first): + gidArray[glyphID] = fd + self.gidArray = gidArray + else: + assert False, "unsupported FDSelect format: %s" % format + else: + # reading from XML. Make empty gidArray, and leave format as passed in. + # format is None will result in the smallest representation being used. + self.format = format + self.gidArray = [] + + def __len__(self): + return len(self.gidArray) + + def __getitem__(self, index): + return self.gidArray[index] + + def __setitem__(self, index, fdSelectValue): + self.gidArray[index] = fdSelectValue + + def append(self, fdSelectValue): + self.gidArray.append(fdSelectValue) + + +class CharStrings(object): + """The ``CharStrings`` in the font represent the instructions for drawing + each glyph. This object presents a dictionary interface to the font's + CharStrings, indexed by glyph name: + + .. code:: python + + tt["CFF "].cff[0].CharStrings["a"] + # + + See :class:`fontTools.misc.psCharStrings.T1CharString` and + :class:`fontTools.misc.psCharStrings.T2CharString` for how to decompile, + compile and interpret the glyph drawing instructions in the returned objects. + + """ + + def __init__( + self, + file, + charset, + globalSubrs, + private, + fdSelect, + fdArray, + isCFF2=None, + varStore=None, + ): + self.globalSubrs = globalSubrs + self.varStore = varStore + if file is not None: + self.charStringsIndex = SubrsIndex( + file, globalSubrs, private, fdSelect, fdArray, isCFF2=isCFF2 + ) + self.charStrings = charStrings = {} + for i in range(len(charset)): + charStrings[charset[i]] = i + # read from OTF file: charStrings.values() are indices into + # charStringsIndex. + self.charStringsAreIndexed = 1 + else: + self.charStrings = {} + # read from ttx file: charStrings.values() are actual charstrings + self.charStringsAreIndexed = 0 + self.private = private + if fdSelect is not None: + self.fdSelect = fdSelect + if fdArray is not None: + self.fdArray = fdArray + + def keys(self): + return list(self.charStrings.keys()) + + def values(self): + if self.charStringsAreIndexed: + return self.charStringsIndex + else: + return list(self.charStrings.values()) + + def has_key(self, name): + return name in self.charStrings + + __contains__ = has_key + + def __len__(self): + return len(self.charStrings) + + def __getitem__(self, name): + charString = self.charStrings[name] + if self.charStringsAreIndexed: + charString = self.charStringsIndex[charString] + return charString + + def __setitem__(self, name, charString): + if self.charStringsAreIndexed: + index = self.charStrings[name] + self.charStringsIndex[index] = charString + else: + self.charStrings[name] = charString + + def getItemAndSelector(self, name): + if self.charStringsAreIndexed: + index = self.charStrings[name] + return self.charStringsIndex.getItemAndSelector(index) + else: + if hasattr(self, "fdArray"): + if hasattr(self, "fdSelect"): + sel = self.charStrings[name].fdSelectIndex + else: + sel = 0 + else: + sel = None + return self.charStrings[name], sel + + def toXML(self, xmlWriter): + names = sorted(self.keys()) + for name in names: + charStr, fdSelectIndex = self.getItemAndSelector(name) + if charStr.needsDecompilation(): + raw = [("raw", 1)] + else: + raw = [] + if fdSelectIndex is None: + xmlWriter.begintag("CharString", [("name", name)] + raw) + else: + xmlWriter.begintag( + "CharString", + [("name", name), ("fdSelectIndex", fdSelectIndex)] + raw, + ) + xmlWriter.newline() + charStr.toXML(xmlWriter) + xmlWriter.endtag("CharString") + xmlWriter.newline() + + def fromXML(self, name, attrs, content): + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + if name != "CharString": + continue + fdID = -1 + if hasattr(self, "fdArray"): + try: + fdID = safeEval(attrs["fdSelectIndex"]) + except KeyError: + fdID = 0 + private = self.fdArray[fdID].Private + else: + private = self.private + + glyphName = attrs["name"] + charStringClass = psCharStrings.T2CharString + charString = charStringClass(private=private, globalSubrs=self.globalSubrs) + charString.fromXML(name, attrs, content) + if fdID >= 0: + charString.fdSelectIndex = fdID + self[glyphName] = charString + + +def readCard8(file): + return byteord(file.read(1)) + + +def readCard16(file): + (value,) = struct.unpack(">H", file.read(2)) + return value + + +def readCard32(file): + (value,) = struct.unpack(">L", file.read(4)) + return value + + +def writeCard8(file, value): + file.write(bytechr(value)) + + +def writeCard16(file, value): + file.write(struct.pack(">H", value)) + + +def writeCard32(file, value): + file.write(struct.pack(">L", value)) + + +def packCard8(value): + return bytechr(value) + + +def packCard16(value): + return struct.pack(">H", value) + + +def packCard32(value): + return struct.pack(">L", value) + + +def buildOperatorDict(table): + d = {} + for op, name, arg, default, conv in table: + d[op] = (name, arg) + return d + + +def buildOpcodeDict(table): + d = {} + for op, name, arg, default, conv in table: + if isinstance(op, tuple): + op = bytechr(op[0]) + bytechr(op[1]) + else: + op = bytechr(op) + d[name] = (op, arg) + return d + + +def buildOrder(table): + l = [] + for op, name, arg, default, conv in table: + l.append(name) + return l + + +def buildDefaults(table): + d = {} + for op, name, arg, default, conv in table: + if default is not None: + d[name] = default + return d + + +def buildConverters(table): + d = {} + for op, name, arg, default, conv in table: + d[name] = conv + return d + + +class SimpleConverter(object): + def read(self, parent, value): + if not hasattr(parent, "file"): + return self._read(parent, value) + file = parent.file + pos = file.tell() + try: + return self._read(parent, value) + finally: + file.seek(pos) + + def _read(self, parent, value): + return value + + def write(self, parent, value): + return value + + def xmlWrite(self, xmlWriter, name, value): + xmlWriter.simpletag(name, value=value) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + return attrs["value"] + + +class ASCIIConverter(SimpleConverter): + def _read(self, parent, value): + return tostr(value, encoding="ascii") + + def write(self, parent, value): + return tobytes(value, encoding="ascii") + + def xmlWrite(self, xmlWriter, name, value): + xmlWriter.simpletag(name, value=tostr(value, encoding="ascii")) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + return tobytes(attrs["value"], encoding=("ascii")) + + +class Latin1Converter(SimpleConverter): + def _read(self, parent, value): + return tostr(value, encoding="latin1") + + def write(self, parent, value): + return tobytes(value, encoding="latin1") + + def xmlWrite(self, xmlWriter, name, value): + value = tostr(value, encoding="latin1") + if name in ["Notice", "Copyright"]: + value = re.sub(r"[\r\n]\s+", " ", value) + xmlWriter.simpletag(name, value=value) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + return tobytes(attrs["value"], encoding=("latin1")) + + +def parseNum(s): + try: + value = int(s) + except: + value = float(s) + return value + + +def parseBlendList(s): + valueList = [] + for element in s: + if isinstance(element, str): + continue + name, attrs, content = element + blendList = attrs["value"].split() + blendList = [eval(val) for val in blendList] + valueList.append(blendList) + if len(valueList) == 1: + valueList = valueList[0] + return valueList + + +class NumberConverter(SimpleConverter): + def xmlWrite(self, xmlWriter, name, value): + if isinstance(value, list): + xmlWriter.begintag(name) + xmlWriter.newline() + xmlWriter.indent() + blendValue = " ".join([str(val) for val in value]) + xmlWriter.simpletag(kBlendDictOpName, value=blendValue) + xmlWriter.newline() + xmlWriter.dedent() + xmlWriter.endtag(name) + xmlWriter.newline() + else: + xmlWriter.simpletag(name, value=value) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + valueString = attrs.get("value", None) + if valueString is None: + value = parseBlendList(content) + else: + value = parseNum(attrs["value"]) + return value + + +class ArrayConverter(SimpleConverter): + def xmlWrite(self, xmlWriter, name, value): + if value and isinstance(value[0], list): + xmlWriter.begintag(name) + xmlWriter.newline() + xmlWriter.indent() + for valueList in value: + blendValue = " ".join([str(val) for val in valueList]) + xmlWriter.simpletag(kBlendDictOpName, value=blendValue) + xmlWriter.newline() + xmlWriter.dedent() + xmlWriter.endtag(name) + xmlWriter.newline() + else: + value = " ".join([str(val) for val in value]) + xmlWriter.simpletag(name, value=value) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + valueString = attrs.get("value", None) + if valueString is None: + valueList = parseBlendList(content) + else: + values = valueString.split() + valueList = [parseNum(value) for value in values] + return valueList + + +class TableConverter(SimpleConverter): + def xmlWrite(self, xmlWriter, name, value): + xmlWriter.begintag(name) + xmlWriter.newline() + value.toXML(xmlWriter) + xmlWriter.endtag(name) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + ob = self.getClass()() + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + ob.fromXML(name, attrs, content) + return ob + + +class PrivateDictConverter(TableConverter): + def getClass(self): + return PrivateDict + + def _read(self, parent, value): + size, offset = value + file = parent.file + isCFF2 = parent._isCFF2 + try: + vstore = parent.vstore + except AttributeError: + vstore = None + priv = PrivateDict(parent.strings, file, offset, isCFF2=isCFF2, vstore=vstore) + file.seek(offset) + data = file.read(size) + assert len(data) == size + priv.decompile(data) + return priv + + def write(self, parent, value): + return (0, 0) # dummy value + + +class SubrsConverter(TableConverter): + def getClass(self): + return SubrsIndex + + def _read(self, parent, value): + file = parent.file + isCFF2 = parent._isCFF2 + file.seek(parent.offset + value) # Offset(self) + return SubrsIndex(file, isCFF2=isCFF2) + + def write(self, parent, value): + return 0 # dummy value + + +class CharStringsConverter(TableConverter): + def _read(self, parent, value): + file = parent.file + isCFF2 = parent._isCFF2 + charset = parent.charset + varStore = getattr(parent, "VarStore", None) + globalSubrs = parent.GlobalSubrs + if hasattr(parent, "FDArray"): + fdArray = parent.FDArray + if hasattr(parent, "FDSelect"): + fdSelect = parent.FDSelect + else: + fdSelect = None + private = None + else: + fdSelect, fdArray = None, None + private = parent.Private + file.seek(value) # Offset(0) + charStrings = CharStrings( + file, + charset, + globalSubrs, + private, + fdSelect, + fdArray, + isCFF2=isCFF2, + varStore=varStore, + ) + return charStrings + + def write(self, parent, value): + return 0 # dummy value + + def xmlRead(self, name, attrs, content, parent): + if hasattr(parent, "FDArray"): + # if it is a CID-keyed font, then the private Dict is extracted from the + # parent.FDArray + fdArray = parent.FDArray + if hasattr(parent, "FDSelect"): + fdSelect = parent.FDSelect + else: + fdSelect = None + private = None + else: + # if it is a name-keyed font, then the private dict is in the top dict, + # and + # there is no fdArray. + private, fdSelect, fdArray = parent.Private, None, None + charStrings = CharStrings( + None, + None, + parent.GlobalSubrs, + private, + fdSelect, + fdArray, + varStore=getattr(parent, "VarStore", None), + ) + charStrings.fromXML(name, attrs, content) + return charStrings + + +class CharsetConverter(SimpleConverter): + def _read(self, parent, value): + isCID = hasattr(parent, "ROS") + if value > 2: + numGlyphs = parent.numGlyphs + file = parent.file + file.seek(value) + log.log(DEBUG, "loading charset at %s", value) + format = readCard8(file) + if format == 0: + charset = parseCharset0(numGlyphs, file, parent.strings, isCID) + elif format == 1 or format == 2: + charset = parseCharset(numGlyphs, file, parent.strings, isCID, format) + else: + raise NotImplementedError + assert len(charset) == numGlyphs + log.log(DEBUG, " charset end at %s", file.tell()) + # make sure glyph names are unique + allNames = {} + newCharset = [] + for glyphName in charset: + if glyphName in allNames: + # make up a new glyphName that's unique + n = allNames[glyphName] + names = set(allNames) | set(charset) + while (glyphName + "." + str(n)) in names: + n += 1 + allNames[glyphName] = n + 1 + glyphName = glyphName + "." + str(n) + allNames[glyphName] = 1 + newCharset.append(glyphName) + charset = newCharset + else: # offset == 0 -> no charset data. + if isCID or "CharStrings" not in parent.rawDict: + # We get here only when processing fontDicts from the FDArray of + # CFF-CID fonts. Only the real topDict references the charset. + assert value == 0 + charset = None + elif value == 0: + charset = cffISOAdobeStrings + elif value == 1: + charset = cffIExpertStrings + elif value == 2: + charset = cffExpertSubsetStrings + if charset and (len(charset) != parent.numGlyphs): + charset = charset[: parent.numGlyphs] + return charset + + def write(self, parent, value): + return 0 # dummy value + + def xmlWrite(self, xmlWriter, name, value): + # XXX only write charset when not in OT/TTX context, where we + # dump charset as a separate "GlyphOrder" table. + # # xmlWriter.simpletag("charset") + xmlWriter.comment("charset is dumped separately as the 'GlyphOrder' element") + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + pass + + +class CharsetCompiler(object): + def __init__(self, strings, charset, parent): + assert charset[0] == ".notdef" + isCID = hasattr(parent.dictObj, "ROS") + data0 = packCharset0(charset, isCID, strings) + data = packCharset(charset, isCID, strings) + if len(data) < len(data0): + self.data = data + else: + self.data = data0 + self.parent = parent + + def setPos(self, pos, endPos): + self.parent.rawDict["charset"] = pos + + def getDataLength(self): + return len(self.data) + + def toFile(self, file): + file.write(self.data) + + +def getStdCharSet(charset): + # check to see if we can use a predefined charset value. + predefinedCharSetVal = None + predefinedCharSets = [ + (cffISOAdobeStringCount, cffISOAdobeStrings, 0), + (cffExpertStringCount, cffIExpertStrings, 1), + (cffExpertSubsetStringCount, cffExpertSubsetStrings, 2), + ] + lcs = len(charset) + for cnt, pcs, csv in predefinedCharSets: + if predefinedCharSetVal is not None: + break + if lcs > cnt: + continue + predefinedCharSetVal = csv + for i in range(lcs): + if charset[i] != pcs[i]: + predefinedCharSetVal = None + break + return predefinedCharSetVal + + +def getCIDfromName(name, strings): + return int(name[3:]) + + +def getSIDfromName(name, strings): + return strings.getSID(name) + + +def packCharset0(charset, isCID, strings): + fmt = 0 + data = [packCard8(fmt)] + if isCID: + getNameID = getCIDfromName + else: + getNameID = getSIDfromName + + for name in charset[1:]: + data.append(packCard16(getNameID(name, strings))) + return bytesjoin(data) + + +def packCharset(charset, isCID, strings): + fmt = 1 + ranges = [] + first = None + end = 0 + if isCID: + getNameID = getCIDfromName + else: + getNameID = getSIDfromName + + for name in charset[1:]: + SID = getNameID(name, strings) + if first is None: + first = SID + elif end + 1 != SID: + nLeft = end - first + if nLeft > 255: + fmt = 2 + ranges.append((first, nLeft)) + first = SID + end = SID + if end: + nLeft = end - first + if nLeft > 255: + fmt = 2 + ranges.append((first, nLeft)) + + data = [packCard8(fmt)] + if fmt == 1: + nLeftFunc = packCard8 + else: + nLeftFunc = packCard16 + for first, nLeft in ranges: + data.append(packCard16(first) + nLeftFunc(nLeft)) + return bytesjoin(data) + + +def parseCharset0(numGlyphs, file, strings, isCID): + charset = [".notdef"] + if isCID: + for i in range(numGlyphs - 1): + CID = readCard16(file) + charset.append("cid" + str(CID).zfill(5)) + else: + for i in range(numGlyphs - 1): + SID = readCard16(file) + charset.append(strings[SID]) + return charset + + +def parseCharset(numGlyphs, file, strings, isCID, fmt): + charset = [".notdef"] + count = 1 + if fmt == 1: + nLeftFunc = readCard8 + else: + nLeftFunc = readCard16 + while count < numGlyphs: + first = readCard16(file) + nLeft = nLeftFunc(file) + if isCID: + for CID in range(first, first + nLeft + 1): + charset.append("cid" + str(CID).zfill(5)) + else: + for SID in range(first, first + nLeft + 1): + charset.append(strings[SID]) + count = count + nLeft + 1 + return charset + + +class EncodingCompiler(object): + def __init__(self, strings, encoding, parent): + assert not isinstance(encoding, str) + data0 = packEncoding0(parent.dictObj.charset, encoding, parent.strings) + data1 = packEncoding1(parent.dictObj.charset, encoding, parent.strings) + if len(data0) < len(data1): + self.data = data0 + else: + self.data = data1 + self.parent = parent + + def setPos(self, pos, endPos): + self.parent.rawDict["Encoding"] = pos + + def getDataLength(self): + return len(self.data) + + def toFile(self, file): + file.write(self.data) + + +class EncodingConverter(SimpleConverter): + def _read(self, parent, value): + if value == 0: + return "StandardEncoding" + elif value == 1: + return "ExpertEncoding" + # custom encoding at offset `value` + assert value > 1 + file = parent.file + file.seek(value) + log.log(DEBUG, "loading Encoding at %s", value) + fmt = readCard8(file) + haveSupplement = bool(fmt & 0x80) + fmt = fmt & 0x7F + + if fmt == 0: + encoding = parseEncoding0(parent.charset, file) + elif fmt == 1: + encoding = parseEncoding1(parent.charset, file) + else: + raise ValueError(f"Unknown Encoding format: {fmt}") + + if haveSupplement: + parseEncodingSupplement(file, encoding, parent.strings) + + return encoding + + def write(self, parent, value): + if value == "StandardEncoding": + return 0 + elif value == "ExpertEncoding": + return 1 + return 0 # dummy value + + def xmlWrite(self, xmlWriter, name, value): + if value in ("StandardEncoding", "ExpertEncoding"): + xmlWriter.simpletag(name, name=value) + xmlWriter.newline() + return + xmlWriter.begintag(name) + xmlWriter.newline() + for code in range(len(value)): + glyphName = value[code] + if glyphName != ".notdef": + xmlWriter.simpletag("map", code=hex(code), name=glyphName) + xmlWriter.newline() + xmlWriter.endtag(name) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + if "name" in attrs: + return attrs["name"] + encoding = [".notdef"] * 256 + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + code = safeEval(attrs["code"]) + glyphName = attrs["name"] + encoding[code] = glyphName + return encoding + + +def readSID(file): + """Read a String ID (SID) — 2-byte unsigned integer.""" + data = file.read(2) + if len(data) != 2: + raise EOFError("Unexpected end of file while reading SID") + return struct.unpack(">H", data)[0] # big-endian uint16 + + +def parseEncodingSupplement(file, encoding, strings): + """ + Parse the CFF Encoding supplement data: + - nSups: number of supplementary mappings + - each mapping: (code, SID) pair + and apply them to the `encoding` list in place. + """ + nSups = readCard8(file) + for _ in range(nSups): + code = readCard8(file) + sid = readSID(file) + name = strings[sid] + encoding[code] = name + + +def parseEncoding0(charset, file): + """ + Format 0: simple list of codes. + After reading the base table, optionally parse the supplement. + """ + nCodes = readCard8(file) + encoding = [".notdef"] * 256 + for glyphID in range(1, nCodes + 1): + code = readCard8(file) + if code != 0: + encoding[code] = charset[glyphID] + + return encoding + + +def parseEncoding1(charset, file): + """ + Format 1: range-based encoding. + After reading the base ranges, optionally parse the supplement. + """ + nRanges = readCard8(file) + encoding = [".notdef"] * 256 + glyphID = 1 + for _ in range(nRanges): + code = readCard8(file) + nLeft = readCard8(file) + for _ in range(nLeft + 1): + encoding[code] = charset[glyphID] + code += 1 + glyphID += 1 + + return encoding + + +def packEncoding0(charset, encoding, strings): + fmt = 0 + m = {} + for code in range(len(encoding)): + name = encoding[code] + if name != ".notdef": + m[name] = code + codes = [] + for name in charset[1:]: + code = m.get(name) + codes.append(code) + + while codes and codes[-1] is None: + codes.pop() + + data = [packCard8(fmt), packCard8(len(codes))] + for code in codes: + if code is None: + code = 0 + data.append(packCard8(code)) + return bytesjoin(data) + + +def packEncoding1(charset, encoding, strings): + fmt = 1 + m = {} + for code in range(len(encoding)): + name = encoding[code] + if name != ".notdef": + m[name] = code + ranges = [] + first = None + end = 0 + for name in charset[1:]: + code = m.get(name, -1) + if first is None: + first = code + elif end + 1 != code: + nLeft = end - first + ranges.append((first, nLeft)) + first = code + end = code + nLeft = end - first + ranges.append((first, nLeft)) + + # remove unencoded glyphs at the end. + while ranges and ranges[-1][0] == -1: + ranges.pop() + + data = [packCard8(fmt), packCard8(len(ranges))] + for first, nLeft in ranges: + if first == -1: # unencoded + first = 0 + data.append(packCard8(first) + packCard8(nLeft)) + return bytesjoin(data) + + +class FDArrayConverter(TableConverter): + def _read(self, parent, value): + try: + vstore = parent.VarStore + except AttributeError: + vstore = None + file = parent.file + isCFF2 = parent._isCFF2 + file.seek(value) + fdArray = FDArrayIndex(file, isCFF2=isCFF2) + fdArray.vstore = vstore + fdArray.strings = parent.strings + fdArray.GlobalSubrs = parent.GlobalSubrs + return fdArray + + def write(self, parent, value): + return 0 # dummy value + + def xmlRead(self, name, attrs, content, parent): + fdArray = FDArrayIndex() + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + fdArray.fromXML(name, attrs, content) + return fdArray + + +class FDSelectConverter(SimpleConverter): + def _read(self, parent, value): + file = parent.file + file.seek(value) + fdSelect = FDSelect(file, parent.numGlyphs) + return fdSelect + + def write(self, parent, value): + return 0 # dummy value + + # The FDSelect glyph data is written out to XML in the charstring keys, + # so we write out only the format selector + def xmlWrite(self, xmlWriter, name, value): + xmlWriter.simpletag(name, [("format", value.format)]) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + fmt = safeEval(attrs["format"]) + file = None + numGlyphs = None + fdSelect = FDSelect(file, numGlyphs, fmt) + return fdSelect + + +class VarStoreConverter(SimpleConverter): + def _read(self, parent, value): + file = parent.file + file.seek(value) + varStore = VarStoreData(file) + varStore.decompile() + return varStore + + def write(self, parent, value): + return 0 # dummy value + + def xmlWrite(self, xmlWriter, name, value): + value.writeXML(xmlWriter, name) + + def xmlRead(self, name, attrs, content, parent): + varStore = VarStoreData() + varStore.xmlRead(name, attrs, content, parent) + return varStore + + +def packFDSelect0(fdSelectArray): + fmt = 0 + data = [packCard8(fmt)] + for index in fdSelectArray: + data.append(packCard8(index)) + return bytesjoin(data) + + +def packFDSelect3(fdSelectArray): + fmt = 3 + fdRanges = [] + lenArray = len(fdSelectArray) + lastFDIndex = -1 + for i in range(lenArray): + fdIndex = fdSelectArray[i] + if lastFDIndex != fdIndex: + fdRanges.append([i, fdIndex]) + lastFDIndex = fdIndex + sentinelGID = i + 1 + + data = [packCard8(fmt)] + data.append(packCard16(len(fdRanges))) + for fdRange in fdRanges: + data.append(packCard16(fdRange[0])) + data.append(packCard8(fdRange[1])) + data.append(packCard16(sentinelGID)) + return bytesjoin(data) + + +def packFDSelect4(fdSelectArray): + fmt = 4 + fdRanges = [] + lenArray = len(fdSelectArray) + lastFDIndex = -1 + for i in range(lenArray): + fdIndex = fdSelectArray[i] + if lastFDIndex != fdIndex: + fdRanges.append([i, fdIndex]) + lastFDIndex = fdIndex + sentinelGID = i + 1 + + data = [packCard8(fmt)] + data.append(packCard32(len(fdRanges))) + for fdRange in fdRanges: + data.append(packCard32(fdRange[0])) + data.append(packCard16(fdRange[1])) + data.append(packCard32(sentinelGID)) + return bytesjoin(data) + + +class FDSelectCompiler(object): + def __init__(self, fdSelect, parent): + fmt = fdSelect.format + fdSelectArray = fdSelect.gidArray + if fmt == 0: + self.data = packFDSelect0(fdSelectArray) + elif fmt == 3: + self.data = packFDSelect3(fdSelectArray) + elif fmt == 4: + self.data = packFDSelect4(fdSelectArray) + else: + # choose smaller of the two formats + data0 = packFDSelect0(fdSelectArray) + data3 = packFDSelect3(fdSelectArray) + if len(data0) < len(data3): + self.data = data0 + fdSelect.format = 0 + else: + self.data = data3 + fdSelect.format = 3 + + self.parent = parent + + def setPos(self, pos, endPos): + self.parent.rawDict["FDSelect"] = pos + + def getDataLength(self): + return len(self.data) + + def toFile(self, file): + file.write(self.data) + + +class VarStoreCompiler(object): + def __init__(self, varStoreData, parent): + self.parent = parent + if not varStoreData.data: + varStoreData.compile() + varStoreDataLen = min(0xFFFF, len(varStoreData.data)) + data = [packCard16(varStoreDataLen), varStoreData.data] + self.data = bytesjoin(data) + + def setPos(self, pos, endPos): + self.parent.rawDict["VarStore"] = pos + + def getDataLength(self): + return len(self.data) + + def toFile(self, file): + file.write(self.data) + + +class ROSConverter(SimpleConverter): + def xmlWrite(self, xmlWriter, name, value): + registry, order, supplement = value + xmlWriter.simpletag( + name, + [ + ("Registry", tostr(registry)), + ("Order", tostr(order)), + ("Supplement", supplement), + ], + ) + xmlWriter.newline() + + def xmlRead(self, name, attrs, content, parent): + return (attrs["Registry"], attrs["Order"], safeEval(attrs["Supplement"])) + + +topDictOperators = [ + # opcode name argument type default converter + (25, "maxstack", "number", None, None), + ((12, 30), "ROS", ("SID", "SID", "number"), None, ROSConverter()), + ((12, 20), "SyntheticBase", "number", None, None), + (0, "version", "SID", None, None), + (1, "Notice", "SID", None, Latin1Converter()), + ((12, 0), "Copyright", "SID", None, Latin1Converter()), + (2, "FullName", "SID", None, Latin1Converter()), + ((12, 38), "FontName", "SID", None, Latin1Converter()), + (3, "FamilyName", "SID", None, Latin1Converter()), + (4, "Weight", "SID", None, None), + ((12, 1), "isFixedPitch", "number", 0, None), + ((12, 2), "ItalicAngle", "number", 0, None), + ((12, 3), "UnderlinePosition", "number", -100, None), + ((12, 4), "UnderlineThickness", "number", 50, None), + ((12, 5), "PaintType", "number", 0, None), + ((12, 6), "CharstringType", "number", 2, None), + ((12, 7), "FontMatrix", "array", [0.001, 0, 0, 0.001, 0, 0], None), + (13, "UniqueID", "number", None, None), + (5, "FontBBox", "array", [0, 0, 0, 0], None), + ((12, 8), "StrokeWidth", "number", 0, None), + (14, "XUID", "array", None, None), + ((12, 21), "PostScript", "SID", None, None), + ((12, 22), "BaseFontName", "SID", None, None), + ((12, 23), "BaseFontBlend", "delta", None, None), + ((12, 31), "CIDFontVersion", "number", 0, None), + ((12, 32), "CIDFontRevision", "number", 0, None), + ((12, 33), "CIDFontType", "number", 0, None), + ((12, 34), "CIDCount", "number", 8720, None), + (15, "charset", "number", None, CharsetConverter()), + ((12, 35), "UIDBase", "number", None, None), + (16, "Encoding", "number", 0, EncodingConverter()), + (18, "Private", ("number", "number"), None, PrivateDictConverter()), + ((12, 37), "FDSelect", "number", None, FDSelectConverter()), + ((12, 36), "FDArray", "number", None, FDArrayConverter()), + (17, "CharStrings", "number", None, CharStringsConverter()), + (24, "VarStore", "number", None, VarStoreConverter()), +] + +topDictOperators2 = [ + # opcode name argument type default converter + (25, "maxstack", "number", None, None), + ((12, 7), "FontMatrix", "array", [0.001, 0, 0, 0.001, 0, 0], None), + ((12, 37), "FDSelect", "number", None, FDSelectConverter()), + ((12, 36), "FDArray", "number", None, FDArrayConverter()), + (17, "CharStrings", "number", None, CharStringsConverter()), + (24, "VarStore", "number", None, VarStoreConverter()), +] + +# Note! FDSelect and FDArray must both preceed CharStrings in the output XML build order, +# in order for the font to compile back from xml. + +kBlendDictOpName = "blend" +blendOp = 23 + +privateDictOperators = [ + # opcode name argument type default converter + (22, "vsindex", "number", None, None), + ( + blendOp, + kBlendDictOpName, + "blendList", + None, + None, + ), # This is for reading to/from XML: it not written to CFF. + (6, "BlueValues", "delta", None, None), + (7, "OtherBlues", "delta", None, None), + (8, "FamilyBlues", "delta", None, None), + (9, "FamilyOtherBlues", "delta", None, None), + ((12, 9), "BlueScale", "number", 0.039625, None), + ((12, 10), "BlueShift", "number", 7, None), + ((12, 11), "BlueFuzz", "number", 1, None), + (10, "StdHW", "number", None, None), + (11, "StdVW", "number", None, None), + ((12, 12), "StemSnapH", "delta", None, None), + ((12, 13), "StemSnapV", "delta", None, None), + ((12, 14), "ForceBold", "number", 0, None), + ((12, 15), "ForceBoldThreshold", "number", None, None), # deprecated + ((12, 16), "lenIV", "number", None, None), # deprecated + ((12, 17), "LanguageGroup", "number", 0, None), + ((12, 18), "ExpansionFactor", "number", 0.06, None), + ((12, 19), "initialRandomSeed", "number", 0, None), + (20, "defaultWidthX", "number", 0, None), + (21, "nominalWidthX", "number", 0, None), + (19, "Subrs", "number", None, SubrsConverter()), +] + +privateDictOperators2 = [ + # opcode name argument type default converter + (22, "vsindex", "number", None, None), + ( + blendOp, + kBlendDictOpName, + "blendList", + None, + None, + ), # This is for reading to/from XML: it not written to CFF. + (6, "BlueValues", "delta", None, None), + (7, "OtherBlues", "delta", None, None), + (8, "FamilyBlues", "delta", None, None), + (9, "FamilyOtherBlues", "delta", None, None), + ((12, 9), "BlueScale", "number", 0.039625, None), + ((12, 10), "BlueShift", "number", 7, None), + ((12, 11), "BlueFuzz", "number", 1, None), + (10, "StdHW", "number", None, None), + (11, "StdVW", "number", None, None), + ((12, 12), "StemSnapH", "delta", None, None), + ((12, 13), "StemSnapV", "delta", None, None), + ((12, 17), "LanguageGroup", "number", 0, None), + ((12, 18), "ExpansionFactor", "number", 0.06, None), + (19, "Subrs", "number", None, SubrsConverter()), +] + + +def addConverters(table): + for i in range(len(table)): + op, name, arg, default, conv = table[i] + if conv is not None: + continue + if arg in ("delta", "array"): + conv = ArrayConverter() + elif arg == "number": + conv = NumberConverter() + elif arg == "SID": + conv = ASCIIConverter() + elif arg == "blendList": + conv = None + else: + assert False + table[i] = op, name, arg, default, conv + + +addConverters(privateDictOperators) +addConverters(topDictOperators) + + +class TopDictDecompiler(psCharStrings.DictDecompiler): + operators = buildOperatorDict(topDictOperators) + + +class PrivateDictDecompiler(psCharStrings.DictDecompiler): + operators = buildOperatorDict(privateDictOperators) + + +class DictCompiler(object): + maxBlendStack = 0 + + def __init__(self, dictObj, strings, parent, isCFF2=None): + if strings: + assert isinstance(strings, IndexedStrings) + if isCFF2 is None and hasattr(parent, "isCFF2"): + isCFF2 = parent.isCFF2 + assert isCFF2 is not None + self.isCFF2 = isCFF2 + self.dictObj = dictObj + self.strings = strings + self.parent = parent + rawDict = {} + for name in dictObj.order: + value = getattr(dictObj, name, None) + if value is None: + continue + conv = dictObj.converters[name] + value = conv.write(dictObj, value) + if value == dictObj.defaults.get(name): + continue + rawDict[name] = value + self.rawDict = rawDict + + def setPos(self, pos, endPos): + pass + + def getDataLength(self): + return len(self.compile("getDataLength")) + + def compile(self, reason): + log.log(DEBUG, "-- compiling %s for %s", self.__class__.__name__, reason) + rawDict = self.rawDict + data = [] + for name in self.dictObj.order: + value = rawDict.get(name) + if value is None: + continue + op, argType = self.opcodes[name] + if isinstance(argType, tuple): + l = len(argType) + assert len(value) == l, "value doesn't match arg type" + for i in range(l): + arg = argType[i] + v = value[i] + arghandler = getattr(self, "arg_" + arg) + data.append(arghandler(v)) + else: + arghandler = getattr(self, "arg_" + argType) + data.append(arghandler(value)) + data.append(op) + data = bytesjoin(data) + return data + + def toFile(self, file): + data = self.compile("toFile") + file.write(data) + + def arg_number(self, num): + if isinstance(num, list): + data = [encodeNumber(val) for val in num] + data.append(encodeNumber(1)) + data.append(bytechr(blendOp)) + datum = bytesjoin(data) + else: + datum = encodeNumber(num) + return datum + + def arg_SID(self, s): + return psCharStrings.encodeIntCFF(self.strings.getSID(s)) + + def arg_array(self, value): + data = [] + for num in value: + data.append(self.arg_number(num)) + return bytesjoin(data) + + def arg_delta(self, value): + if not value: + return b"" + val0 = value[0] + if isinstance(val0, list): + data = self.arg_delta_blend(value) + else: + out = [] + last = 0 + for v in value: + out.append(v - last) + last = v + data = [] + for num in out: + data.append(encodeNumber(num)) + return bytesjoin(data) + + def arg_delta_blend(self, value): + """A delta list with blend lists has to be *all* blend lists. + + The value is a list is arranged as follows:: + + [ + [V0, d0..dn] + [V1, d0..dn] + ... + [Vm, d0..dn] + ] + + ``V`` is the absolute coordinate value from the default font, and ``d0-dn`` + are the delta values from the *n* regions. Each ``V`` is an absolute + coordinate from the default font. + + We want to return a list:: + + [ + [v0, v1..vm] + [d0..dn] + ... + [d0..dn] + numBlends + blendOp + ] + + where each ``v`` is relative to the previous default font value. + """ + numMasters = len(value[0]) + numBlends = len(value) + numStack = (numBlends * numMasters) + 1 + if numStack > self.maxBlendStack: + # Figure out the max number of value we can blend + # and divide this list up into chunks of that size. + + numBlendValues = int((self.maxBlendStack - 1) / numMasters) + out = [] + while True: + numVal = min(len(value), numBlendValues) + if numVal == 0: + break + valList = value[0:numVal] + out1 = self.arg_delta_blend(valList) + out.extend(out1) + value = value[numVal:] + else: + firstList = [0] * numBlends + deltaList = [None] * numBlends + i = 0 + prevVal = 0 + while i < numBlends: + # For PrivateDict BlueValues, the default font + # values are absolute, not relative. + # Must convert these back to relative coordinates + # before writing to CFF2. + defaultValue = value[i][0] + firstList[i] = defaultValue - prevVal + prevVal = defaultValue + deltaList[i] = value[i][1:] + i += 1 + + relValueList = firstList + for blendList in deltaList: + relValueList.extend(blendList) + out = [encodeNumber(val) for val in relValueList] + out.append(encodeNumber(numBlends)) + out.append(bytechr(blendOp)) + return out + + +def encodeNumber(num): + if isinstance(num, float): + return psCharStrings.encodeFloat(num) + else: + return psCharStrings.encodeIntCFF(num) + + +class TopDictCompiler(DictCompiler): + opcodes = buildOpcodeDict(topDictOperators) + + def getChildren(self, strings): + isCFF2 = self.isCFF2 + children = [] + if self.dictObj.cff2GetGlyphOrder is None: + if hasattr(self.dictObj, "charset") and self.dictObj.charset: + if hasattr(self.dictObj, "ROS"): # aka isCID + charsetCode = None + else: + charsetCode = getStdCharSet(self.dictObj.charset) + if charsetCode is None: + children.append( + CharsetCompiler(strings, self.dictObj.charset, self) + ) + else: + self.rawDict["charset"] = charsetCode + if hasattr(self.dictObj, "Encoding") and self.dictObj.Encoding: + encoding = self.dictObj.Encoding + if not isinstance(encoding, str): + children.append(EncodingCompiler(strings, encoding, self)) + else: + if hasattr(self.dictObj, "VarStore"): + varStoreData = self.dictObj.VarStore + varStoreComp = VarStoreCompiler(varStoreData, self) + children.append(varStoreComp) + if hasattr(self.dictObj, "FDSelect"): + # I have not yet supported merging a ttx CFF-CID font, as there are + # interesting issues about merging the FDArrays. Here I assume that + # either the font was read from XML, and the FDSelect indices are all + # in the charstring data, or the FDSelect array is already fully defined. + fdSelect = self.dictObj.FDSelect + # probably read in from XML; assume fdIndex in CharString data + if len(fdSelect) == 0: + charStrings = self.dictObj.CharStrings + for name in self.dictObj.charset: + fdSelect.append(charStrings[name].fdSelectIndex) + fdSelectComp = FDSelectCompiler(fdSelect, self) + children.append(fdSelectComp) + if hasattr(self.dictObj, "CharStrings"): + items = [] + charStrings = self.dictObj.CharStrings + for name in self.dictObj.charset: + items.append(charStrings[name]) + charStringsComp = CharStringsCompiler(items, strings, self, isCFF2=isCFF2) + children.append(charStringsComp) + if hasattr(self.dictObj, "FDArray"): + # I have not yet supported merging a ttx CFF-CID font, as there are + # interesting issues about merging the FDArrays. Here I assume that the + # FDArray info is correct and complete. + fdArrayIndexComp = self.dictObj.FDArray.getCompiler(strings, self) + children.append(fdArrayIndexComp) + children.extend(fdArrayIndexComp.getChildren(strings)) + if hasattr(self.dictObj, "Private"): + privComp = self.dictObj.Private.getCompiler(strings, self) + children.append(privComp) + children.extend(privComp.getChildren(strings)) + return children + + +class FontDictCompiler(DictCompiler): + opcodes = buildOpcodeDict(topDictOperators) + + def __init__(self, dictObj, strings, parent, isCFF2=None): + super(FontDictCompiler, self).__init__(dictObj, strings, parent, isCFF2=isCFF2) + # + # We now take some effort to detect if there were any key/value pairs + # supplied that were ignored in the FontDict context, and issue a warning + # for those cases. + # + ignoredNames = [] + dictObj = self.dictObj + for name in sorted(set(dictObj.converters) - set(dictObj.order)): + if name in dictObj.rawDict: + # The font was directly read from binary. In this + # case, we want to report *all* "useless" key/value + # pairs that are in the font, not just the ones that + # are different from the default. + ignoredNames.append(name) + else: + # The font was probably read from a TTX file. We only + # warn about keys whos value is not the default. The + # ones that have the default value will not be written + # to binary anyway. + default = dictObj.defaults.get(name) + if default is not None: + conv = dictObj.converters[name] + default = conv.read(dictObj, default) + if getattr(dictObj, name, None) != default: + ignoredNames.append(name) + if ignoredNames: + log.warning( + "Some CFF FDArray/FontDict keys were ignored upon compile: " + + " ".join(sorted(ignoredNames)) + ) + + def getChildren(self, strings): + children = [] + if hasattr(self.dictObj, "Private"): + privComp = self.dictObj.Private.getCompiler(strings, self) + children.append(privComp) + children.extend(privComp.getChildren(strings)) + return children + + +class PrivateDictCompiler(DictCompiler): + maxBlendStack = maxStackLimit + opcodes = buildOpcodeDict(privateDictOperators) + + def setPos(self, pos, endPos): + size = endPos - pos + self.parent.rawDict["Private"] = size, pos + self.pos = pos + + def getChildren(self, strings): + children = [] + if hasattr(self.dictObj, "Subrs"): + children.append(self.dictObj.Subrs.getCompiler(strings, self)) + return children + + +class BaseDict(object): + def __init__(self, strings=None, file=None, offset=None, isCFF2=None): + assert (isCFF2 is None) == (file is None) + self.rawDict = {} + self.skipNames = [] + self.strings = strings + if file is None: + return + self._isCFF2 = isCFF2 + self.file = file + if offset is not None: + log.log(DEBUG, "loading %s at %s", self.__class__.__name__, offset) + self.offset = offset + + def decompile(self, data): + log.log(DEBUG, " length %s is %d", self.__class__.__name__, len(data)) + dec = self.decompilerClass(self.strings, self) + dec.decompile(data) + self.rawDict = dec.getDict() + self.postDecompile() + + def postDecompile(self): + pass + + def getCompiler(self, strings, parent, isCFF2=None): + return self.compilerClass(self, strings, parent, isCFF2=isCFF2) + + def __getattr__(self, name): + if name[:2] == name[-2:] == "__": + # to make deepcopy() and pickle.load() work, we need to signal with + # AttributeError that dunder methods like '__deepcopy__' or '__getstate__' + # aren't implemented. For more details, see: + # https://github.com/fonttools/fonttools/pull/1488 + raise AttributeError(name) + value = self.rawDict.get(name, None) + if value is None: + value = self.defaults.get(name) + if value is None: + raise AttributeError(name) + conv = self.converters[name] + value = conv.read(self, value) + setattr(self, name, value) + return value + + def toXML(self, xmlWriter): + for name in self.order: + if name in self.skipNames: + continue + value = getattr(self, name, None) + # XXX For "charset" we never skip calling xmlWrite even if the + # value is None, so we always write the following XML comment: + # + # + # + # Charset is None when 'CFF ' table is imported from XML into an + # empty TTFont(). By writing this comment all the time, we obtain + # the same XML output whether roundtripping XML-to-XML or + # dumping binary-to-XML + if value is None and name != "charset": + continue + conv = self.converters[name] + conv.xmlWrite(xmlWriter, name, value) + ignoredNames = set(self.rawDict) - set(self.order) + if ignoredNames: + xmlWriter.comment( + "some keys were ignored: %s" % " ".join(sorted(ignoredNames)) + ) + xmlWriter.newline() + + def fromXML(self, name, attrs, content): + conv = self.converters[name] + value = conv.xmlRead(name, attrs, content, self) + setattr(self, name, value) + + +class TopDict(BaseDict): + """The ``TopDict`` represents the top-level dictionary holding font + information. CFF2 tables contain a restricted set of top-level entries + as described `here `_, + but CFF tables may contain a wider range of information. This information + can be accessed through attributes or through the dictionary returned + through the ``rawDict`` property: + + .. code:: python + + font = tt["CFF "].cff[0] + font.FamilyName + # 'Linux Libertine O' + font.rawDict["FamilyName"] + # 'Linux Libertine O' + + More information is available in the CFF file's private dictionary, accessed + via the ``Private`` property: + + .. code:: python + + tt["CFF "].cff[0].Private.BlueValues + # [-15, 0, 515, 515, 666, 666] + + """ + + defaults = buildDefaults(topDictOperators) + converters = buildConverters(topDictOperators) + compilerClass = TopDictCompiler + order = buildOrder(topDictOperators) + decompilerClass = TopDictDecompiler + + def __init__( + self, + strings=None, + file=None, + offset=None, + GlobalSubrs=None, + cff2GetGlyphOrder=None, + isCFF2=None, + ): + super(TopDict, self).__init__(strings, file, offset, isCFF2=isCFF2) + self.cff2GetGlyphOrder = cff2GetGlyphOrder + self.GlobalSubrs = GlobalSubrs + if isCFF2: + self.defaults = buildDefaults(topDictOperators2) + self.charset = cff2GetGlyphOrder() + self.order = buildOrder(topDictOperators2) + else: + self.defaults = buildDefaults(topDictOperators) + self.order = buildOrder(topDictOperators) + + def getGlyphOrder(self): + """Returns a list of glyph names in the CFF font.""" + return self.charset + + def postDecompile(self): + offset = self.rawDict.get("CharStrings") + if offset is None: + return + # get the number of glyphs beforehand. + self.file.seek(offset) + if self._isCFF2: + self.numGlyphs = readCard32(self.file) + else: + self.numGlyphs = readCard16(self.file) + + def toXML(self, xmlWriter): + if hasattr(self, "CharStrings"): + self.decompileAllCharStrings() + if hasattr(self, "ROS"): + self.skipNames = ["Encoding"] + if not hasattr(self, "ROS") or not hasattr(self, "CharStrings"): + # these values have default values, but I only want them to show up + # in CID fonts. + self.skipNames = [ + "CIDFontVersion", + "CIDFontRevision", + "CIDFontType", + "CIDCount", + ] + BaseDict.toXML(self, xmlWriter) + + def decompileAllCharStrings(self): + # Make sure that all the Private Dicts have been instantiated. + for i, charString in enumerate(self.CharStrings.values()): + try: + charString.decompile() + except: + log.error("Error in charstring %s", i) + raise + + def recalcFontBBox(self): + fontBBox = None + for charString in self.CharStrings.values(): + bounds = charString.calcBounds(self.CharStrings) + if bounds is not None: + if fontBBox is not None: + fontBBox = unionRect(fontBBox, bounds) + else: + fontBBox = bounds + + if fontBBox is None: + self.FontBBox = self.defaults["FontBBox"][:] + else: + self.FontBBox = list(intRect(fontBBox)) + + +class FontDict(BaseDict): + # + # Since fonttools used to pass a lot of fields that are not relevant in the FDArray + # FontDict, there are 'ttx' files in the wild that contain all these. These got in + # the ttx files because fonttools writes explicit values for all the TopDict default + # values. These are not actually illegal in the context of an FDArray FontDict - you + # can legally, per spec, put any arbitrary key/value pair in a FontDict - but are + # useless since current major company CFF interpreters ignore anything but the set + # listed in this file. So, we just silently skip them. An exception is Weight: this + # is not used by any interpreter, but some foundries have asked that this be + # supported in FDArray FontDicts just to preserve information about the design when + # the font is being inspected. + # + # On top of that, there are fonts out there that contain such useless FontDict values. + # + # By subclassing TopDict, we *allow* all key/values from TopDict, both when reading + # from binary or when reading from XML, but by overriding `order` with a limited + # list of names, we ensure that only the useful names ever get exported to XML and + # ever get compiled into the binary font. + # + # We override compilerClass so we can warn about "useless" key/value pairs, either + # from the original binary font or from TTX input. + # + # See: + # - https://github.com/fonttools/fonttools/issues/740 + # - https://github.com/fonttools/fonttools/issues/601 + # - https://github.com/adobe-type-tools/afdko/issues/137 + # + defaults = {} + converters = buildConverters(topDictOperators) + compilerClass = FontDictCompiler + orderCFF = ["FontName", "FontMatrix", "Weight", "Private"] + orderCFF2 = ["Private"] + decompilerClass = TopDictDecompiler + + def __init__( + self, + strings=None, + file=None, + offset=None, + GlobalSubrs=None, + isCFF2=None, + vstore=None, + ): + super(FontDict, self).__init__(strings, file, offset, isCFF2=isCFF2) + self.vstore = vstore + self.setCFF2(isCFF2) + + def setCFF2(self, isCFF2): + # isCFF2 may be None. + if isCFF2: + self.order = self.orderCFF2 + self._isCFF2 = True + else: + self.order = self.orderCFF + self._isCFF2 = False + + +class PrivateDict(BaseDict): + defaults = buildDefaults(privateDictOperators) + converters = buildConverters(privateDictOperators) + order = buildOrder(privateDictOperators) + decompilerClass = PrivateDictDecompiler + compilerClass = PrivateDictCompiler + + def __init__(self, strings=None, file=None, offset=None, isCFF2=None, vstore=None): + super(PrivateDict, self).__init__(strings, file, offset, isCFF2=isCFF2) + self.vstore = vstore + if isCFF2: + self.defaults = buildDefaults(privateDictOperators2) + self.order = buildOrder(privateDictOperators2) + # Provide dummy values. This avoids needing to provide + # an isCFF2 state in a lot of places. + self.nominalWidthX = self.defaultWidthX = None + self._isCFF2 = True + else: + self.defaults = buildDefaults(privateDictOperators) + self.order = buildOrder(privateDictOperators) + self._isCFF2 = False + + @property + def in_cff2(self): + return self._isCFF2 + + def getNumRegions(self, vi=None): # called from misc/psCharStrings.py + # if getNumRegions is being called, we can assume that VarStore exists. + if vi is None: + if hasattr(self, "vsindex"): + vi = self.vsindex + else: + vi = 0 + numRegions = self.vstore.getNumRegions(vi) + return numRegions + + +class IndexedStrings(object): + """SID -> string mapping.""" + + def __init__(self, file=None): + if file is None: + strings = [] + else: + strings = [tostr(s, encoding="latin1") for s in Index(file, isCFF2=False)] + self.strings = strings + + def getCompiler(self): + return IndexedStringsCompiler(self, None, self, isCFF2=False) + + def __len__(self): + return len(self.strings) + + def __getitem__(self, SID): + if SID < cffStandardStringCount: + return cffStandardStrings[SID] + else: + return self.strings[SID - cffStandardStringCount] + + def getSID(self, s): + if not hasattr(self, "stringMapping"): + self.buildStringMapping() + s = tostr(s, encoding="latin1") + if s in cffStandardStringMapping: + SID = cffStandardStringMapping[s] + elif s in self.stringMapping: + SID = self.stringMapping[s] + else: + SID = len(self.strings) + cffStandardStringCount + self.strings.append(s) + self.stringMapping[s] = SID + return SID + + def getStrings(self): + return self.strings + + def buildStringMapping(self): + self.stringMapping = {} + for index in range(len(self.strings)): + self.stringMapping[self.strings[index]] = index + cffStandardStringCount + + +# The 391 Standard Strings as used in the CFF format. +# from Adobe Technical None #5176, version 1.0, 18 March 1998 + +cffStandardStrings = [ + ".notdef", + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quoteright", + "parenleft", + "parenright", + "asterisk", + "plus", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "bracketleft", + "backslash", + "bracketright", + "asciicircum", + "underscore", + "quoteleft", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "braceleft", + "bar", + "braceright", + "asciitilde", + "exclamdown", + "cent", + "sterling", + "fraction", + "yen", + "florin", + "section", + "currency", + "quotesingle", + "quotedblleft", + "guillemotleft", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + "endash", + "dagger", + "daggerdbl", + "periodcentered", + "paragraph", + "bullet", + "quotesinglbase", + "quotedblbase", + "quotedblright", + "guillemotright", + "ellipsis", + "perthousand", + "questiondown", + "grave", + "acute", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "dieresis", + "ring", + "cedilla", + "hungarumlaut", + "ogonek", + "caron", + "emdash", + "AE", + "ordfeminine", + "Lslash", + "Oslash", + "OE", + "ordmasculine", + "ae", + "dotlessi", + "lslash", + "oslash", + "oe", + "germandbls", + "onesuperior", + "logicalnot", + "mu", + "trademark", + "Eth", + "onehalf", + "plusminus", + "Thorn", + "onequarter", + "divide", + "brokenbar", + "degree", + "thorn", + "threequarters", + "twosuperior", + "registered", + "minus", + "eth", + "multiply", + "threesuperior", + "copyright", + "Aacute", + "Acircumflex", + "Adieresis", + "Agrave", + "Aring", + "Atilde", + "Ccedilla", + "Eacute", + "Ecircumflex", + "Edieresis", + "Egrave", + "Iacute", + "Icircumflex", + "Idieresis", + "Igrave", + "Ntilde", + "Oacute", + "Ocircumflex", + "Odieresis", + "Ograve", + "Otilde", + "Scaron", + "Uacute", + "Ucircumflex", + "Udieresis", + "Ugrave", + "Yacute", + "Ydieresis", + "Zcaron", + "aacute", + "acircumflex", + "adieresis", + "agrave", + "aring", + "atilde", + "ccedilla", + "eacute", + "ecircumflex", + "edieresis", + "egrave", + "iacute", + "icircumflex", + "idieresis", + "igrave", + "ntilde", + "oacute", + "ocircumflex", + "odieresis", + "ograve", + "otilde", + "scaron", + "uacute", + "ucircumflex", + "udieresis", + "ugrave", + "yacute", + "ydieresis", + "zcaron", + "exclamsmall", + "Hungarumlautsmall", + "dollaroldstyle", + "dollarsuperior", + "ampersandsmall", + "Acutesmall", + "parenleftsuperior", + "parenrightsuperior", + "twodotenleader", + "onedotenleader", + "zerooldstyle", + "oneoldstyle", + "twooldstyle", + "threeoldstyle", + "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", + "sevenoldstyle", + "eightoldstyle", + "nineoldstyle", + "commasuperior", + "threequartersemdash", + "periodsuperior", + "questionsmall", + "asuperior", + "bsuperior", + "centsuperior", + "dsuperior", + "esuperior", + "isuperior", + "lsuperior", + "msuperior", + "nsuperior", + "osuperior", + "rsuperior", + "ssuperior", + "tsuperior", + "ff", + "ffi", + "ffl", + "parenleftinferior", + "parenrightinferior", + "Circumflexsmall", + "hyphensuperior", + "Gravesmall", + "Asmall", + "Bsmall", + "Csmall", + "Dsmall", + "Esmall", + "Fsmall", + "Gsmall", + "Hsmall", + "Ismall", + "Jsmall", + "Ksmall", + "Lsmall", + "Msmall", + "Nsmall", + "Osmall", + "Psmall", + "Qsmall", + "Rsmall", + "Ssmall", + "Tsmall", + "Usmall", + "Vsmall", + "Wsmall", + "Xsmall", + "Ysmall", + "Zsmall", + "colonmonetary", + "onefitted", + "rupiah", + "Tildesmall", + "exclamdownsmall", + "centoldstyle", + "Lslashsmall", + "Scaronsmall", + "Zcaronsmall", + "Dieresissmall", + "Brevesmall", + "Caronsmall", + "Dotaccentsmall", + "Macronsmall", + "figuredash", + "hypheninferior", + "Ogoneksmall", + "Ringsmall", + "Cedillasmall", + "questiondownsmall", + "oneeighth", + "threeeighths", + "fiveeighths", + "seveneighths", + "onethird", + "twothirds", + "zerosuperior", + "foursuperior", + "fivesuperior", + "sixsuperior", + "sevensuperior", + "eightsuperior", + "ninesuperior", + "zeroinferior", + "oneinferior", + "twoinferior", + "threeinferior", + "fourinferior", + "fiveinferior", + "sixinferior", + "seveninferior", + "eightinferior", + "nineinferior", + "centinferior", + "dollarinferior", + "periodinferior", + "commainferior", + "Agravesmall", + "Aacutesmall", + "Acircumflexsmall", + "Atildesmall", + "Adieresissmall", + "Aringsmall", + "AEsmall", + "Ccedillasmall", + "Egravesmall", + "Eacutesmall", + "Ecircumflexsmall", + "Edieresissmall", + "Igravesmall", + "Iacutesmall", + "Icircumflexsmall", + "Idieresissmall", + "Ethsmall", + "Ntildesmall", + "Ogravesmall", + "Oacutesmall", + "Ocircumflexsmall", + "Otildesmall", + "Odieresissmall", + "OEsmall", + "Oslashsmall", + "Ugravesmall", + "Uacutesmall", + "Ucircumflexsmall", + "Udieresissmall", + "Yacutesmall", + "Thornsmall", + "Ydieresissmall", + "001.000", + "001.001", + "001.002", + "001.003", + "Black", + "Bold", + "Book", + "Light", + "Medium", + "Regular", + "Roman", + "Semibold", +] + +cffStandardStringCount = 391 +assert len(cffStandardStrings) == cffStandardStringCount +# build reverse mapping +cffStandardStringMapping = {} +for _i in range(cffStandardStringCount): + cffStandardStringMapping[cffStandardStrings[_i]] = _i + +cffISOAdobeStrings = [ + ".notdef", + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quoteright", + "parenleft", + "parenright", + "asterisk", + "plus", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "bracketleft", + "backslash", + "bracketright", + "asciicircum", + "underscore", + "quoteleft", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "braceleft", + "bar", + "braceright", + "asciitilde", + "exclamdown", + "cent", + "sterling", + "fraction", + "yen", + "florin", + "section", + "currency", + "quotesingle", + "quotedblleft", + "guillemotleft", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + "endash", + "dagger", + "daggerdbl", + "periodcentered", + "paragraph", + "bullet", + "quotesinglbase", + "quotedblbase", + "quotedblright", + "guillemotright", + "ellipsis", + "perthousand", + "questiondown", + "grave", + "acute", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "dieresis", + "ring", + "cedilla", + "hungarumlaut", + "ogonek", + "caron", + "emdash", + "AE", + "ordfeminine", + "Lslash", + "Oslash", + "OE", + "ordmasculine", + "ae", + "dotlessi", + "lslash", + "oslash", + "oe", + "germandbls", + "onesuperior", + "logicalnot", + "mu", + "trademark", + "Eth", + "onehalf", + "plusminus", + "Thorn", + "onequarter", + "divide", + "brokenbar", + "degree", + "thorn", + "threequarters", + "twosuperior", + "registered", + "minus", + "eth", + "multiply", + "threesuperior", + "copyright", + "Aacute", + "Acircumflex", + "Adieresis", + "Agrave", + "Aring", + "Atilde", + "Ccedilla", + "Eacute", + "Ecircumflex", + "Edieresis", + "Egrave", + "Iacute", + "Icircumflex", + "Idieresis", + "Igrave", + "Ntilde", + "Oacute", + "Ocircumflex", + "Odieresis", + "Ograve", + "Otilde", + "Scaron", + "Uacute", + "Ucircumflex", + "Udieresis", + "Ugrave", + "Yacute", + "Ydieresis", + "Zcaron", + "aacute", + "acircumflex", + "adieresis", + "agrave", + "aring", + "atilde", + "ccedilla", + "eacute", + "ecircumflex", + "edieresis", + "egrave", + "iacute", + "icircumflex", + "idieresis", + "igrave", + "ntilde", + "oacute", + "ocircumflex", + "odieresis", + "ograve", + "otilde", + "scaron", + "uacute", + "ucircumflex", + "udieresis", + "ugrave", + "yacute", + "ydieresis", + "zcaron", +] + +cffISOAdobeStringCount = 229 +assert len(cffISOAdobeStrings) == cffISOAdobeStringCount + +cffIExpertStrings = [ + ".notdef", + "space", + "exclamsmall", + "Hungarumlautsmall", + "dollaroldstyle", + "dollarsuperior", + "ampersandsmall", + "Acutesmall", + "parenleftsuperior", + "parenrightsuperior", + "twodotenleader", + "onedotenleader", + "comma", + "hyphen", + "period", + "fraction", + "zerooldstyle", + "oneoldstyle", + "twooldstyle", + "threeoldstyle", + "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", + "sevenoldstyle", + "eightoldstyle", + "nineoldstyle", + "colon", + "semicolon", + "commasuperior", + "threequartersemdash", + "periodsuperior", + "questionsmall", + "asuperior", + "bsuperior", + "centsuperior", + "dsuperior", + "esuperior", + "isuperior", + "lsuperior", + "msuperior", + "nsuperior", + "osuperior", + "rsuperior", + "ssuperior", + "tsuperior", + "ff", + "fi", + "fl", + "ffi", + "ffl", + "parenleftinferior", + "parenrightinferior", + "Circumflexsmall", + "hyphensuperior", + "Gravesmall", + "Asmall", + "Bsmall", + "Csmall", + "Dsmall", + "Esmall", + "Fsmall", + "Gsmall", + "Hsmall", + "Ismall", + "Jsmall", + "Ksmall", + "Lsmall", + "Msmall", + "Nsmall", + "Osmall", + "Psmall", + "Qsmall", + "Rsmall", + "Ssmall", + "Tsmall", + "Usmall", + "Vsmall", + "Wsmall", + "Xsmall", + "Ysmall", + "Zsmall", + "colonmonetary", + "onefitted", + "rupiah", + "Tildesmall", + "exclamdownsmall", + "centoldstyle", + "Lslashsmall", + "Scaronsmall", + "Zcaronsmall", + "Dieresissmall", + "Brevesmall", + "Caronsmall", + "Dotaccentsmall", + "Macronsmall", + "figuredash", + "hypheninferior", + "Ogoneksmall", + "Ringsmall", + "Cedillasmall", + "onequarter", + "onehalf", + "threequarters", + "questiondownsmall", + "oneeighth", + "threeeighths", + "fiveeighths", + "seveneighths", + "onethird", + "twothirds", + "zerosuperior", + "onesuperior", + "twosuperior", + "threesuperior", + "foursuperior", + "fivesuperior", + "sixsuperior", + "sevensuperior", + "eightsuperior", + "ninesuperior", + "zeroinferior", + "oneinferior", + "twoinferior", + "threeinferior", + "fourinferior", + "fiveinferior", + "sixinferior", + "seveninferior", + "eightinferior", + "nineinferior", + "centinferior", + "dollarinferior", + "periodinferior", + "commainferior", + "Agravesmall", + "Aacutesmall", + "Acircumflexsmall", + "Atildesmall", + "Adieresissmall", + "Aringsmall", + "AEsmall", + "Ccedillasmall", + "Egravesmall", + "Eacutesmall", + "Ecircumflexsmall", + "Edieresissmall", + "Igravesmall", + "Iacutesmall", + "Icircumflexsmall", + "Idieresissmall", + "Ethsmall", + "Ntildesmall", + "Ogravesmall", + "Oacutesmall", + "Ocircumflexsmall", + "Otildesmall", + "Odieresissmall", + "OEsmall", + "Oslashsmall", + "Ugravesmall", + "Uacutesmall", + "Ucircumflexsmall", + "Udieresissmall", + "Yacutesmall", + "Thornsmall", + "Ydieresissmall", +] + +cffExpertStringCount = 166 +assert len(cffIExpertStrings) == cffExpertStringCount + +cffExpertSubsetStrings = [ + ".notdef", + "space", + "dollaroldstyle", + "dollarsuperior", + "parenleftsuperior", + "parenrightsuperior", + "twodotenleader", + "onedotenleader", + "comma", + "hyphen", + "period", + "fraction", + "zerooldstyle", + "oneoldstyle", + "twooldstyle", + "threeoldstyle", + "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", + "sevenoldstyle", + "eightoldstyle", + "nineoldstyle", + "colon", + "semicolon", + "commasuperior", + "threequartersemdash", + "periodsuperior", + "asuperior", + "bsuperior", + "centsuperior", + "dsuperior", + "esuperior", + "isuperior", + "lsuperior", + "msuperior", + "nsuperior", + "osuperior", + "rsuperior", + "ssuperior", + "tsuperior", + "ff", + "fi", + "fl", + "ffi", + "ffl", + "parenleftinferior", + "parenrightinferior", + "hyphensuperior", + "colonmonetary", + "onefitted", + "rupiah", + "centoldstyle", + "figuredash", + "hypheninferior", + "onequarter", + "onehalf", + "threequarters", + "oneeighth", + "threeeighths", + "fiveeighths", + "seveneighths", + "onethird", + "twothirds", + "zerosuperior", + "onesuperior", + "twosuperior", + "threesuperior", + "foursuperior", + "fivesuperior", + "sixsuperior", + "sevensuperior", + "eightsuperior", + "ninesuperior", + "zeroinferior", + "oneinferior", + "twoinferior", + "threeinferior", + "fourinferior", + "fiveinferior", + "sixinferior", + "seveninferior", + "eightinferior", + "nineinferior", + "centinferior", + "dollarinferior", + "periodinferior", + "commainferior", +] + +cffExpertSubsetStringCount = 87 +assert len(cffExpertSubsetStrings) == cffExpertSubsetStringCount diff --git a/.venv/lib/python3.13/site-packages/fontTools/cffLib/specializer.py b/.venv/lib/python3.13/site-packages/fontTools/cffLib/specializer.py new file mode 100644 index 0000000000000000000000000000000000000000..974060c40ec21a9c9ede2db0a34d0e60e4b42cf9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/cffLib/specializer.py @@ -0,0 +1,927 @@ +# -*- coding: utf-8 -*- + +"""T2CharString operator specializer and generalizer. + +PostScript glyph drawing operations can be expressed in multiple different +ways. For example, as well as the ``lineto`` operator, there is also a +``hlineto`` operator which draws a horizontal line, removing the need to +specify a ``dx`` coordinate, and a ``vlineto`` operator which draws a +vertical line, removing the need to specify a ``dy`` coordinate. As well +as decompiling :class:`fontTools.misc.psCharStrings.T2CharString` objects +into lists of operations, this module allows for conversion between general +and specific forms of the operation. + +""" + +from fontTools.cffLib import maxStackLimit + + +def stringToProgram(string): + if isinstance(string, str): + string = string.split() + program = [] + for token in string: + try: + token = int(token) + except ValueError: + try: + token = float(token) + except ValueError: + pass + program.append(token) + return program + + +def programToString(program): + return " ".join(str(x) for x in program) + + +def programToCommands(program, getNumRegions=None): + """Takes a T2CharString program list and returns list of commands. + Each command is a two-tuple of commandname,arg-list. The commandname might + be empty string if no commandname shall be emitted (used for glyph width, + hintmask/cntrmask argument, as well as stray arguments at the end of the + program (🤷). + 'getNumRegions' may be None, or a callable object. It must return the + number of regions. 'getNumRegions' takes a single argument, vsindex. It + returns the numRegions for the vsindex. + The Charstring may or may not start with a width value. If the first + non-blend operator has an odd number of arguments, then the first argument is + a width, and is popped off. This is complicated with blend operators, as + there may be more than one before the first hint or moveto operator, and each + one reduces several arguments to just one list argument. We have to sum the + number of arguments that are not part of the blend arguments, and all the + 'numBlends' values. We could instead have said that by definition, if there + is a blend operator, there is no width value, since CFF2 Charstrings don't + have width values. I discussed this with Behdad, and we are allowing for an + initial width value in this case because developers may assemble a CFF2 + charstring from CFF Charstrings, which could have width values. + """ + + seenWidthOp = False + vsIndex = 0 + lenBlendStack = 0 + lastBlendIndex = 0 + commands = [] + stack = [] + it = iter(program) + + for token in it: + if not isinstance(token, str): + stack.append(token) + continue + + if token == "blend": + assert getNumRegions is not None + numSourceFonts = 1 + getNumRegions(vsIndex) + # replace the blend op args on the stack with a single list + # containing all the blend op args. + numBlends = stack[-1] + numBlendArgs = numBlends * numSourceFonts + 1 + # replace first blend op by a list of the blend ops. + stack[-numBlendArgs:] = [stack[-numBlendArgs:]] + lenStack = len(stack) + lenBlendStack += numBlends + lenStack - 1 + lastBlendIndex = lenStack + # if a blend op exists, this is or will be a CFF2 charstring. + continue + + elif token == "vsindex": + vsIndex = stack[-1] + assert type(vsIndex) is int + + elif (not seenWidthOp) and token in { + "hstem", + "hstemhm", + "vstem", + "vstemhm", + "cntrmask", + "hintmask", + "hmoveto", + "vmoveto", + "rmoveto", + "endchar", + }: + seenWidthOp = True + parity = token in {"hmoveto", "vmoveto"} + if lenBlendStack: + # lenBlendStack has the number of args represented by the last blend + # arg and all the preceding args. We need to now add the number of + # args following the last blend arg. + numArgs = lenBlendStack + len(stack[lastBlendIndex:]) + else: + numArgs = len(stack) + if numArgs and (numArgs % 2) ^ parity: + width = stack.pop(0) + commands.append(("", [width])) + + if token in {"hintmask", "cntrmask"}: + if stack: + commands.append(("", stack)) + commands.append((token, [])) + commands.append(("", [next(it)])) + else: + commands.append((token, stack)) + stack = [] + if stack: + commands.append(("", stack)) + return commands + + +def _flattenBlendArgs(args): + token_list = [] + for arg in args: + if isinstance(arg, list): + token_list.extend(arg) + token_list.append("blend") + else: + token_list.append(arg) + return token_list + + +def commandsToProgram(commands): + """Takes a commands list as returned by programToCommands() and converts + it back to a T2CharString program list.""" + program = [] + for op, args in commands: + if any(isinstance(arg, list) for arg in args): + args = _flattenBlendArgs(args) + program.extend(args) + if op: + program.append(op) + return program + + +def _everyN(el, n): + """Group the list el into groups of size n""" + l = len(el) + if l % n != 0: + raise ValueError(el) + for i in range(0, l, n): + yield el[i : i + n] + + +class _GeneralizerDecombinerCommandsMap(object): + @staticmethod + def rmoveto(args): + if len(args) != 2: + raise ValueError(args) + yield ("rmoveto", args) + + @staticmethod + def hmoveto(args): + if len(args) != 1: + raise ValueError(args) + yield ("rmoveto", [args[0], 0]) + + @staticmethod + def vmoveto(args): + if len(args) != 1: + raise ValueError(args) + yield ("rmoveto", [0, args[0]]) + + @staticmethod + def rlineto(args): + if not args: + raise ValueError(args) + for args in _everyN(args, 2): + yield ("rlineto", args) + + @staticmethod + def hlineto(args): + if not args: + raise ValueError(args) + it = iter(args) + try: + while True: + yield ("rlineto", [next(it), 0]) + yield ("rlineto", [0, next(it)]) + except StopIteration: + pass + + @staticmethod + def vlineto(args): + if not args: + raise ValueError(args) + it = iter(args) + try: + while True: + yield ("rlineto", [0, next(it)]) + yield ("rlineto", [next(it), 0]) + except StopIteration: + pass + + @staticmethod + def rrcurveto(args): + if not args: + raise ValueError(args) + for args in _everyN(args, 6): + yield ("rrcurveto", args) + + @staticmethod + def hhcurveto(args): + l = len(args) + if l < 4 or l % 4 > 1: + raise ValueError(args) + if l % 2 == 1: + yield ("rrcurveto", [args[1], args[0], args[2], args[3], args[4], 0]) + args = args[5:] + for args in _everyN(args, 4): + yield ("rrcurveto", [args[0], 0, args[1], args[2], args[3], 0]) + + @staticmethod + def vvcurveto(args): + l = len(args) + if l < 4 or l % 4 > 1: + raise ValueError(args) + if l % 2 == 1: + yield ("rrcurveto", [args[0], args[1], args[2], args[3], 0, args[4]]) + args = args[5:] + for args in _everyN(args, 4): + yield ("rrcurveto", [0, args[0], args[1], args[2], 0, args[3]]) + + @staticmethod + def hvcurveto(args): + l = len(args) + if l < 4 or l % 8 not in {0, 1, 4, 5}: + raise ValueError(args) + last_args = None + if l % 2 == 1: + lastStraight = l % 8 == 5 + args, last_args = args[:-5], args[-5:] + it = _everyN(args, 4) + try: + while True: + args = next(it) + yield ("rrcurveto", [args[0], 0, args[1], args[2], 0, args[3]]) + args = next(it) + yield ("rrcurveto", [0, args[0], args[1], args[2], args[3], 0]) + except StopIteration: + pass + if last_args: + args = last_args + if lastStraight: + yield ("rrcurveto", [args[0], 0, args[1], args[2], args[4], args[3]]) + else: + yield ("rrcurveto", [0, args[0], args[1], args[2], args[3], args[4]]) + + @staticmethod + def vhcurveto(args): + l = len(args) + if l < 4 or l % 8 not in {0, 1, 4, 5}: + raise ValueError(args) + last_args = None + if l % 2 == 1: + lastStraight = l % 8 == 5 + args, last_args = args[:-5], args[-5:] + it = _everyN(args, 4) + try: + while True: + args = next(it) + yield ("rrcurveto", [0, args[0], args[1], args[2], args[3], 0]) + args = next(it) + yield ("rrcurveto", [args[0], 0, args[1], args[2], 0, args[3]]) + except StopIteration: + pass + if last_args: + args = last_args + if lastStraight: + yield ("rrcurveto", [0, args[0], args[1], args[2], args[3], args[4]]) + else: + yield ("rrcurveto", [args[0], 0, args[1], args[2], args[4], args[3]]) + + @staticmethod + def rcurveline(args): + l = len(args) + if l < 8 or l % 6 != 2: + raise ValueError(args) + args, last_args = args[:-2], args[-2:] + for args in _everyN(args, 6): + yield ("rrcurveto", args) + yield ("rlineto", last_args) + + @staticmethod + def rlinecurve(args): + l = len(args) + if l < 8 or l % 2 != 0: + raise ValueError(args) + args, last_args = args[:-6], args[-6:] + for args in _everyN(args, 2): + yield ("rlineto", args) + yield ("rrcurveto", last_args) + + +def _convertBlendOpToArgs(blendList): + # args is list of blend op args. Since we are supporting + # recursive blend op calls, some of these args may also + # be a list of blend op args, and need to be converted before + # we convert the current list. + if any([isinstance(arg, list) for arg in blendList]): + args = [ + i + for e in blendList + for i in (_convertBlendOpToArgs(e) if isinstance(e, list) else [e]) + ] + else: + args = blendList + + # We now know that blendList contains a blend op argument list, even if + # some of the args are lists that each contain a blend op argument list. + # Convert from: + # [default font arg sequence x0,...,xn] + [delta tuple for x0] + ... + [delta tuple for xn] + # to: + # [ [x0] + [delta tuple for x0], + # ..., + # [xn] + [delta tuple for xn] ] + numBlends = args[-1] + # Can't use args.pop() when the args are being used in a nested list + # comprehension. See calling context + args = args[:-1] + + l = len(args) + numRegions = l // numBlends - 1 + if not (numBlends * (numRegions + 1) == l): + raise ValueError(blendList) + + defaultArgs = [[arg] for arg in args[:numBlends]] + deltaArgs = args[numBlends:] + numDeltaValues = len(deltaArgs) + deltaList = [ + deltaArgs[i : i + numRegions] for i in range(0, numDeltaValues, numRegions) + ] + blend_args = [a + b + [1] for a, b in zip(defaultArgs, deltaList)] + return blend_args + + +def generalizeCommands(commands, ignoreErrors=False): + result = [] + mapping = _GeneralizerDecombinerCommandsMap + for op, args in commands: + # First, generalize any blend args in the arg list. + if any([isinstance(arg, list) for arg in args]): + try: + args = [ + n + for arg in args + for n in ( + _convertBlendOpToArgs(arg) if isinstance(arg, list) else [arg] + ) + ] + except ValueError: + if ignoreErrors: + # Store op as data, such that consumers of commands do not have to + # deal with incorrect number of arguments. + result.append(("", args)) + result.append(("", [op])) + else: + raise + + func = getattr(mapping, op, None) + if func is None: + result.append((op, args)) + continue + try: + for command in func(args): + result.append(command) + except ValueError: + if ignoreErrors: + # Store op as data, such that consumers of commands do not have to + # deal with incorrect number of arguments. + result.append(("", args)) + result.append(("", [op])) + else: + raise + return result + + +def generalizeProgram(program, getNumRegions=None, **kwargs): + return commandsToProgram( + generalizeCommands(programToCommands(program, getNumRegions), **kwargs) + ) + + +def _categorizeVector(v): + """ + Takes X,Y vector v and returns one of r, h, v, or 0 depending on which + of X and/or Y are zero, plus tuple of nonzero ones. If both are zero, + it returns a single zero still. + + >>> _categorizeVector((0,0)) + ('0', (0,)) + >>> _categorizeVector((1,0)) + ('h', (1,)) + >>> _categorizeVector((0,2)) + ('v', (2,)) + >>> _categorizeVector((1,2)) + ('r', (1, 2)) + """ + if not v[0]: + if not v[1]: + return "0", v[:1] + else: + return "v", v[1:] + else: + if not v[1]: + return "h", v[:1] + else: + return "r", v + + +def _mergeCategories(a, b): + if a == "0": + return b + if b == "0": + return a + if a == b: + return a + return None + + +def _negateCategory(a): + if a == "h": + return "v" + if a == "v": + return "h" + assert a in "0r" + return a + + +def _convertToBlendCmds(args): + # return a list of blend commands, and + # the remaining non-blended args, if any. + num_args = len(args) + stack_use = 0 + new_args = [] + i = 0 + while i < num_args: + arg = args[i] + i += 1 + if not isinstance(arg, list): + new_args.append(arg) + stack_use += 1 + else: + prev_stack_use = stack_use + # The arg is a tuple of blend values. + # These are each (master 0,delta 1..delta n, 1) + # Combine as many successive tuples as we can, + # up to the max stack limit. + num_sources = len(arg) - 1 + blendlist = [arg] + stack_use += 1 + num_sources # 1 for the num_blends arg + + # if we are here, max stack is the CFF2 max stack. + # I use the CFF2 max stack limit here rather than + # the 'maxstack' chosen by the client, as the default + # maxstack may have been used unintentionally. For all + # the other operators, this just produces a little less + # optimization, but here it puts a hard (and low) limit + # on the number of source fonts that can be used. + # + # Make sure the stack depth does not exceed (maxstack - 1), so + # that subroutinizer can insert subroutine calls at any point. + while ( + (i < num_args) + and isinstance(args[i], list) + and stack_use + num_sources < maxStackLimit + ): + blendlist.append(args[i]) + i += 1 + stack_use += num_sources + # blendList now contains as many single blend tuples as can be + # combined without exceeding the CFF2 stack limit. + num_blends = len(blendlist) + # append the 'num_blends' default font values + blend_args = [] + for arg in blendlist: + blend_args.append(arg[0]) + for arg in blendlist: + assert arg[-1] == 1 + blend_args.extend(arg[1:-1]) + blend_args.append(num_blends) + new_args.append(blend_args) + stack_use = prev_stack_use + num_blends + + return new_args + + +def _addArgs(a, b): + if isinstance(b, list): + if isinstance(a, list): + if len(a) != len(b) or a[-1] != b[-1]: + raise ValueError() + return [_addArgs(va, vb) for va, vb in zip(a[:-1], b[:-1])] + [a[-1]] + else: + a, b = b, a + if isinstance(a, list): + assert a[-1] == 1 + return [_addArgs(a[0], b)] + a[1:] + return a + b + + +def _argsStackUse(args): + stackLen = 0 + maxLen = 0 + for arg in args: + if type(arg) is list: + # Blended arg + maxLen = max(maxLen, stackLen + _argsStackUse(arg)) + stackLen += arg[-1] + else: + stackLen += 1 + return max(stackLen, maxLen) + + +def specializeCommands( + commands, + ignoreErrors=False, + generalizeFirst=True, + preserveTopology=False, + maxstack=48, +): + # We perform several rounds of optimizations. They are carefully ordered and are: + # + # 0. Generalize commands. + # This ensures that they are in our expected simple form, with each line/curve only + # having arguments for one segment, and using the generic form (rlineto/rrcurveto). + # If caller is sure the input is in this form, they can turn off generalization to + # save time. + # + # 1. Combine successive rmoveto operations. + # + # 2. Specialize rmoveto/rlineto/rrcurveto operators into horizontal/vertical variants. + # We specialize into some, made-up, variants as well, which simplifies following + # passes. + # + # 3. Merge or delete redundant operations, to the extent requested. + # OpenType spec declares point numbers in CFF undefined. As such, we happily + # change topology. If client relies on point numbers (in GPOS anchors, or for + # hinting purposes(what?)) they can turn this off. + # + # 4. Peephole optimization to revert back some of the h/v variants back into their + # original "relative" operator (rline/rrcurveto) if that saves a byte. + # + # 5. Combine adjacent operators when possible, minding not to go over max stack size. + # + # 6. Resolve any remaining made-up operators into real operators. + # + # I have convinced myself that this produces optimal bytecode (except for, possibly + # one byte each time maxstack size prohibits combining.) YMMV, but you'd be wrong. :-) + # A dynamic-programming approach can do the same but would be significantly slower. + # + # 7. For any args which are blend lists, convert them to a blend command. + + # 0. Generalize commands. + if generalizeFirst: + commands = generalizeCommands(commands, ignoreErrors=ignoreErrors) + else: + commands = list(commands) # Make copy since we modify in-place later. + + # 1. Combine successive rmoveto operations. + for i in range(len(commands) - 1, 0, -1): + if "rmoveto" == commands[i][0] == commands[i - 1][0]: + v1, v2 = commands[i - 1][1], commands[i][1] + commands[i - 1] = ( + "rmoveto", + [_addArgs(v1[0], v2[0]), _addArgs(v1[1], v2[1])], + ) + del commands[i] + + # 2. Specialize rmoveto/rlineto/rrcurveto operators into horizontal/vertical variants. + # + # We, in fact, specialize into more, made-up, variants that special-case when both + # X and Y components are zero. This simplifies the following optimization passes. + # This case is rare, but OCD does not let me skip it. + # + # After this round, we will have four variants that use the following mnemonics: + # + # - 'r' for relative, ie. non-zero X and non-zero Y, + # - 'h' for horizontal, ie. zero X and non-zero Y, + # - 'v' for vertical, ie. non-zero X and zero Y, + # - '0' for zeros, ie. zero X and zero Y. + # + # The '0' pseudo-operators are not part of the spec, but help simplify the following + # optimization rounds. We resolve them at the end. So, after this, we will have four + # moveto and four lineto variants: + # + # - 0moveto, 0lineto + # - hmoveto, hlineto + # - vmoveto, vlineto + # - rmoveto, rlineto + # + # and sixteen curveto variants. For example, a '0hcurveto' operator means a curve + # dx0,dy0,dx1,dy1,dx2,dy2,dx3,dy3 where dx0, dx1, and dy3 are zero but not dx3. + # An 'rvcurveto' means dx3 is zero but not dx0,dy0,dy3. + # + # There are nine different variants of curves without the '0'. Those nine map exactly + # to the existing curve variants in the spec: rrcurveto, and the four variants hhcurveto, + # vvcurveto, hvcurveto, and vhcurveto each cover two cases, one with an odd number of + # arguments and one without. Eg. an hhcurveto with an extra argument (odd number of + # arguments) is in fact an rhcurveto. The operators in the spec are designed such that + # all four of rhcurveto, rvcurveto, hrcurveto, and vrcurveto are encodable for one curve. + # + # Of the curve types with '0', the 00curveto is equivalent to a lineto variant. The rest + # of the curve types with a 0 need to be encoded as a h or v variant. Ie. a '0' can be + # thought of a "don't care" and can be used as either an 'h' or a 'v'. As such, we always + # encode a number 0 as argument when we use a '0' variant. Later on, we can just substitute + # the '0' with either 'h' or 'v' and it works. + # + # When we get to curve splines however, things become more complicated... XXX finish this. + # There's one more complexity with splines. If one side of the spline is not horizontal or + # vertical (or zero), ie. if it's 'r', then it limits which spline types we can encode. + # Only hhcurveto and vvcurveto operators can encode a spline starting with 'r', and + # only hvcurveto and vhcurveto operators can encode a spline ending with 'r'. + # This limits our merge opportunities later. + # + for i in range(len(commands)): + op, args = commands[i] + + if op in {"rmoveto", "rlineto"}: + c, args = _categorizeVector(args) + commands[i] = c + op[1:], args + continue + + if op == "rrcurveto": + c1, args1 = _categorizeVector(args[:2]) + c2, args2 = _categorizeVector(args[-2:]) + commands[i] = c1 + c2 + "curveto", args1 + args[2:4] + args2 + continue + + # 3. Merge or delete redundant operations, to the extent requested. + # + # TODO + # A 0moveto that comes before all other path operations can be removed. + # though I find conflicting evidence for this. + # + # TODO + # "If hstem and vstem hints are both declared at the beginning of a + # CharString, and this sequence is followed directly by the hintmask or + # cntrmask operators, then the vstem hint operator (or, if applicable, + # the vstemhm operator) need not be included." + # + # "The sequence and form of a CFF2 CharString program may be represented as: + # {hs* vs* cm* hm* mt subpath}? {mt subpath}*" + # + # https://www.microsoft.com/typography/otspec/cff2charstr.htm#section3.1 + # + # For Type2 CharStrings the sequence is: + # w? {hs* vs* cm* hm* mt subpath}? {mt subpath}* endchar" + + # Some other redundancies change topology (point numbers). + if not preserveTopology: + for i in range(len(commands) - 1, -1, -1): + op, args = commands[i] + + # A 00curveto is demoted to a (specialized) lineto. + if op == "00curveto": + assert len(args) == 4 + c, args = _categorizeVector(args[1:3]) + op = c + "lineto" + commands[i] = op, args + # and then... + + # A 0lineto can be deleted. + if op == "0lineto": + del commands[i] + continue + + # Merge adjacent hlineto's and vlineto's. + # In CFF2 charstrings from variable fonts, each + # arg item may be a list of blendable values, one from + # each source font. + if i and op in {"hlineto", "vlineto"} and (op == commands[i - 1][0]): + _, other_args = commands[i - 1] + assert len(args) == 1 and len(other_args) == 1 + try: + new_args = [_addArgs(args[0], other_args[0])] + except ValueError: + continue + commands[i - 1] = (op, new_args) + del commands[i] + continue + + # 4. Peephole optimization to revert back some of the h/v variants back into their + # original "relative" operator (rline/rrcurveto) if that saves a byte. + for i in range(1, len(commands) - 1): + op, args = commands[i] + prv, nxt = commands[i - 1][0], commands[i + 1][0] + + if op in {"0lineto", "hlineto", "vlineto"} and prv == nxt == "rlineto": + assert len(args) == 1 + args = [0, args[0]] if op[0] == "v" else [args[0], 0] + commands[i] = ("rlineto", args) + continue + + if op[2:] == "curveto" and len(args) == 5 and prv == nxt == "rrcurveto": + assert (op[0] == "r") ^ (op[1] == "r") + if op[0] == "v": + pos = 0 + elif op[0] != "r": + pos = 1 + elif op[1] == "v": + pos = 4 + else: + pos = 5 + # Insert, while maintaining the type of args (can be tuple or list). + args = args[:pos] + type(args)((0,)) + args[pos:] + commands[i] = ("rrcurveto", args) + continue + + # 5. Combine adjacent operators when possible, minding not to go over max stack size. + stackUse = _argsStackUse(commands[-1][1]) if commands else 0 + for i in range(len(commands) - 1, 0, -1): + op1, args1 = commands[i - 1] + op2, args2 = commands[i] + new_op = None + + # Merge logic... + if {op1, op2} <= {"rlineto", "rrcurveto"}: + if op1 == op2: + new_op = op1 + else: + l = len(args2) + if op2 == "rrcurveto" and l == 6: + new_op = "rlinecurve" + elif l == 2: + new_op = "rcurveline" + + elif (op1, op2) in {("rlineto", "rlinecurve"), ("rrcurveto", "rcurveline")}: + new_op = op2 + + elif {op1, op2} == {"vlineto", "hlineto"}: + new_op = op1 + + elif "curveto" == op1[2:] == op2[2:]: + d0, d1 = op1[:2] + d2, d3 = op2[:2] + + if d1 == "r" or d2 == "r" or d0 == d3 == "r": + continue + + d = _mergeCategories(d1, d2) + if d is None: + continue + if d0 == "r": + d = _mergeCategories(d, d3) + if d is None: + continue + new_op = "r" + d + "curveto" + elif d3 == "r": + d0 = _mergeCategories(d0, _negateCategory(d)) + if d0 is None: + continue + new_op = d0 + "r" + "curveto" + else: + d0 = _mergeCategories(d0, d3) + if d0 is None: + continue + new_op = d0 + d + "curveto" + + # Make sure the stack depth does not exceed (maxstack - 1), so + # that subroutinizer can insert subroutine calls at any point. + args1StackUse = _argsStackUse(args1) + combinedStackUse = max(args1StackUse, len(args1) + stackUse) + if new_op and combinedStackUse < maxstack: + commands[i - 1] = (new_op, args1 + args2) + del commands[i] + stackUse = combinedStackUse + else: + stackUse = args1StackUse + + # 6. Resolve any remaining made-up operators into real operators. + for i in range(len(commands)): + op, args = commands[i] + + if op in {"0moveto", "0lineto"}: + commands[i] = "h" + op[1:], args + continue + + if op[2:] == "curveto" and op[:2] not in {"rr", "hh", "vv", "vh", "hv"}: + l = len(args) + + op0, op1 = op[:2] + if (op0 == "r") ^ (op1 == "r"): + assert l % 2 == 1 + if op0 == "0": + op0 = "h" + if op1 == "0": + op1 = "h" + if op0 == "r": + op0 = op1 + if op1 == "r": + op1 = _negateCategory(op0) + assert {op0, op1} <= {"h", "v"}, (op0, op1) + + if l % 2: + if op0 != op1: # vhcurveto / hvcurveto + if (op0 == "h") ^ (l % 8 == 1): + # Swap last two args order + args = args[:-2] + args[-1:] + args[-2:-1] + else: # hhcurveto / vvcurveto + if op0 == "h": # hhcurveto + # Swap first two args order + args = args[1:2] + args[:1] + args[2:] + + commands[i] = op0 + op1 + "curveto", args + continue + + # 7. For any series of args which are blend lists, convert the series to a single blend arg. + for i in range(len(commands)): + op, args = commands[i] + if any(isinstance(arg, list) for arg in args): + commands[i] = op, _convertToBlendCmds(args) + + return commands + + +def specializeProgram(program, getNumRegions=None, **kwargs): + return commandsToProgram( + specializeCommands(programToCommands(program, getNumRegions), **kwargs) + ) + + +if __name__ == "__main__": + import sys + + if len(sys.argv) == 1: + import doctest + + sys.exit(doctest.testmod().failed) + + import argparse + + parser = argparse.ArgumentParser( + "fonttools cffLib.specializer", + description="CFF CharString generalizer/specializer", + ) + parser.add_argument("program", metavar="command", nargs="*", help="Commands.") + parser.add_argument( + "--num-regions", + metavar="NumRegions", + nargs="*", + default=None, + help="Number of variable-font regions for blend opertaions.", + ) + parser.add_argument( + "--font", + metavar="FONTFILE", + default=None, + help="CFF2 font to specialize.", + ) + parser.add_argument( + "-o", + "--output-file", + type=str, + help="Output font file name.", + ) + + options = parser.parse_args(sys.argv[1:]) + + if options.program: + getNumRegions = ( + None + if options.num_regions is None + else lambda vsIndex: int( + options.num_regions[0 if vsIndex is None else vsIndex] + ) + ) + + program = stringToProgram(options.program) + print("Program:") + print(programToString(program)) + commands = programToCommands(program, getNumRegions) + print("Commands:") + print(commands) + program2 = commandsToProgram(commands) + print("Program from commands:") + print(programToString(program2)) + assert program == program2 + print("Generalized program:") + print(programToString(generalizeProgram(program, getNumRegions))) + print("Specialized program:") + print(programToString(specializeProgram(program, getNumRegions))) + + if options.font: + from fontTools.ttLib import TTFont + + font = TTFont(options.font) + cff2 = font["CFF2"].cff.topDictIndex[0] + charstrings = cff2.CharStrings + for glyphName in charstrings.keys(): + charstring = charstrings[glyphName] + charstring.decompile() + getNumRegions = charstring.private.getNumRegions + charstring.program = specializeProgram( + charstring.program, getNumRegions, maxstack=maxStackLimit + ) + + if options.output_file is None: + from fontTools.misc.cliTools import makeOutputFileName + + outfile = makeOutputFileName( + options.font, overWrite=True, suffix=".specialized" + ) + else: + outfile = options.output_file + if outfile: + print("Saving", outfile) + font.save(outfile) diff --git a/.venv/lib/python3.13/site-packages/fontTools/cffLib/transforms.py b/.venv/lib/python3.13/site-packages/fontTools/cffLib/transforms.py new file mode 100644 index 0000000000000000000000000000000000000000..b9b7c86c8b450d8a599780b1af53004afa9004d7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/cffLib/transforms.py @@ -0,0 +1,495 @@ +from fontTools.misc.psCharStrings import ( + SimpleT2Decompiler, + T2WidthExtractor, + calcSubrBias, +) + + +def _uniq_sort(l): + return sorted(set(l)) + + +class StopHintCountEvent(Exception): + pass + + +class _DesubroutinizingT2Decompiler(SimpleT2Decompiler): + stop_hintcount_ops = ( + "op_hintmask", + "op_cntrmask", + "op_rmoveto", + "op_hmoveto", + "op_vmoveto", + ) + + def __init__(self, localSubrs, globalSubrs, private=None): + SimpleT2Decompiler.__init__(self, localSubrs, globalSubrs, private) + + def execute(self, charString): + self.need_hintcount = True # until proven otherwise + for op_name in self.stop_hintcount_ops: + setattr(self, op_name, self.stop_hint_count) + + if hasattr(charString, "_desubroutinized"): + # If a charstring has already been desubroutinized, we will still + # need to execute it if we need to count hints in order to + # compute the byte length for mask arguments, and haven't finished + # counting hints pairs. + if self.need_hintcount and self.callingStack: + try: + SimpleT2Decompiler.execute(self, charString) + except StopHintCountEvent: + del self.callingStack[-1] + return + + charString._patches = [] + SimpleT2Decompiler.execute(self, charString) + desubroutinized = charString.program[:] + for idx, expansion in reversed(charString._patches): + assert idx >= 2 + assert desubroutinized[idx - 1] in [ + "callsubr", + "callgsubr", + ], desubroutinized[idx - 1] + assert type(desubroutinized[idx - 2]) == int + if expansion[-1] == "return": + expansion = expansion[:-1] + desubroutinized[idx - 2 : idx] = expansion + if not self.private.in_cff2: + if "endchar" in desubroutinized: + # Cut off after first endchar + desubroutinized = desubroutinized[ + : desubroutinized.index("endchar") + 1 + ] + + charString._desubroutinized = desubroutinized + del charString._patches + + def op_callsubr(self, index): + subr = self.localSubrs[self.operandStack[-1] + self.localBias] + SimpleT2Decompiler.op_callsubr(self, index) + self.processSubr(index, subr) + + def op_callgsubr(self, index): + subr = self.globalSubrs[self.operandStack[-1] + self.globalBias] + SimpleT2Decompiler.op_callgsubr(self, index) + self.processSubr(index, subr) + + def stop_hint_count(self, *args): + self.need_hintcount = False + for op_name in self.stop_hintcount_ops: + setattr(self, op_name, None) + cs = self.callingStack[-1] + if hasattr(cs, "_desubroutinized"): + raise StopHintCountEvent() + + def op_hintmask(self, index): + SimpleT2Decompiler.op_hintmask(self, index) + if self.need_hintcount: + self.stop_hint_count() + + def processSubr(self, index, subr): + cs = self.callingStack[-1] + if not hasattr(cs, "_desubroutinized"): + cs._patches.append((index, subr._desubroutinized)) + + +def desubroutinizeCharString(cs): + """Desubroutinize a charstring in-place.""" + cs.decompile() + subrs = getattr(cs.private, "Subrs", []) + decompiler = _DesubroutinizingT2Decompiler(subrs, cs.globalSubrs, cs.private) + decompiler.execute(cs) + cs.program = cs._desubroutinized + del cs._desubroutinized + + +def desubroutinize(cff): + for fontName in cff.fontNames: + font = cff[fontName] + cs = font.CharStrings + for c in cs.values(): + desubroutinizeCharString(c) + # Delete all the local subrs + if hasattr(font, "FDArray"): + for fd in font.FDArray: + pd = fd.Private + if hasattr(pd, "Subrs"): + del pd.Subrs + if "Subrs" in pd.rawDict: + del pd.rawDict["Subrs"] + else: + pd = font.Private + if hasattr(pd, "Subrs"): + del pd.Subrs + if "Subrs" in pd.rawDict: + del pd.rawDict["Subrs"] + # as well as the global subrs + cff.GlobalSubrs.clear() + + +class _MarkingT2Decompiler(SimpleT2Decompiler): + def __init__(self, localSubrs, globalSubrs, private): + SimpleT2Decompiler.__init__(self, localSubrs, globalSubrs, private) + for subrs in [localSubrs, globalSubrs]: + if subrs and not hasattr(subrs, "_used"): + subrs._used = set() + + def op_callsubr(self, index): + self.localSubrs._used.add(self.operandStack[-1] + self.localBias) + SimpleT2Decompiler.op_callsubr(self, index) + + def op_callgsubr(self, index): + self.globalSubrs._used.add(self.operandStack[-1] + self.globalBias) + SimpleT2Decompiler.op_callgsubr(self, index) + + +class _DehintingT2Decompiler(T2WidthExtractor): + class Hints(object): + def __init__(self): + # Whether calling this charstring produces any hint stems + # Note that if a charstring starts with hintmask, it will + # have has_hint set to True, because it *might* produce an + # implicit vstem if called under certain conditions. + self.has_hint = False + # Index to start at to drop all hints + self.last_hint = 0 + # Index up to which we know more hints are possible. + # Only relevant if status is 0 or 1. + self.last_checked = 0 + # The status means: + # 0: after dropping hints, this charstring is empty + # 1: after dropping hints, there may be more hints + # continuing after this, or there might be + # other things. Not clear yet. + # 2: no more hints possible after this charstring + self.status = 0 + # Has hintmask instructions; not recursive + self.has_hintmask = False + # List of indices of calls to empty subroutines to remove. + self.deletions = [] + + pass + + def __init__( + self, css, localSubrs, globalSubrs, nominalWidthX, defaultWidthX, private=None + ): + self._css = css + T2WidthExtractor.__init__( + self, localSubrs, globalSubrs, nominalWidthX, defaultWidthX + ) + self.private = private + + def execute(self, charString): + old_hints = charString._hints if hasattr(charString, "_hints") else None + charString._hints = self.Hints() + + T2WidthExtractor.execute(self, charString) + + hints = charString._hints + + if hints.has_hint or hints.has_hintmask: + self._css.add(charString) + + if hints.status != 2: + # Check from last_check, make sure we didn't have any operators. + for i in range(hints.last_checked, len(charString.program) - 1): + if isinstance(charString.program[i], str): + hints.status = 2 + break + else: + hints.status = 1 # There's *something* here + hints.last_checked = len(charString.program) + + if old_hints: + assert hints.__dict__ == old_hints.__dict__ + + def op_callsubr(self, index): + subr = self.localSubrs[self.operandStack[-1] + self.localBias] + T2WidthExtractor.op_callsubr(self, index) + self.processSubr(index, subr) + + def op_callgsubr(self, index): + subr = self.globalSubrs[self.operandStack[-1] + self.globalBias] + T2WidthExtractor.op_callgsubr(self, index) + self.processSubr(index, subr) + + def op_hstem(self, index): + T2WidthExtractor.op_hstem(self, index) + self.processHint(index) + + def op_vstem(self, index): + T2WidthExtractor.op_vstem(self, index) + self.processHint(index) + + def op_hstemhm(self, index): + T2WidthExtractor.op_hstemhm(self, index) + self.processHint(index) + + def op_vstemhm(self, index): + T2WidthExtractor.op_vstemhm(self, index) + self.processHint(index) + + def op_hintmask(self, index): + rv = T2WidthExtractor.op_hintmask(self, index) + self.processHintmask(index) + return rv + + def op_cntrmask(self, index): + rv = T2WidthExtractor.op_cntrmask(self, index) + self.processHintmask(index) + return rv + + def processHintmask(self, index): + cs = self.callingStack[-1] + hints = cs._hints + hints.has_hintmask = True + if hints.status != 2: + # Check from last_check, see if we may be an implicit vstem + for i in range(hints.last_checked, index - 1): + if isinstance(cs.program[i], str): + hints.status = 2 + break + else: + # We are an implicit vstem + hints.has_hint = True + hints.last_hint = index + 1 + hints.status = 0 + hints.last_checked = index + 1 + + def processHint(self, index): + cs = self.callingStack[-1] + hints = cs._hints + hints.has_hint = True + hints.last_hint = index + hints.last_checked = index + + def processSubr(self, index, subr): + cs = self.callingStack[-1] + hints = cs._hints + subr_hints = subr._hints + + # Check from last_check, make sure we didn't have + # any operators. + if hints.status != 2: + for i in range(hints.last_checked, index - 1): + if isinstance(cs.program[i], str): + hints.status = 2 + break + hints.last_checked = index + + if hints.status != 2: + if subr_hints.has_hint: + hints.has_hint = True + + # Decide where to chop off from + if subr_hints.status == 0: + hints.last_hint = index + else: + hints.last_hint = index - 2 # Leave the subr call in + + elif subr_hints.status == 0: + hints.deletions.append(index) + + hints.status = max(hints.status, subr_hints.status) + + +def _cs_subset_subroutines(charstring, subrs, gsubrs): + p = charstring.program + for i in range(1, len(p)): + if p[i] == "callsubr": + assert isinstance(p[i - 1], int) + p[i - 1] = subrs._used.index(p[i - 1] + subrs._old_bias) - subrs._new_bias + elif p[i] == "callgsubr": + assert isinstance(p[i - 1], int) + p[i - 1] = ( + gsubrs._used.index(p[i - 1] + gsubrs._old_bias) - gsubrs._new_bias + ) + + +def _cs_drop_hints(charstring): + hints = charstring._hints + + if hints.deletions: + p = charstring.program + for idx in reversed(hints.deletions): + del p[idx - 2 : idx] + + if hints.has_hint: + assert not hints.deletions or hints.last_hint <= hints.deletions[0] + charstring.program = charstring.program[hints.last_hint :] + if not charstring.program: + # TODO CFF2 no need for endchar. + charstring.program.append("endchar") + if hasattr(charstring, "width"): + # Insert width back if needed + if charstring.width != charstring.private.defaultWidthX: + # For CFF2 charstrings, this should never happen + assert ( + charstring.private.defaultWidthX is not None + ), "CFF2 CharStrings must not have an initial width value" + charstring.program.insert( + 0, charstring.width - charstring.private.nominalWidthX + ) + + if hints.has_hintmask: + i = 0 + p = charstring.program + while i < len(p): + if p[i] in ["hintmask", "cntrmask"]: + assert i + 1 <= len(p) + del p[i : i + 2] + continue + i += 1 + + assert len(charstring.program) + + del charstring._hints + + +def remove_hints(cff, *, removeUnusedSubrs: bool = True): + for fontname in cff.keys(): + font = cff[fontname] + cs = font.CharStrings + # This can be tricky, but doesn't have to. What we do is: + # + # - Run all used glyph charstrings and recurse into subroutines, + # - For each charstring (including subroutines), if it has any + # of the hint stem operators, we mark it as such. + # Upon returning, for each charstring we note all the + # subroutine calls it makes that (recursively) contain a stem, + # - Dropping hinting then consists of the following two ops: + # * Drop the piece of the program in each charstring before the + # last call to a stem op or a stem-calling subroutine, + # * Drop all hintmask operations. + # - It's trickier... A hintmask right after hints and a few numbers + # will act as an implicit vstemhm. As such, we track whether + # we have seen any non-hint operators so far and do the right + # thing, recursively... Good luck understanding that :( + css = set() + for c in cs.values(): + c.decompile() + subrs = getattr(c.private, "Subrs", []) + decompiler = _DehintingT2Decompiler( + css, + subrs, + c.globalSubrs, + c.private.nominalWidthX, + c.private.defaultWidthX, + c.private, + ) + decompiler.execute(c) + c.width = decompiler.width + for charstring in css: + _cs_drop_hints(charstring) + del css + + # Drop font-wide hinting values + all_privs = [] + if hasattr(font, "FDArray"): + all_privs.extend(fd.Private for fd in font.FDArray) + else: + all_privs.append(font.Private) + for priv in all_privs: + for k in [ + "BlueValues", + "OtherBlues", + "FamilyBlues", + "FamilyOtherBlues", + "BlueScale", + "BlueShift", + "BlueFuzz", + "StemSnapH", + "StemSnapV", + "StdHW", + "StdVW", + "ForceBold", + "LanguageGroup", + "ExpansionFactor", + ]: + if hasattr(priv, k): + setattr(priv, k, None) + if removeUnusedSubrs: + remove_unused_subroutines(cff) + + +def _pd_delete_empty_subrs(private_dict): + if hasattr(private_dict, "Subrs") and not private_dict.Subrs: + if "Subrs" in private_dict.rawDict: + del private_dict.rawDict["Subrs"] + del private_dict.Subrs + + +def remove_unused_subroutines(cff): + for fontname in cff.keys(): + font = cff[fontname] + cs = font.CharStrings + # Renumber subroutines to remove unused ones + + # Mark all used subroutines + for c in cs.values(): + subrs = getattr(c.private, "Subrs", []) + decompiler = _MarkingT2Decompiler(subrs, c.globalSubrs, c.private) + decompiler.execute(c) + + all_subrs = [font.GlobalSubrs] + if hasattr(font, "FDArray"): + all_subrs.extend( + fd.Private.Subrs + for fd in font.FDArray + if hasattr(fd.Private, "Subrs") and fd.Private.Subrs + ) + elif hasattr(font.Private, "Subrs") and font.Private.Subrs: + all_subrs.append(font.Private.Subrs) + + subrs = set(subrs) # Remove duplicates + + # Prepare + for subrs in all_subrs: + if not hasattr(subrs, "_used"): + subrs._used = set() + subrs._used = _uniq_sort(subrs._used) + subrs._old_bias = calcSubrBias(subrs) + subrs._new_bias = calcSubrBias(subrs._used) + + # Renumber glyph charstrings + for c in cs.values(): + subrs = getattr(c.private, "Subrs", None) + _cs_subset_subroutines(c, subrs, font.GlobalSubrs) + + # Renumber subroutines themselves + for subrs in all_subrs: + if subrs == font.GlobalSubrs: + if not hasattr(font, "FDArray") and hasattr(font.Private, "Subrs"): + local_subrs = font.Private.Subrs + elif ( + hasattr(font, "FDArray") + and len(font.FDArray) == 1 + and hasattr(font.FDArray[0].Private, "Subrs") + ): + # Technically we shouldn't do this. But I've run into fonts that do it. + local_subrs = font.FDArray[0].Private.Subrs + else: + local_subrs = None + else: + local_subrs = subrs + + subrs.items = [subrs.items[i] for i in subrs._used] + if hasattr(subrs, "file"): + del subrs.file + if hasattr(subrs, "offsets"): + del subrs.offsets + + for subr in subrs.items: + _cs_subset_subroutines(subr, local_subrs, font.GlobalSubrs) + + # Delete local SubrsIndex if empty + if hasattr(font, "FDArray"): + for fd in font.FDArray: + _pd_delete_empty_subrs(fd.Private) + else: + _pd_delete_empty_subrs(font.Private) + + # Cleanup + for subrs in all_subrs: + del subrs._used, subrs._old_bias, subrs._new_bias diff --git a/.venv/lib/python3.13/site-packages/fontTools/cffLib/width.py b/.venv/lib/python3.13/site-packages/fontTools/cffLib/width.py new file mode 100644 index 0000000000000000000000000000000000000000..78ff27e4fd85636141cddac2ee8035c0d7e33e03 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/cffLib/width.py @@ -0,0 +1,210 @@ +# -*- coding: utf-8 -*- + +"""T2CharString glyph width optimizer. + +CFF glyphs whose width equals the CFF Private dictionary's ``defaultWidthX`` +value do not need to specify their width in their charstring, saving bytes. +This module determines the optimum ``defaultWidthX`` and ``nominalWidthX`` +values for a font, when provided with a list of glyph widths.""" + +from fontTools.ttLib import TTFont +from collections import defaultdict +from operator import add +from functools import reduce + + +__all__ = ["optimizeWidths", "main"] + + +class missingdict(dict): + def __init__(self, missing_func): + self.missing_func = missing_func + + def __missing__(self, v): + return self.missing_func(v) + + +def cumSum(f, op=add, start=0, decreasing=False): + keys = sorted(f.keys()) + minx, maxx = keys[0], keys[-1] + + total = reduce(op, f.values(), start) + + if decreasing: + missing = lambda x: start if x > maxx else total + domain = range(maxx, minx - 1, -1) + else: + missing = lambda x: start if x < minx else total + domain = range(minx, maxx + 1) + + out = missingdict(missing) + + v = start + for x in domain: + v = op(v, f[x]) + out[x] = v + + return out + + +def byteCost(widths, default, nominal): + if not hasattr(widths, "items"): + d = defaultdict(int) + for w in widths: + d[w] += 1 + widths = d + + cost = 0 + for w, freq in widths.items(): + if w == default: + continue + diff = abs(w - nominal) + if diff <= 107: + cost += freq + elif diff <= 1131: + cost += freq * 2 + else: + cost += freq * 5 + return cost + + +def optimizeWidthsBruteforce(widths): + """Bruteforce version. Veeeeeeeeeeeeeeeeery slow. Only works for smallests of fonts.""" + + d = defaultdict(int) + for w in widths: + d[w] += 1 + + # Maximum number of bytes using default can possibly save + maxDefaultAdvantage = 5 * max(d.values()) + + minw, maxw = min(widths), max(widths) + domain = list(range(minw, maxw + 1)) + + bestCostWithoutDefault = min(byteCost(widths, None, nominal) for nominal in domain) + + bestCost = len(widths) * 5 + 1 + for nominal in domain: + if byteCost(widths, None, nominal) > bestCost + maxDefaultAdvantage: + continue + for default in domain: + cost = byteCost(widths, default, nominal) + if cost < bestCost: + bestCost = cost + bestDefault = default + bestNominal = nominal + + return bestDefault, bestNominal + + +def optimizeWidths(widths): + """Given a list of glyph widths, or dictionary mapping glyph width to number of + glyphs having that, returns a tuple of best CFF default and nominal glyph widths. + + This algorithm is linear in UPEM+numGlyphs.""" + + if not hasattr(widths, "items"): + d = defaultdict(int) + for w in widths: + d[w] += 1 + widths = d + + keys = sorted(widths.keys()) + minw, maxw = keys[0], keys[-1] + domain = list(range(minw, maxw + 1)) + + # Cumulative sum/max forward/backward. + cumFrqU = cumSum(widths, op=add) + cumMaxU = cumSum(widths, op=max) + cumFrqD = cumSum(widths, op=add, decreasing=True) + cumMaxD = cumSum(widths, op=max, decreasing=True) + + # Cost per nominal choice, without default consideration. + nomnCostU = missingdict( + lambda x: cumFrqU[x] + cumFrqU[x - 108] + cumFrqU[x - 1132] * 3 + ) + nomnCostD = missingdict( + lambda x: cumFrqD[x] + cumFrqD[x + 108] + cumFrqD[x + 1132] * 3 + ) + nomnCost = missingdict(lambda x: nomnCostU[x] + nomnCostD[x] - widths[x]) + + # Cost-saving per nominal choice, by best default choice. + dfltCostU = missingdict( + lambda x: max(cumMaxU[x], cumMaxU[x - 108] * 2, cumMaxU[x - 1132] * 5) + ) + dfltCostD = missingdict( + lambda x: max(cumMaxD[x], cumMaxD[x + 108] * 2, cumMaxD[x + 1132] * 5) + ) + dfltCost = missingdict(lambda x: max(dfltCostU[x], dfltCostD[x])) + + # Combined cost per nominal choice. + bestCost = missingdict(lambda x: nomnCost[x] - dfltCost[x]) + + # Best nominal. + nominal = min(domain, key=lambda x: bestCost[x]) + + # Work back the best default. + bestC = bestCost[nominal] + dfltC = nomnCost[nominal] - bestCost[nominal] + ends = [] + if dfltC == dfltCostU[nominal]: + starts = [nominal, nominal - 108, nominal - 1132] + for start in starts: + while cumMaxU[start] and cumMaxU[start] == cumMaxU[start - 1]: + start -= 1 + ends.append(start) + else: + starts = [nominal, nominal + 108, nominal + 1132] + for start in starts: + while cumMaxD[start] and cumMaxD[start] == cumMaxD[start + 1]: + start += 1 + ends.append(start) + default = min(ends, key=lambda default: byteCost(widths, default, nominal)) + + return default, nominal + + +def main(args=None): + """Calculate optimum defaultWidthX/nominalWidthX values""" + + import argparse + + parser = argparse.ArgumentParser( + "fonttools cffLib.width", + description=main.__doc__, + ) + parser.add_argument( + "inputs", metavar="FILE", type=str, nargs="+", help="Input TTF files" + ) + parser.add_argument( + "-b", + "--brute-force", + dest="brute", + action="store_true", + help="Use brute-force approach (VERY slow)", + ) + + args = parser.parse_args(args) + + for fontfile in args.inputs: + font = TTFont(fontfile) + hmtx = font["hmtx"] + widths = [m[0] for m in hmtx.metrics.values()] + if args.brute: + default, nominal = optimizeWidthsBruteforce(widths) + else: + default, nominal = optimizeWidths(widths) + print( + "glyphs=%d default=%d nominal=%d byteCost=%d" + % (len(widths), default, nominal, byteCost(widths, default, nominal)) + ) + + +if __name__ == "__main__": + import sys + + if len(sys.argv) == 1: + import doctest + + sys.exit(doctest.testmod().failed) + main() diff --git a/.venv/lib/python3.13/site-packages/fontTools/feaLib/__init__.py b/.venv/lib/python3.13/site-packages/fontTools/feaLib/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ae532cd31b6eb54bdd5778c13989c1475b643db3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/feaLib/__init__.py @@ -0,0 +1,4 @@ +"""fontTools.feaLib -- a package for dealing with OpenType feature files.""" + +# The structure of OpenType feature files is defined here: +# http://www.adobe.com/devnet/opentype/afdko/topic_feature_file_syntax.html diff --git a/.venv/lib/python3.13/site-packages/fontTools/feaLib/__main__.py b/.venv/lib/python3.13/site-packages/fontTools/feaLib/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..a45230e8dbd8399fdd2a5d292bf71fe96c271b78 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/feaLib/__main__.py @@ -0,0 +1,78 @@ +from fontTools.ttLib import TTFont +from fontTools.feaLib.builder import addOpenTypeFeatures, Builder +from fontTools.feaLib.error import FeatureLibError +from fontTools import configLogger +from fontTools.misc.cliTools import makeOutputFileName +import sys +import argparse +import logging + + +log = logging.getLogger("fontTools.feaLib") + + +def main(args=None): + """Add features from a feature file (.fea) into an OTF font""" + parser = argparse.ArgumentParser( + description="Use fontTools to compile OpenType feature files (*.fea)." + ) + parser.add_argument( + "input_fea", metavar="FEATURES", help="Path to the feature file" + ) + parser.add_argument( + "input_font", metavar="INPUT_FONT", help="Path to the input font" + ) + parser.add_argument( + "-o", + "--output", + dest="output_font", + metavar="OUTPUT_FONT", + help="Path to the output font.", + ) + parser.add_argument( + "-t", + "--tables", + metavar="TABLE_TAG", + choices=Builder.supportedTables, + nargs="+", + help="Specify the table(s) to be built.", + ) + parser.add_argument( + "-d", + "--debug", + action="store_true", + help="Add source-level debugging information to font.", + ) + parser.add_argument( + "-v", + "--verbose", + help="Increase the logger verbosity. Multiple -v " "options are allowed.", + action="count", + default=0, + ) + parser.add_argument( + "--traceback", help="show traceback for exceptions.", action="store_true" + ) + options = parser.parse_args(args) + + levels = ["WARNING", "INFO", "DEBUG"] + configLogger(level=levels[min(len(levels) - 1, options.verbose)]) + + output_font = options.output_font or makeOutputFileName(options.input_font) + log.info("Compiling features to '%s'" % (output_font)) + + font = TTFont(options.input_font) + try: + addOpenTypeFeatures( + font, options.input_fea, tables=options.tables, debug=options.debug + ) + except FeatureLibError as e: + if options.traceback: + raise + log.error(e) + sys.exit(1) + font.save(output_font) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.venv/lib/python3.13/site-packages/fontTools/feaLib/ast.py b/.venv/lib/python3.13/site-packages/fontTools/feaLib/ast.py new file mode 100644 index 0000000000000000000000000000000000000000..2624e6b9d6df656d3caafbf65fad1676c523f58f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/feaLib/ast.py @@ -0,0 +1,2143 @@ +import weakref +from fontTools.feaLib.error import FeatureLibError +from fontTools.feaLib.location import FeatureLibLocation +from fontTools.misc.encodingTools import getEncoding +from fontTools.misc.textTools import byteord, tobytes +from collections import OrderedDict +import itertools + +SHIFT = " " * 4 + +__all__ = [ + "Element", + "FeatureFile", + "Comment", + "GlyphName", + "GlyphClass", + "GlyphClassName", + "MarkClassName", + "AnonymousBlock", + "Block", + "FeatureBlock", + "NestedBlock", + "LookupBlock", + "GlyphClassDefinition", + "GlyphClassDefStatement", + "MarkClass", + "MarkClassDefinition", + "AlternateSubstStatement", + "Anchor", + "AnchorDefinition", + "AttachStatement", + "AxisValueLocationStatement", + "BaseAxis", + "CVParametersNameStatement", + "ChainContextPosStatement", + "ChainContextSubstStatement", + "CharacterStatement", + "ConditionsetStatement", + "CursivePosStatement", + "ElidedFallbackName", + "ElidedFallbackNameID", + "Expression", + "FeatureNameStatement", + "FeatureReferenceStatement", + "FontRevisionStatement", + "HheaField", + "IgnorePosStatement", + "IgnoreSubstStatement", + "IncludeStatement", + "LanguageStatement", + "LanguageSystemStatement", + "LigatureCaretByIndexStatement", + "LigatureCaretByPosStatement", + "LigatureSubstStatement", + "LookupFlagStatement", + "LookupReferenceStatement", + "MarkBasePosStatement", + "MarkLigPosStatement", + "MarkMarkPosStatement", + "MultipleSubstStatement", + "NameRecord", + "OS2Field", + "PairPosStatement", + "ReverseChainSingleSubstStatement", + "ScriptStatement", + "SinglePosStatement", + "SingleSubstStatement", + "SizeParameters", + "Statement", + "STATAxisValueStatement", + "STATDesignAxisStatement", + "STATNameStatement", + "SubtableStatement", + "TableBlock", + "ValueRecord", + "ValueRecordDefinition", + "VheaField", +] + + +def deviceToString(device): + if device is None: + return "" + else: + return "" % ", ".join("%d %d" % t for t in device) + + +fea_keywords = set( + [ + "anchor", + "anchordef", + "anon", + "anonymous", + "by", + "contour", + "cursive", + "device", + "enum", + "enumerate", + "excludedflt", + "exclude_dflt", + "feature", + "from", + "ignore", + "ignorebaseglyphs", + "ignoreligatures", + "ignoremarks", + "include", + "includedflt", + "include_dflt", + "language", + "languagesystem", + "lookup", + "lookupflag", + "mark", + "markattachmenttype", + "markclass", + "nameid", + "null", + "parameters", + "pos", + "position", + "required", + "righttoleft", + "reversesub", + "rsub", + "script", + "sub", + "substitute", + "subtable", + "table", + "usemarkfilteringset", + "useextension", + "valuerecorddef", + "base", + "gdef", + "head", + "hhea", + "name", + "vhea", + "vmtx", + ] +) + + +def asFea(g): + if hasattr(g, "asFea"): + return g.asFea() + elif isinstance(g, tuple) and len(g) == 2: + return asFea(g[0]) + " - " + asFea(g[1]) # a range + elif g.lower() in fea_keywords: + return "\\" + g + else: + return g + + +class Element(object): + """A base class representing "something" in a feature file.""" + + def __init__(self, location=None): + #: location of this element as a `FeatureLibLocation` object. + if location and not isinstance(location, FeatureLibLocation): + location = FeatureLibLocation(*location) + self.location = location + + def build(self, builder): + pass + + def asFea(self, indent=""): + """Returns this element as a string of feature code. For block-type + elements (such as :class:`FeatureBlock`), the `indent` string is + added to the start of each line in the output.""" + raise NotImplementedError + + def __str__(self): + return self.asFea() + + +class Statement(Element): + pass + + +class Expression(Element): + pass + + +class Comment(Element): + """A comment in a feature file.""" + + def __init__(self, text, location=None): + super(Comment, self).__init__(location) + #: Text of the comment + self.text = text + + def asFea(self, indent=""): + return self.text + + +class NullGlyph(Expression): + """The NULL glyph, used in glyph deletion substitutions.""" + + def __init__(self, location=None): + Expression.__init__(self, location) + #: The name itself as a string + + def glyphSet(self): + """The glyphs in this class as a tuple of :class:`GlyphName` objects.""" + return () + + def asFea(self, indent=""): + return "NULL" + + +class GlyphName(Expression): + """A single glyph name, such as ``cedilla``.""" + + def __init__(self, glyph, location=None): + Expression.__init__(self, location) + #: The name itself as a string + self.glyph = glyph + + def glyphSet(self): + """The glyphs in this class as a tuple of :class:`GlyphName` objects.""" + return (self.glyph,) + + def asFea(self, indent=""): + return asFea(self.glyph) + + +class GlyphClass(Expression): + """A glyph class, such as ``[acute cedilla grave]``.""" + + def __init__(self, glyphs=None, location=None): + Expression.__init__(self, location) + #: The list of glyphs in this class, as :class:`GlyphName` objects. + self.glyphs = glyphs if glyphs is not None else [] + self.original = [] + self.curr = 0 + + def glyphSet(self): + """The glyphs in this class as a tuple of :class:`GlyphName` objects.""" + return tuple(self.glyphs) + + def asFea(self, indent=""): + if len(self.original): + if self.curr < len(self.glyphs): + self.original.extend(self.glyphs[self.curr :]) + self.curr = len(self.glyphs) + return "[" + " ".join(map(asFea, self.original)) + "]" + else: + return "[" + " ".join(map(asFea, self.glyphs)) + "]" + + def extend(self, glyphs): + """Add a list of :class:`GlyphName` objects to the class.""" + self.glyphs.extend(glyphs) + + def append(self, glyph): + """Add a single :class:`GlyphName` object to the class.""" + self.glyphs.append(glyph) + + def add_range(self, start, end, glyphs): + """Add a range (e.g. ``A-Z``) to the class. ``start`` and ``end`` + are either :class:`GlyphName` objects or strings representing the + start and end glyphs in the class, and ``glyphs`` is the full list of + :class:`GlyphName` objects in the range.""" + if self.curr < len(self.glyphs): + self.original.extend(self.glyphs[self.curr :]) + self.original.append((start, end)) + self.glyphs.extend(glyphs) + self.curr = len(self.glyphs) + + def add_cid_range(self, start, end, glyphs): + """Add a range to the class by glyph ID. ``start`` and ``end`` are the + initial and final IDs, and ``glyphs`` is the full list of + :class:`GlyphName` objects in the range.""" + if self.curr < len(self.glyphs): + self.original.extend(self.glyphs[self.curr :]) + self.original.append(("\\{}".format(start), "\\{}".format(end))) + self.glyphs.extend(glyphs) + self.curr = len(self.glyphs) + + def add_class(self, gc): + """Add glyphs from the given :class:`GlyphClassName` object to the + class.""" + if self.curr < len(self.glyphs): + self.original.extend(self.glyphs[self.curr :]) + self.original.append(gc) + self.glyphs.extend(gc.glyphSet()) + self.curr = len(self.glyphs) + + +class GlyphClassName(Expression): + """A glyph class name, such as ``@FRENCH_MARKS``. This must be instantiated + with a :class:`GlyphClassDefinition` object.""" + + def __init__(self, glyphclass, location=None): + Expression.__init__(self, location) + assert isinstance(glyphclass, GlyphClassDefinition) + self.glyphclass = glyphclass + + def glyphSet(self): + """The glyphs in this class as a tuple of :class:`GlyphName` objects.""" + return tuple(self.glyphclass.glyphSet()) + + def asFea(self, indent=""): + return "@" + self.glyphclass.name + + +class MarkClassName(Expression): + """A mark class name, such as ``@FRENCH_MARKS`` defined with ``markClass``. + This must be instantiated with a :class:`MarkClass` object.""" + + def __init__(self, markClass, location=None): + Expression.__init__(self, location) + assert isinstance(markClass, MarkClass) + self.markClass = markClass + + def glyphSet(self): + """The glyphs in this class as a tuple of :class:`GlyphName` objects.""" + return self.markClass.glyphSet() + + def asFea(self, indent=""): + return "@" + self.markClass.name + + +class AnonymousBlock(Statement): + """An anonymous data block.""" + + def __init__(self, tag, content, location=None): + Statement.__init__(self, location) + self.tag = tag #: string containing the block's "tag" + self.content = content #: block data as string + + def asFea(self, indent=""): + res = "anon {} {{\n".format(self.tag) + res += self.content + res += "}} {};\n\n".format(self.tag) + return res + + +class Block(Statement): + """A block of statements: feature, lookup, etc.""" + + def __init__(self, location=None): + Statement.__init__(self, location) + self.statements = [] #: Statements contained in the block + + def build(self, builder): + """When handed a 'builder' object of comparable interface to + :class:`fontTools.feaLib.builder`, walks the statements in this + block, calling the builder callbacks.""" + for s in self.statements: + s.build(builder) + + def asFea(self, indent=""): + indent += SHIFT + return ( + indent + + ("\n" + indent).join([s.asFea(indent=indent) for s in self.statements]) + + "\n" + ) + + +class FeatureFile(Block): + """The top-level element of the syntax tree, containing the whole feature + file in its ``statements`` attribute.""" + + def __init__(self): + Block.__init__(self, location=None) + self.markClasses = {} # name --> ast.MarkClass + + def asFea(self, indent=""): + return "\n".join(s.asFea(indent=indent) for s in self.statements) + + +class FeatureBlock(Block): + """A named feature block.""" + + def __init__(self, name, use_extension=False, location=None): + Block.__init__(self, location) + self.name, self.use_extension = name, use_extension + + def build(self, builder): + """Call the ``start_feature`` callback on the builder object, visit + all the statements in this feature, and then call ``end_feature``.""" + builder.start_feature(self.location, self.name, self.use_extension) + # language exclude_dflt statements modify builder.features_ + # limit them to this block with temporary builder.features_ + features = builder.features_ + builder.features_ = {} + Block.build(self, builder) + for key, value in builder.features_.items(): + features.setdefault(key, []).extend(value) + builder.features_ = features + builder.end_feature() + + def asFea(self, indent=""): + res = indent + "feature %s " % self.name.strip() + if self.use_extension: + res += "useExtension " + res += "{\n" + res += Block.asFea(self, indent=indent) + res += indent + "} %s;\n" % self.name.strip() + return res + + +class NestedBlock(Block): + """A block inside another block, for example when found inside a + ``cvParameters`` block.""" + + def __init__(self, tag, block_name, location=None): + Block.__init__(self, location) + self.tag = tag + self.block_name = block_name + + def build(self, builder): + Block.build(self, builder) + if self.block_name == "ParamUILabelNameID": + builder.add_to_cv_num_named_params(self.tag) + + def asFea(self, indent=""): + res = "{}{} {{\n".format(indent, self.block_name) + res += Block.asFea(self, indent=indent) + res += "{}}};\n".format(indent) + return res + + +class LookupBlock(Block): + """A named lookup, containing ``statements``.""" + + def __init__(self, name, use_extension=False, location=None): + Block.__init__(self, location) + self.name, self.use_extension = name, use_extension + + def build(self, builder): + builder.start_lookup_block(self.location, self.name, self.use_extension) + Block.build(self, builder) + builder.end_lookup_block() + + def asFea(self, indent=""): + res = "lookup {} ".format(self.name) + if self.use_extension: + res += "useExtension " + res += "{\n" + res += Block.asFea(self, indent=indent) + res += "{}}} {};\n".format(indent, self.name) + return res + + +class TableBlock(Block): + """A ``table ... { }`` block.""" + + def __init__(self, name, location=None): + Block.__init__(self, location) + self.name = name + + def asFea(self, indent=""): + res = "table {} {{\n".format(self.name.strip()) + res += super(TableBlock, self).asFea(indent=indent) + res += "}} {};\n".format(self.name.strip()) + return res + + +class GlyphClassDefinition(Statement): + """Example: ``@UPPERCASE = [A-Z];``.""" + + def __init__(self, name, glyphs, location=None): + Statement.__init__(self, location) + self.name = name #: class name as a string, without initial ``@`` + self.glyphs = glyphs #: a :class:`GlyphClass` object + + def glyphSet(self): + """The glyphs in this class as a tuple of :class:`GlyphName` objects.""" + return tuple(self.glyphs.glyphSet()) + + def asFea(self, indent=""): + return "@" + self.name + " = " + self.glyphs.asFea() + ";" + + +class GlyphClassDefStatement(Statement): + """Example: ``GlyphClassDef @UPPERCASE, [B], [C], [D];``. The parameters + must be either :class:`GlyphClass` or :class:`GlyphClassName` objects, or + ``None``.""" + + def __init__( + self, baseGlyphs, markGlyphs, ligatureGlyphs, componentGlyphs, location=None + ): + Statement.__init__(self, location) + self.baseGlyphs, self.markGlyphs = (baseGlyphs, markGlyphs) + self.ligatureGlyphs = ligatureGlyphs + self.componentGlyphs = componentGlyphs + + def build(self, builder): + """Calls the builder's ``add_glyphClassDef`` callback.""" + base = self.baseGlyphs.glyphSet() if self.baseGlyphs else tuple() + liga = self.ligatureGlyphs.glyphSet() if self.ligatureGlyphs else tuple() + mark = self.markGlyphs.glyphSet() if self.markGlyphs else tuple() + comp = self.componentGlyphs.glyphSet() if self.componentGlyphs else tuple() + builder.add_glyphClassDef(self.location, base, liga, mark, comp) + + def asFea(self, indent=""): + return "GlyphClassDef {}, {}, {}, {};".format( + self.baseGlyphs.asFea() if self.baseGlyphs else "", + self.ligatureGlyphs.asFea() if self.ligatureGlyphs else "", + self.markGlyphs.asFea() if self.markGlyphs else "", + self.componentGlyphs.asFea() if self.componentGlyphs else "", + ) + + +class MarkClass(object): + """One `or more` ``markClass`` statements for the same mark class. + + While glyph classes can be defined only once, the feature file format + allows expanding mark classes with multiple definitions, each using + different glyphs and anchors. The following are two ``MarkClassDefinitions`` + for the same ``MarkClass``:: + + markClass [acute grave] @FRENCH_ACCENTS; + markClass [cedilla] @FRENCH_ACCENTS; + + The ``MarkClass`` object is therefore just a container for a list of + :class:`MarkClassDefinition` statements. + """ + + def __init__(self, name): + self.name = name + self.definitions = [] + self.glyphs = OrderedDict() # glyph --> ast.MarkClassDefinitions + + def addDefinition(self, definition): + """Add a :class:`MarkClassDefinition` statement to this mark class.""" + assert isinstance(definition, MarkClassDefinition) + self.definitions.append(weakref.proxy(definition)) + for glyph in definition.glyphSet(): + if glyph in self.glyphs: + otherLoc = self.glyphs[glyph].location + if otherLoc is None: + end = "" + else: + end = f" at {otherLoc}" + raise FeatureLibError( + "Glyph %s already defined%s" % (glyph, end), definition.location + ) + self.glyphs[glyph] = definition + + def glyphSet(self): + """The glyphs in this class as a tuple of :class:`GlyphName` objects.""" + return tuple(self.glyphs.keys()) + + def asFea(self, indent=""): + res = "\n".join(d.asFea() for d in self.definitions) + return res + + +class MarkClassDefinition(Statement): + """A single ``markClass`` statement. The ``markClass`` should be a + :class:`MarkClass` object, the ``anchor`` an :class:`Anchor` object, + and the ``glyphs`` parameter should be a `glyph-containing object`_ . + + Example: + + .. code:: python + + mc = MarkClass("FRENCH_ACCENTS") + mc.addDefinition( MarkClassDefinition(mc, Anchor(350, 800), + GlyphClass([ GlyphName("acute"), GlyphName("grave") ]) + ) ) + mc.addDefinition( MarkClassDefinition(mc, Anchor(350, -200), + GlyphClass([ GlyphName("cedilla") ]) + ) ) + + mc.asFea() + # markClass [acute grave] @FRENCH_ACCENTS; + # markClass [cedilla] @FRENCH_ACCENTS; + + """ + + def __init__(self, markClass, anchor, glyphs, location=None): + Statement.__init__(self, location) + assert isinstance(markClass, MarkClass) + assert isinstance(anchor, Anchor) and isinstance(glyphs, Expression) + self.markClass, self.anchor, self.glyphs = markClass, anchor, glyphs + + def glyphSet(self): + """The glyphs in this class as a tuple of :class:`GlyphName` objects.""" + return self.glyphs.glyphSet() + + def asFea(self, indent=""): + return "markClass {} {} @{};".format( + self.glyphs.asFea(), self.anchor.asFea(), self.markClass.name + ) + + +class AlternateSubstStatement(Statement): + """A ``sub ... from ...`` statement. + + ``glyph`` and ``replacement`` should be `glyph-containing objects`_. + ``prefix`` and ``suffix`` should be lists of `glyph-containing objects`_.""" + + def __init__(self, prefix, glyph, suffix, replacement, location=None): + Statement.__init__(self, location) + self.prefix, self.glyph, self.suffix = (prefix, glyph, suffix) + self.replacement = replacement + + def build(self, builder): + """Calls the builder's ``add_alternate_subst`` callback.""" + glyph = self.glyph.glyphSet() + assert len(glyph) == 1, glyph + glyph = list(glyph)[0] + prefix = [p.glyphSet() for p in self.prefix] + suffix = [s.glyphSet() for s in self.suffix] + replacement = self.replacement.glyphSet() + builder.add_alternate_subst(self.location, prefix, glyph, suffix, replacement) + + def asFea(self, indent=""): + res = "sub " + if len(self.prefix) or len(self.suffix): + if len(self.prefix): + res += " ".join(map(asFea, self.prefix)) + " " + res += asFea(self.glyph) + "'" # even though we really only use 1 + if len(self.suffix): + res += " " + " ".join(map(asFea, self.suffix)) + else: + res += asFea(self.glyph) + res += " from " + res += asFea(self.replacement) + res += ";" + return res + + +class Anchor(Expression): + """An ``Anchor`` element, used inside a ``pos`` rule. + + If a ``name`` is given, this will be used in preference to the coordinates. + Other values should be integer. + """ + + def __init__( + self, + x, + y, + name=None, + contourpoint=None, + xDeviceTable=None, + yDeviceTable=None, + location=None, + ): + Expression.__init__(self, location) + self.name = name + self.x, self.y, self.contourpoint = x, y, contourpoint + self.xDeviceTable, self.yDeviceTable = xDeviceTable, yDeviceTable + + def asFea(self, indent=""): + if self.name is not None: + return "".format(self.name) + res = "" + exit = self.exitAnchor.asFea() if self.exitAnchor else "" + return "pos cursive {} {} {};".format(self.glyphclass.asFea(), entry, exit) + + +class FeatureReferenceStatement(Statement): + """Example: ``feature salt;``""" + + def __init__(self, featureName, location=None): + Statement.__init__(self, location) + self.location, self.featureName = (location, featureName) + + def build(self, builder): + """Calls the builder object's ``add_feature_reference`` callback.""" + builder.add_feature_reference(self.location, self.featureName) + + def asFea(self, indent=""): + return "feature {};".format(self.featureName) + + +class IgnorePosStatement(Statement): + """An ``ignore pos`` statement, containing `one or more` contexts to ignore. + + ``chainContexts`` should be a list of ``(prefix, glyphs, suffix)`` tuples, + with each of ``prefix``, ``glyphs`` and ``suffix`` being + `glyph-containing objects`_ .""" + + def __init__(self, chainContexts, location=None): + Statement.__init__(self, location) + self.chainContexts = chainContexts + + def build(self, builder): + """Calls the builder object's ``add_chain_context_pos`` callback on each + rule context.""" + for prefix, glyphs, suffix in self.chainContexts: + prefix = [p.glyphSet() for p in prefix] + glyphs = [g.glyphSet() for g in glyphs] + suffix = [s.glyphSet() for s in suffix] + builder.add_chain_context_pos(self.location, prefix, glyphs, suffix, []) + + def asFea(self, indent=""): + contexts = [] + for prefix, glyphs, suffix in self.chainContexts: + res = "" + if len(prefix) or len(suffix): + if len(prefix): + res += " ".join(map(asFea, prefix)) + " " + res += " ".join(g.asFea() + "'" for g in glyphs) + if len(suffix): + res += " " + " ".join(map(asFea, suffix)) + else: + res += " ".join(map(asFea, glyphs)) + contexts.append(res) + return "ignore pos " + ", ".join(contexts) + ";" + + +class IgnoreSubstStatement(Statement): + """An ``ignore sub`` statement, containing `one or more` contexts to ignore. + + ``chainContexts`` should be a list of ``(prefix, glyphs, suffix)`` tuples, + with each of ``prefix``, ``glyphs`` and ``suffix`` being + `glyph-containing objects`_ .""" + + def __init__(self, chainContexts, location=None): + Statement.__init__(self, location) + self.chainContexts = chainContexts + + def build(self, builder): + """Calls the builder object's ``add_chain_context_subst`` callback on + each rule context.""" + for prefix, glyphs, suffix in self.chainContexts: + prefix = [p.glyphSet() for p in prefix] + glyphs = [g.glyphSet() for g in glyphs] + suffix = [s.glyphSet() for s in suffix] + builder.add_chain_context_subst(self.location, prefix, glyphs, suffix, []) + + def asFea(self, indent=""): + contexts = [] + for prefix, glyphs, suffix in self.chainContexts: + res = "" + if len(prefix): + res += " ".join(map(asFea, prefix)) + " " + res += " ".join(g.asFea() + "'" for g in glyphs) + if len(suffix): + res += " " + " ".join(map(asFea, suffix)) + contexts.append(res) + return "ignore sub " + ", ".join(contexts) + ";" + + +class IncludeStatement(Statement): + """An ``include()`` statement.""" + + def __init__(self, filename, location=None): + super(IncludeStatement, self).__init__(location) + self.filename = filename #: String containing name of file to include + + def build(self): + # TODO: consider lazy-loading the including parser/lexer? + raise FeatureLibError( + "Building an include statement is not implemented yet. " + "Instead, use Parser(..., followIncludes=True) for building.", + self.location, + ) + + def asFea(self, indent=""): + return indent + "include(%s);" % self.filename + + +class LanguageStatement(Statement): + """A ``language`` statement within a feature.""" + + def __init__(self, language, include_default=True, required=False, location=None): + Statement.__init__(self, location) + assert len(language) == 4 + self.language = language #: A four-character language tag + self.include_default = include_default #: If false, "exclude_dflt" + self.required = required + + def build(self, builder): + """Call the builder object's ``set_language`` callback.""" + builder.set_language( + location=self.location, + language=self.language, + include_default=self.include_default, + required=self.required, + ) + + def asFea(self, indent=""): + res = "language {}".format(self.language.strip()) + if not self.include_default: + res += " exclude_dflt" + if self.required: + res += " required" + res += ";" + return res + + +class LanguageSystemStatement(Statement): + """A top-level ``languagesystem`` statement.""" + + def __init__(self, script, language, location=None): + Statement.__init__(self, location) + self.script, self.language = (script, language) + + def build(self, builder): + """Calls the builder object's ``add_language_system`` callback.""" + builder.add_language_system(self.location, self.script, self.language) + + def asFea(self, indent=""): + return "languagesystem {} {};".format(self.script, self.language.strip()) + + +class FontRevisionStatement(Statement): + """A ``head`` table ``FontRevision`` statement. ``revision`` should be a + number, and will be formatted to three significant decimal places.""" + + def __init__(self, revision, location=None): + Statement.__init__(self, location) + self.revision = revision + + def build(self, builder): + builder.set_font_revision(self.location, self.revision) + + def asFea(self, indent=""): + return "FontRevision {:.3f};".format(self.revision) + + +class LigatureCaretByIndexStatement(Statement): + """A ``GDEF`` table ``LigatureCaretByIndex`` statement. ``glyphs`` should be + a `glyph-containing object`_, and ``carets`` should be a list of integers.""" + + def __init__(self, glyphs, carets, location=None): + Statement.__init__(self, location) + self.glyphs, self.carets = (glyphs, carets) + + def build(self, builder): + """Calls the builder object's ``add_ligatureCaretByIndex_`` callback.""" + glyphs = self.glyphs.glyphSet() + builder.add_ligatureCaretByIndex_(self.location, glyphs, set(self.carets)) + + def asFea(self, indent=""): + return "LigatureCaretByIndex {} {};".format( + self.glyphs.asFea(), " ".join(str(x) for x in self.carets) + ) + + +class LigatureCaretByPosStatement(Statement): + """A ``GDEF`` table ``LigatureCaretByPos`` statement. ``glyphs`` should be + a `glyph-containing object`_, and ``carets`` should be a list of integers.""" + + def __init__(self, glyphs, carets, location=None): + Statement.__init__(self, location) + self.glyphs, self.carets = (glyphs, carets) + + def build(self, builder): + """Calls the builder object's ``add_ligatureCaretByPos_`` callback.""" + glyphs = self.glyphs.glyphSet() + builder.add_ligatureCaretByPos_(self.location, glyphs, set(self.carets)) + + def asFea(self, indent=""): + return "LigatureCaretByPos {} {};".format( + self.glyphs.asFea(), " ".join(str(x) for x in self.carets) + ) + + +class LigatureSubstStatement(Statement): + """A chained contextual substitution statement. + + ``prefix``, ``glyphs``, and ``suffix`` should be lists of + `glyph-containing objects`_; ``replacement`` should be a single + `glyph-containing object`_. + + If ``forceChain`` is True, this is expressed as a chaining rule + (e.g. ``sub f' i' by f_i``) even when no context is given.""" + + def __init__(self, prefix, glyphs, suffix, replacement, forceChain, location=None): + Statement.__init__(self, location) + self.prefix, self.glyphs, self.suffix = (prefix, glyphs, suffix) + self.replacement, self.forceChain = replacement, forceChain + + def build(self, builder): + prefix = [p.glyphSet() for p in self.prefix] + glyphs = [g.glyphSet() for g in self.glyphs] + suffix = [s.glyphSet() for s in self.suffix] + builder.add_ligature_subst( + self.location, prefix, glyphs, suffix, self.replacement, self.forceChain + ) + + def asFea(self, indent=""): + res = "sub " + if len(self.prefix) or len(self.suffix) or self.forceChain: + if len(self.prefix): + res += " ".join(g.asFea() for g in self.prefix) + " " + res += " ".join(g.asFea() + "'" for g in self.glyphs) + if len(self.suffix): + res += " " + " ".join(g.asFea() for g in self.suffix) + else: + res += " ".join(g.asFea() for g in self.glyphs) + res += " by " + res += asFea(self.replacement) + res += ";" + return res + + +class LookupFlagStatement(Statement): + """A ``lookupflag`` statement. The ``value`` should be an integer value + representing the flags in use, but not including the ``markAttachment`` + class and ``markFilteringSet`` values, which must be specified as + glyph-containing objects.""" + + def __init__( + self, value=0, markAttachment=None, markFilteringSet=None, location=None + ): + Statement.__init__(self, location) + self.value = value + self.markAttachment = markAttachment + self.markFilteringSet = markFilteringSet + + def build(self, builder): + """Calls the builder object's ``set_lookup_flag`` callback.""" + markAttach = None + if self.markAttachment is not None: + markAttach = self.markAttachment.glyphSet() + markFilter = None + if self.markFilteringSet is not None: + markFilter = self.markFilteringSet.glyphSet() + builder.set_lookup_flag(self.location, self.value, markAttach, markFilter) + + def asFea(self, indent=""): + res = [] + flags = ["RightToLeft", "IgnoreBaseGlyphs", "IgnoreLigatures", "IgnoreMarks"] + curr = 1 + for i in range(len(flags)): + if self.value & curr != 0: + res.append(flags[i]) + curr = curr << 1 + if self.markAttachment is not None: + res.append("MarkAttachmentType {}".format(self.markAttachment.asFea())) + if self.markFilteringSet is not None: + res.append("UseMarkFilteringSet {}".format(self.markFilteringSet.asFea())) + if not res: + res = ["0"] + return "lookupflag {};".format(" ".join(res)) + + +class LookupReferenceStatement(Statement): + """Represents a ``lookup ...;`` statement to include a lookup in a feature. + + The ``lookup`` should be a :class:`LookupBlock` object.""" + + def __init__(self, lookup, location=None): + Statement.__init__(self, location) + self.location, self.lookup = (location, lookup) + + def build(self, builder): + """Calls the builder object's ``add_lookup_call`` callback.""" + builder.add_lookup_call(self.lookup.name) + + def asFea(self, indent=""): + return "lookup {};".format(self.lookup.name) + + +class MarkBasePosStatement(Statement): + """A mark-to-base positioning rule. The ``base`` should be a + `glyph-containing object`_. The ``marks`` should be a list of + (:class:`Anchor`, :class:`MarkClass`) tuples.""" + + def __init__(self, base, marks, location=None): + Statement.__init__(self, location) + self.base, self.marks = base, marks + + def build(self, builder): + """Calls the builder object's ``add_mark_base_pos`` callback.""" + builder.add_mark_base_pos(self.location, self.base.glyphSet(), self.marks) + + def asFea(self, indent=""): + res = "pos base {}".format(self.base.asFea()) + for a, m in self.marks: + res += "\n" + indent + SHIFT + "{} mark @{}".format(a.asFea(), m.name) + res += ";" + return res + + +class MarkLigPosStatement(Statement): + """A mark-to-ligature positioning rule. The ``ligatures`` must be a + `glyph-containing object`_. The ``marks`` should be a list of lists: each + element in the top-level list represents a component glyph, and is made + up of a list of (:class:`Anchor`, :class:`MarkClass`) tuples representing + mark attachment points for that position. + + Example:: + + m1 = MarkClass("TOP_MARKS") + m2 = MarkClass("BOTTOM_MARKS") + # ... add definitions to mark classes... + + glyph = GlyphName("lam_meem_jeem") + marks = [ + [ (Anchor(625,1800), m1) ], # Attachments on 1st component (lam) + [ (Anchor(376,-378), m2) ], # Attachments on 2nd component (meem) + [ ] # No attachments on the jeem + ] + mlp = MarkLigPosStatement(glyph, marks) + + mlp.asFea() + # pos ligature lam_meem_jeem mark @TOP_MARKS + # ligComponent mark @BOTTOM_MARKS; + + """ + + def __init__(self, ligatures, marks, location=None): + Statement.__init__(self, location) + self.ligatures, self.marks = ligatures, marks + + def build(self, builder): + """Calls the builder object's ``add_mark_lig_pos`` callback.""" + builder.add_mark_lig_pos(self.location, self.ligatures.glyphSet(), self.marks) + + def asFea(self, indent=""): + res = "pos ligature {}".format(self.ligatures.asFea()) + ligs = [] + for l in self.marks: + temp = "" + if l is None or not len(l): + temp = "\n" + indent + SHIFT * 2 + "" + else: + for a, m in l: + temp += ( + "\n" + + indent + + SHIFT * 2 + + "{} mark @{}".format(a.asFea(), m.name) + ) + ligs.append(temp) + res += ("\n" + indent + SHIFT + "ligComponent").join(ligs) + res += ";" + return res + + +class MarkMarkPosStatement(Statement): + """A mark-to-mark positioning rule. The ``baseMarks`` must be a + `glyph-containing object`_. The ``marks`` should be a list of + (:class:`Anchor`, :class:`MarkClass`) tuples.""" + + def __init__(self, baseMarks, marks, location=None): + Statement.__init__(self, location) + self.baseMarks, self.marks = baseMarks, marks + + def build(self, builder): + """Calls the builder object's ``add_mark_mark_pos`` callback.""" + builder.add_mark_mark_pos(self.location, self.baseMarks.glyphSet(), self.marks) + + def asFea(self, indent=""): + res = "pos mark {}".format(self.baseMarks.asFea()) + for a, m in self.marks: + res += "\n" + indent + SHIFT + "{} mark @{}".format(a.asFea(), m.name) + res += ";" + return res + + +class MultipleSubstStatement(Statement): + """A multiple substitution statement. + + Args: + prefix: a list of `glyph-containing objects`_. + glyph: a single glyph-containing object. + suffix: a list of glyph-containing objects. + replacement: a list of glyph-containing objects. + forceChain: If true, the statement is expressed as a chaining rule + (e.g. ``sub f' i' by f_i``) even when no context is given. + """ + + def __init__( + self, prefix, glyph, suffix, replacement, forceChain=False, location=None + ): + Statement.__init__(self, location) + self.prefix, self.glyph, self.suffix = prefix, glyph, suffix + self.replacement = replacement + self.forceChain = forceChain + + def build(self, builder): + """Calls the builder object's ``add_multiple_subst`` callback.""" + prefix = [p.glyphSet() for p in self.prefix] + suffix = [s.glyphSet() for s in self.suffix] + if hasattr(self.glyph, "glyphSet"): + originals = self.glyph.glyphSet() + else: + originals = [self.glyph] + count = len(originals) + replaces = [] + for r in self.replacement: + if hasattr(r, "glyphSet"): + replace = r.glyphSet() + else: + replace = [r] + if len(replace) == 1 and len(replace) != count: + replace = replace * count + replaces.append(replace) + replaces = list(zip(*replaces)) + + seen_originals = set() + for i, original in enumerate(originals): + if original not in seen_originals: + seen_originals.add(original) + builder.add_multiple_subst( + self.location, + prefix, + original, + suffix, + replaces and replaces[i] or (), + self.forceChain, + ) + + def asFea(self, indent=""): + res = "sub " + if len(self.prefix) or len(self.suffix) or self.forceChain: + if len(self.prefix): + res += " ".join(map(asFea, self.prefix)) + " " + res += asFea(self.glyph) + "'" + if len(self.suffix): + res += " " + " ".join(map(asFea, self.suffix)) + else: + res += asFea(self.glyph) + replacement = self.replacement or [NullGlyph()] + res += " by " + res += " ".join(map(asFea, replacement)) + res += ";" + return res + + +class PairPosStatement(Statement): + """A pair positioning statement. + + ``glyphs1`` and ``glyphs2`` should be `glyph-containing objects`_. + ``valuerecord1`` should be a :class:`ValueRecord` object; + ``valuerecord2`` should be either a :class:`ValueRecord` object or ``None``. + If ``enumerated`` is true, then this is expressed as an + `enumerated pair `_. + """ + + def __init__( + self, + glyphs1, + valuerecord1, + glyphs2, + valuerecord2, + enumerated=False, + location=None, + ): + Statement.__init__(self, location) + self.enumerated = enumerated + self.glyphs1, self.valuerecord1 = glyphs1, valuerecord1 + self.glyphs2, self.valuerecord2 = glyphs2, valuerecord2 + + def build(self, builder): + """Calls a callback on the builder object: + + * If the rule is enumerated, calls ``add_specific_pair_pos`` on each + combination of first and second glyphs. + * If the glyphs are both single :class:`GlyphName` objects, calls + ``add_specific_pair_pos``. + * Else, calls ``add_class_pair_pos``. + """ + if self.enumerated: + g = [self.glyphs1.glyphSet(), self.glyphs2.glyphSet()] + seen_pair = False + for glyph1, glyph2 in itertools.product(*g): + seen_pair = True + builder.add_specific_pair_pos( + self.location, glyph1, self.valuerecord1, glyph2, self.valuerecord2 + ) + if not seen_pair: + raise FeatureLibError( + "Empty glyph class in positioning rule", self.location + ) + return + + is_specific = isinstance(self.glyphs1, GlyphName) and isinstance( + self.glyphs2, GlyphName + ) + if is_specific: + builder.add_specific_pair_pos( + self.location, + self.glyphs1.glyph, + self.valuerecord1, + self.glyphs2.glyph, + self.valuerecord2, + ) + else: + builder.add_class_pair_pos( + self.location, + self.glyphs1.glyphSet(), + self.valuerecord1, + self.glyphs2.glyphSet(), + self.valuerecord2, + ) + + def asFea(self, indent=""): + res = "enum " if self.enumerated else "" + if self.valuerecord2: + res += "pos {} {} {} {};".format( + self.glyphs1.asFea(), + self.valuerecord1.asFea(), + self.glyphs2.asFea(), + self.valuerecord2.asFea(), + ) + else: + res += "pos {} {} {};".format( + self.glyphs1.asFea(), self.glyphs2.asFea(), self.valuerecord1.asFea() + ) + return res + + +class ReverseChainSingleSubstStatement(Statement): + """A reverse chaining substitution statement. You don't see those every day. + + Note the unusual argument order: ``suffix`` comes `before` ``glyphs``. + ``old_prefix``, ``old_suffix``, ``glyphs`` and ``replacements`` should be + lists of `glyph-containing objects`_. ``glyphs`` and ``replacements`` should + be one-item lists. + """ + + def __init__(self, old_prefix, old_suffix, glyphs, replacements, location=None): + Statement.__init__(self, location) + self.old_prefix, self.old_suffix = old_prefix, old_suffix + self.glyphs = glyphs + self.replacements = replacements + + def build(self, builder): + prefix = [p.glyphSet() for p in self.old_prefix] + suffix = [s.glyphSet() for s in self.old_suffix] + originals = self.glyphs[0].glyphSet() + replaces = self.replacements[0].glyphSet() + if len(replaces) == 1: + replaces = replaces * len(originals) + builder.add_reverse_chain_single_subst( + self.location, prefix, suffix, dict(zip(originals, replaces)) + ) + + def asFea(self, indent=""): + res = "rsub " + if len(self.old_prefix) or len(self.old_suffix): + if len(self.old_prefix): + res += " ".join(asFea(g) for g in self.old_prefix) + " " + res += " ".join(asFea(g) + "'" for g in self.glyphs) + if len(self.old_suffix): + res += " " + " ".join(asFea(g) for g in self.old_suffix) + else: + res += " ".join(map(asFea, self.glyphs)) + res += " by {};".format(" ".join(asFea(g) for g in self.replacements)) + return res + + +class SingleSubstStatement(Statement): + """A single substitution statement. + + Note the unusual argument order: ``prefix`` and suffix come `after` + the replacement ``glyphs``. ``prefix``, ``suffix``, ``glyphs`` and + ``replace`` should be lists of `glyph-containing objects`_. ``glyphs`` and + ``replace`` should be one-item lists. + """ + + def __init__(self, glyphs, replace, prefix, suffix, forceChain, location=None): + Statement.__init__(self, location) + self.prefix, self.suffix = prefix, suffix + self.forceChain = forceChain + self.glyphs = glyphs + self.replacements = replace + + def build(self, builder): + """Calls the builder object's ``add_single_subst`` callback.""" + prefix = [p.glyphSet() for p in self.prefix] + suffix = [s.glyphSet() for s in self.suffix] + originals = self.glyphs[0].glyphSet() + replaces = self.replacements[0].glyphSet() + if len(replaces) == 1: + replaces = replaces * len(originals) + builder.add_single_subst( + self.location, + prefix, + suffix, + OrderedDict(zip(originals, replaces)), + self.forceChain, + ) + + def asFea(self, indent=""): + res = "sub " + if len(self.prefix) or len(self.suffix) or self.forceChain: + if len(self.prefix): + res += " ".join(asFea(g) for g in self.prefix) + " " + res += " ".join(asFea(g) + "'" for g in self.glyphs) + if len(self.suffix): + res += " " + " ".join(asFea(g) for g in self.suffix) + else: + res += " ".join(asFea(g) for g in self.glyphs) + res += " by {};".format(" ".join(asFea(g) for g in self.replacements)) + return res + + +class ScriptStatement(Statement): + """A ``script`` statement.""" + + def __init__(self, script, location=None): + Statement.__init__(self, location) + self.script = script #: the script code + + def build(self, builder): + """Calls the builder's ``set_script`` callback.""" + builder.set_script(self.location, self.script) + + def asFea(self, indent=""): + return "script {};".format(self.script.strip()) + + +class SinglePosStatement(Statement): + """A single position statement. ``prefix`` and ``suffix`` should be + lists of `glyph-containing objects`_. + + ``pos`` should be a one-element list containing a (`glyph-containing object`_, + :class:`ValueRecord`) tuple.""" + + def __init__(self, pos, prefix, suffix, forceChain, location=None): + Statement.__init__(self, location) + self.pos, self.prefix, self.suffix = pos, prefix, suffix + self.forceChain = forceChain + + def build(self, builder): + """Calls the builder object's ``add_single_pos`` callback.""" + prefix = [p.glyphSet() for p in self.prefix] + suffix = [s.glyphSet() for s in self.suffix] + pos = [(g.glyphSet(), value) for g, value in self.pos] + builder.add_single_pos(self.location, prefix, suffix, pos, self.forceChain) + + def asFea(self, indent=""): + res = "pos " + if len(self.prefix) or len(self.suffix) or self.forceChain: + if len(self.prefix): + res += " ".join(map(asFea, self.prefix)) + " " + res += " ".join( + [ + asFea(x[0]) + + "'" + + ((" " + x[1].asFea()) if x[1] is not None else "") + for x in self.pos + ] + ) + if len(self.suffix): + res += " " + " ".join(map(asFea, self.suffix)) + else: + res += " ".join( + [ + asFea(x[0]) + " " + (x[1].asFea() if x[1] is not None else "") + for x in self.pos + ] + ) + res += ";" + return res + + +class SubtableStatement(Statement): + """Represents a subtable break.""" + + def __init__(self, location=None): + Statement.__init__(self, location) + + def build(self, builder): + """Calls the builder objects's ``add_subtable_break`` callback.""" + builder.add_subtable_break(self.location) + + def asFea(self, indent=""): + return "subtable;" + + +class ValueRecord(Expression): + """Represents a value record.""" + + def __init__( + self, + xPlacement=None, + yPlacement=None, + xAdvance=None, + yAdvance=None, + xPlaDevice=None, + yPlaDevice=None, + xAdvDevice=None, + yAdvDevice=None, + vertical=False, + location=None, + ): + Expression.__init__(self, location) + self.xPlacement, self.yPlacement = (xPlacement, yPlacement) + self.xAdvance, self.yAdvance = (xAdvance, yAdvance) + self.xPlaDevice, self.yPlaDevice = (xPlaDevice, yPlaDevice) + self.xAdvDevice, self.yAdvDevice = (xAdvDevice, yAdvDevice) + self.vertical = vertical + + def __eq__(self, other): + return ( + self.xPlacement == other.xPlacement + and self.yPlacement == other.yPlacement + and self.xAdvance == other.xAdvance + and self.yAdvance == other.yAdvance + and self.xPlaDevice == other.xPlaDevice + and self.xAdvDevice == other.xAdvDevice + ) + + def __ne__(self, other): + return not self.__eq__(other) + + def __hash__(self): + return ( + hash(self.xPlacement) + ^ hash(self.yPlacement) + ^ hash(self.xAdvance) + ^ hash(self.yAdvance) + ^ hash(self.xPlaDevice) + ^ hash(self.yPlaDevice) + ^ hash(self.xAdvDevice) + ^ hash(self.yAdvDevice) + ) + + def asFea(self, indent=""): + if not self: + return "" + + x, y = self.xPlacement, self.yPlacement + xAdvance, yAdvance = self.xAdvance, self.yAdvance + xPlaDevice, yPlaDevice = self.xPlaDevice, self.yPlaDevice + xAdvDevice, yAdvDevice = self.xAdvDevice, self.yAdvDevice + vertical = self.vertical + + # Try format A, if possible. + if x is None and y is None: + if xAdvance is None and vertical: + return str(yAdvance) + elif yAdvance is None and not vertical: + return str(xAdvance) + + # Make any remaining None value 0 to avoid generating invalid records. + x = x or 0 + y = y or 0 + xAdvance = xAdvance or 0 + yAdvance = yAdvance or 0 + + # Try format B, if possible. + if ( + xPlaDevice is None + and yPlaDevice is None + and xAdvDevice is None + and yAdvDevice is None + ): + return "<%s %s %s %s>" % (x, y, xAdvance, yAdvance) + + # Last resort is format C. + return "<%s %s %s %s %s %s %s %s>" % ( + x, + y, + xAdvance, + yAdvance, + deviceToString(xPlaDevice), + deviceToString(yPlaDevice), + deviceToString(xAdvDevice), + deviceToString(yAdvDevice), + ) + + def __bool__(self): + return any( + getattr(self, v) is not None + for v in [ + "xPlacement", + "yPlacement", + "xAdvance", + "yAdvance", + "xPlaDevice", + "yPlaDevice", + "xAdvDevice", + "yAdvDevice", + ] + ) + + __nonzero__ = __bool__ + + +class ValueRecordDefinition(Statement): + """Represents a named value record definition.""" + + def __init__(self, name, value, location=None): + Statement.__init__(self, location) + self.name = name #: Value record name as string + self.value = value #: :class:`ValueRecord` object + + def asFea(self, indent=""): + return "valueRecordDef {} {};".format(self.value.asFea(), self.name) + + +def simplify_name_attributes(pid, eid, lid): + if pid == 3 and eid == 1 and lid == 1033: + return "" + elif pid == 1 and eid == 0 and lid == 0: + return "1" + else: + return "{} {} {}".format(pid, eid, lid) + + +class NameRecord(Statement): + """Represents a name record. (`Section 9.e. `_)""" + + def __init__(self, nameID, platformID, platEncID, langID, string, location=None): + Statement.__init__(self, location) + self.nameID = nameID #: Name ID as integer (e.g. 9 for designer's name) + self.platformID = platformID #: Platform ID as integer + self.platEncID = platEncID #: Platform encoding ID as integer + self.langID = langID #: Language ID as integer + self.string = string #: Name record value + + def build(self, builder): + """Calls the builder object's ``add_name_record`` callback.""" + builder.add_name_record( + self.location, + self.nameID, + self.platformID, + self.platEncID, + self.langID, + self.string, + ) + + def asFea(self, indent=""): + def escape(c, escape_pattern): + # Also escape U+0022 QUOTATION MARK and U+005C REVERSE SOLIDUS + if c >= 0x20 and c <= 0x7E and c not in (0x22, 0x5C): + return chr(c) + else: + return escape_pattern % c + + encoding = getEncoding(self.platformID, self.platEncID, self.langID) + if encoding is None: + raise FeatureLibError("Unsupported encoding", self.location) + s = tobytes(self.string, encoding=encoding) + if encoding == "utf_16_be": + escaped_string = "".join( + [ + escape(byteord(s[i]) * 256 + byteord(s[i + 1]), r"\%04x") + for i in range(0, len(s), 2) + ] + ) + else: + escaped_string = "".join([escape(byteord(b), r"\%02x") for b in s]) + plat = simplify_name_attributes(self.platformID, self.platEncID, self.langID) + if plat != "": + plat += " " + return 'nameid {} {}"{}";'.format(self.nameID, plat, escaped_string) + + +class FeatureNameStatement(NameRecord): + """Represents a ``sizemenuname`` or ``name`` statement.""" + + def build(self, builder): + """Calls the builder object's ``add_featureName`` callback.""" + NameRecord.build(self, builder) + builder.add_featureName(self.nameID) + + def asFea(self, indent=""): + if self.nameID == "size": + tag = "sizemenuname" + else: + tag = "name" + plat = simplify_name_attributes(self.platformID, self.platEncID, self.langID) + if plat != "": + plat += " " + return '{} {}"{}";'.format(tag, plat, self.string) + + +class STATNameStatement(NameRecord): + """Represents a STAT table ``name`` statement.""" + + def asFea(self, indent=""): + plat = simplify_name_attributes(self.platformID, self.platEncID, self.langID) + if plat != "": + plat += " " + return 'name {}"{}";'.format(plat, self.string) + + +class SizeParameters(Statement): + """A ``parameters`` statement.""" + + def __init__(self, DesignSize, SubfamilyID, RangeStart, RangeEnd, location=None): + Statement.__init__(self, location) + self.DesignSize = DesignSize + self.SubfamilyID = SubfamilyID + self.RangeStart = RangeStart + self.RangeEnd = RangeEnd + + def build(self, builder): + """Calls the builder object's ``set_size_parameters`` callback.""" + builder.set_size_parameters( + self.location, + self.DesignSize, + self.SubfamilyID, + self.RangeStart, + self.RangeEnd, + ) + + def asFea(self, indent=""): + res = "parameters {:.1f} {}".format(self.DesignSize, self.SubfamilyID) + if self.RangeStart != 0 or self.RangeEnd != 0: + res += " {} {}".format(int(self.RangeStart * 10), int(self.RangeEnd * 10)) + return res + ";" + + +class CVParametersNameStatement(NameRecord): + """Represent a name statement inside a ``cvParameters`` block.""" + + def __init__( + self, nameID, platformID, platEncID, langID, string, block_name, location=None + ): + NameRecord.__init__( + self, nameID, platformID, platEncID, langID, string, location=location + ) + self.block_name = block_name + + def build(self, builder): + """Calls the builder object's ``add_cv_parameter`` callback.""" + item = "" + if self.block_name == "ParamUILabelNameID": + item = "_{}".format(builder.cv_num_named_params_.get(self.nameID, 0)) + builder.add_cv_parameter(self.nameID) + self.nameID = (self.nameID, self.block_name + item) + NameRecord.build(self, builder) + + def asFea(self, indent=""): + plat = simplify_name_attributes(self.platformID, self.platEncID, self.langID) + if plat != "": + plat += " " + return 'name {}"{}";'.format(plat, self.string) + + +class CharacterStatement(Statement): + """ + Statement used in cvParameters blocks of Character Variant features (cvXX). + The Unicode value may be written with either decimal or hexadecimal + notation. The value must be preceded by '0x' if it is a hexadecimal value. + The largest Unicode value allowed is 0xFFFFFF. + """ + + def __init__(self, character, tag, location=None): + Statement.__init__(self, location) + self.character = character + self.tag = tag + + def build(self, builder): + """Calls the builder object's ``add_cv_character`` callback.""" + builder.add_cv_character(self.character, self.tag) + + def asFea(self, indent=""): + return "Character {:#x};".format(self.character) + + +class BaseAxis(Statement): + """An axis definition, being either a ``VertAxis.BaseTagList/BaseScriptList`` + pair or a ``HorizAxis.BaseTagList/BaseScriptList`` pair.""" + + def __init__(self, bases, scripts, vertical, minmax=None, location=None): + Statement.__init__(self, location) + self.bases = bases #: A list of baseline tag names as strings + self.scripts = scripts #: A list of script record tuplets (script tag, default baseline tag, base coordinate) + self.vertical = vertical #: Boolean; VertAxis if True, HorizAxis if False + self.minmax = [] #: A set of minmax record + + def build(self, builder): + """Calls the builder object's ``set_base_axis`` callback.""" + builder.set_base_axis(self.bases, self.scripts, self.vertical, self.minmax) + + def asFea(self, indent=""): + direction = "Vert" if self.vertical else "Horiz" + scripts = [ + "{} {} {}".format(a[0], a[1], " ".join(map(str, a[2]))) + for a in self.scripts + ] + minmaxes = [ + "\n{}Axis.MinMax {} {} {}, {};".format(direction, a[0], a[1], a[2], a[3]) + for a in self.minmax + ] + return "{}Axis.BaseTagList {};\n{}{}Axis.BaseScriptList {};".format( + direction, " ".join(self.bases), indent, direction, ", ".join(scripts) + ) + "\n".join(minmaxes) + + +class OS2Field(Statement): + """An entry in the ``OS/2`` table. Most ``values`` should be numbers or + strings, apart from when the key is ``UnicodeRange``, ``CodePageRange`` + or ``Panose``, in which case it should be an array of integers.""" + + def __init__(self, key, value, location=None): + Statement.__init__(self, location) + self.key = key + self.value = value + + def build(self, builder): + """Calls the builder object's ``add_os2_field`` callback.""" + builder.add_os2_field(self.key, self.value) + + def asFea(self, indent=""): + def intarr2str(x): + return " ".join(map(str, x)) + + numbers = ( + "FSType", + "TypoAscender", + "TypoDescender", + "TypoLineGap", + "winAscent", + "winDescent", + "XHeight", + "CapHeight", + "WeightClass", + "WidthClass", + "LowerOpSize", + "UpperOpSize", + ) + ranges = ("UnicodeRange", "CodePageRange") + keywords = dict([(x.lower(), [x, str]) for x in numbers]) + keywords.update([(x.lower(), [x, intarr2str]) for x in ranges]) + keywords["panose"] = ["Panose", intarr2str] + keywords["vendor"] = ["Vendor", lambda y: '"{}"'.format(y)] + if self.key in keywords: + return "{} {};".format( + keywords[self.key][0], keywords[self.key][1](self.value) + ) + return "" # should raise exception + + +class HheaField(Statement): + """An entry in the ``hhea`` table.""" + + def __init__(self, key, value, location=None): + Statement.__init__(self, location) + self.key = key + self.value = value + + def build(self, builder): + """Calls the builder object's ``add_hhea_field`` callback.""" + builder.add_hhea_field(self.key, self.value) + + def asFea(self, indent=""): + fields = ("CaretOffset", "Ascender", "Descender", "LineGap") + keywords = dict([(x.lower(), x) for x in fields]) + return "{} {};".format(keywords[self.key], self.value) + + +class VheaField(Statement): + """An entry in the ``vhea`` table.""" + + def __init__(self, key, value, location=None): + Statement.__init__(self, location) + self.key = key + self.value = value + + def build(self, builder): + """Calls the builder object's ``add_vhea_field`` callback.""" + builder.add_vhea_field(self.key, self.value) + + def asFea(self, indent=""): + fields = ("VertTypoAscender", "VertTypoDescender", "VertTypoLineGap") + keywords = dict([(x.lower(), x) for x in fields]) + return "{} {};".format(keywords[self.key], self.value) + + +class STATDesignAxisStatement(Statement): + """A STAT table Design Axis + + Args: + tag (str): a 4 letter axis tag + axisOrder (int): an int + names (list): a list of :class:`STATNameStatement` objects + """ + + def __init__(self, tag, axisOrder, names, location=None): + Statement.__init__(self, location) + self.tag = tag + self.axisOrder = axisOrder + self.names = names + self.location = location + + def build(self, builder): + builder.addDesignAxis(self, self.location) + + def asFea(self, indent=""): + indent += SHIFT + res = f"DesignAxis {self.tag} {self.axisOrder} {{ \n" + res += ("\n" + indent).join([s.asFea(indent=indent) for s in self.names]) + "\n" + res += "};" + return res + + +class ElidedFallbackName(Statement): + """STAT table ElidedFallbackName + + Args: + names: a list of :class:`STATNameStatement` objects + """ + + def __init__(self, names, location=None): + Statement.__init__(self, location) + self.names = names + self.location = location + + def build(self, builder): + builder.setElidedFallbackName(self.names, self.location) + + def asFea(self, indent=""): + indent += SHIFT + res = "ElidedFallbackName { \n" + res += ("\n" + indent).join([s.asFea(indent=indent) for s in self.names]) + "\n" + res += "};" + return res + + +class ElidedFallbackNameID(Statement): + """STAT table ElidedFallbackNameID + + Args: + value: an int pointing to an existing name table name ID + """ + + def __init__(self, value, location=None): + Statement.__init__(self, location) + self.value = value + self.location = location + + def build(self, builder): + builder.setElidedFallbackName(self.value, self.location) + + def asFea(self, indent=""): + return f"ElidedFallbackNameID {self.value};" + + +class STATAxisValueStatement(Statement): + """A STAT table Axis Value Record + + Args: + names (list): a list of :class:`STATNameStatement` objects + locations (list): a list of :class:`AxisValueLocationStatement` objects + flags (int): an int + """ + + def __init__(self, names, locations, flags, location=None): + Statement.__init__(self, location) + self.names = names + self.locations = locations + self.flags = flags + + def build(self, builder): + builder.addAxisValueRecord(self, self.location) + + def asFea(self, indent=""): + res = "AxisValue {\n" + for location in self.locations: + res += location.asFea() + + for nameRecord in self.names: + res += nameRecord.asFea() + res += "\n" + + if self.flags: + flags = ["OlderSiblingFontAttribute", "ElidableAxisValueName"] + flagStrings = [] + curr = 1 + for i in range(len(flags)): + if self.flags & curr != 0: + flagStrings.append(flags[i]) + curr = curr << 1 + res += f"flag {' '.join(flagStrings)};\n" + res += "};" + return res + + +class AxisValueLocationStatement(Statement): + """ + A STAT table Axis Value Location + + Args: + tag (str): a 4 letter axis tag + values (list): a list of ints and/or floats + """ + + def __init__(self, tag, values, location=None): + Statement.__init__(self, location) + self.tag = tag + self.values = values + + def asFea(self, res=""): + res += f"location {self.tag} " + res += f"{' '.join(str(i) for i in self.values)};\n" + return res + + +class ConditionsetStatement(Statement): + """ + A variable layout conditionset + + Args: + name (str): the name of this conditionset + conditions (dict): a dictionary mapping axis tags to a + tuple of (min,max) userspace coordinates. + """ + + def __init__(self, name, conditions, location=None): + Statement.__init__(self, location) + self.name = name + self.conditions = conditions + + def build(self, builder): + builder.add_conditionset(self.location, self.name, self.conditions) + + def asFea(self, res="", indent=""): + res += indent + f"conditionset {self.name} " + "{\n" + for tag, (minvalue, maxvalue) in self.conditions.items(): + res += indent + SHIFT + f"{tag} {minvalue} {maxvalue};\n" + res += indent + "}" + f" {self.name};\n" + return res + + +class VariationBlock(Block): + """A variation feature block, applicable in a given set of conditions.""" + + def __init__(self, name, conditionset, use_extension=False, location=None): + Block.__init__(self, location) + self.name, self.conditionset, self.use_extension = ( + name, + conditionset, + use_extension, + ) + + def build(self, builder): + """Call the ``start_feature`` callback on the builder object, visit + all the statements in this feature, and then call ``end_feature``.""" + builder.start_feature(self.location, self.name, self.use_extension) + if ( + self.conditionset != "NULL" + and self.conditionset not in builder.conditionsets_ + ): + raise FeatureLibError( + f"variation block used undefined conditionset {self.conditionset}", + self.location, + ) + + # language exclude_dflt statements modify builder.features_ + # limit them to this block with temporary builder.features_ + features = builder.features_ + builder.features_ = {} + Block.build(self, builder) + for key, value in builder.features_.items(): + items = builder.feature_variations_.setdefault(key, {}).setdefault( + self.conditionset, [] + ) + items.extend(value) + if key not in features: + features[key] = [] # Ensure we make a feature record + builder.features_ = features + builder.end_feature() + + def asFea(self, indent=""): + res = indent + "variation %s " % self.name.strip() + res += self.conditionset + " " + if self.use_extension: + res += "useExtension " + res += "{\n" + res += Block.asFea(self, indent=indent) + res += indent + "} %s;\n" % self.name.strip() + return res diff --git a/.venv/lib/python3.13/site-packages/fontTools/feaLib/builder.py b/.venv/lib/python3.13/site-packages/fontTools/feaLib/builder.py new file mode 100644 index 0000000000000000000000000000000000000000..21b7f5bdf2630f726d936a209cedf0062f83698d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/feaLib/builder.py @@ -0,0 +1,1814 @@ +from fontTools.misc import sstruct +from fontTools.misc.textTools import Tag, tostr, binary2num, safeEval +from fontTools.feaLib.error import FeatureLibError +from fontTools.feaLib.lookupDebugInfo import ( + LookupDebugInfo, + LOOKUP_DEBUG_INFO_KEY, + LOOKUP_DEBUG_ENV_VAR, +) +from fontTools.feaLib.parser import Parser +from fontTools.feaLib.ast import FeatureFile +from fontTools.feaLib.variableScalar import VariableScalar +from fontTools.otlLib import builder as otl +from fontTools.otlLib.maxContextCalc import maxCtxFont +from fontTools.ttLib import newTable, getTableModule +from fontTools.ttLib.tables import otBase, otTables +from fontTools.otlLib.builder import ( + AlternateSubstBuilder, + ChainContextPosBuilder, + ChainContextSubstBuilder, + LigatureSubstBuilder, + MultipleSubstBuilder, + CursivePosBuilder, + MarkBasePosBuilder, + MarkLigPosBuilder, + MarkMarkPosBuilder, + ReverseChainSingleSubstBuilder, + SingleSubstBuilder, + ClassPairPosSubtableBuilder, + PairPosBuilder, + SinglePosBuilder, + ChainContextualRule, + AnySubstBuilder, +) +from fontTools.otlLib.error import OpenTypeLibError +from fontTools.varLib.errors import VarLibError +from fontTools.varLib.varStore import OnlineVarStoreBuilder +from fontTools.varLib.builder import buildVarDevTable +from fontTools.varLib.featureVars import addFeatureVariationsRaw +from fontTools.varLib.models import normalizeValue, piecewiseLinearMap +from collections import defaultdict +import copy +import itertools +from io import StringIO +import logging +import warnings +import os + + +log = logging.getLogger(__name__) + + +def addOpenTypeFeatures(font, featurefile, tables=None, debug=False): + """Add features from a file to a font. Note that this replaces any features + currently present. + + Args: + font (feaLib.ttLib.TTFont): The font object. + featurefile: Either a path or file object (in which case we + parse it into an AST), or a pre-parsed AST instance. + tables: If passed, restrict the set of affected tables to those in the + list. + debug: Whether to add source debugging information to the font in the + ``Debg`` table + + """ + builder = Builder(font, featurefile) + builder.build(tables=tables, debug=debug) + + +def addOpenTypeFeaturesFromString( + font, features, filename=None, tables=None, debug=False +): + """Add features from a string to a font. Note that this replaces any + features currently present. + + Args: + font (feaLib.ttLib.TTFont): The font object. + features: A string containing feature code. + filename: The directory containing ``filename`` is used as the root of + relative ``include()`` paths; if ``None`` is provided, the current + directory is assumed. + tables: If passed, restrict the set of affected tables to those in the + list. + debug: Whether to add source debugging information to the font in the + ``Debg`` table + + """ + + featurefile = StringIO(tostr(features)) + if filename: + featurefile.name = filename + addOpenTypeFeatures(font, featurefile, tables=tables, debug=debug) + + +class Builder(object): + supportedTables = frozenset( + Tag(tag) + for tag in [ + "BASE", + "GDEF", + "GPOS", + "GSUB", + "OS/2", + "head", + "hhea", + "name", + "vhea", + "STAT", + ] + ) + + def __init__(self, font, featurefile): + self.font = font + # 'featurefile' can be either a path or file object (in which case we + # parse it into an AST), or a pre-parsed AST instance + if isinstance(featurefile, FeatureFile): + self.parseTree, self.file = featurefile, None + else: + self.parseTree, self.file = None, featurefile + self.glyphMap = font.getReverseGlyphMap() + self.varstorebuilder = None + if "fvar" in font: + self.axes = font["fvar"].axes + self.varstorebuilder = OnlineVarStoreBuilder( + [ax.axisTag for ax in self.axes] + ) + self.default_language_systems_ = set() + self.script_ = None + self.lookupflag_ = 0 + self.lookupflag_markFilterSet_ = None + self.use_extension_ = False + self.language_systems = set() + self.seen_non_DFLT_script_ = False + self.named_lookups_ = {} + self.cur_lookup_ = None + self.cur_lookup_name_ = None + self.cur_feature_name_ = None + self.lookups_ = [] + self.lookup_locations = {"GSUB": {}, "GPOS": {}} + self.features_ = {} # ('latn', 'DEU ', 'smcp') --> [LookupBuilder*] + self.required_features_ = {} # ('latn', 'DEU ') --> 'scmp' + self.feature_variations_ = {} + # for feature 'aalt' + self.aalt_features_ = [] # [(location, featureName)*], for 'aalt' + self.aalt_location_ = None + self.aalt_alternates_ = {} + self.aalt_use_extension_ = False + # for 'featureNames' + self.featureNames_ = set() + self.featureNames_ids_ = {} + # for 'cvParameters' + self.cv_parameters_ = set() + self.cv_parameters_ids_ = {} + self.cv_num_named_params_ = {} + self.cv_characters_ = defaultdict(list) + # for feature 'size' + self.size_parameters_ = None + # for table 'head' + self.fontRevision_ = None # 2.71 + # for table 'name' + self.names_ = [] + # for table 'BASE' + self.base_horiz_axis_ = None + self.base_vert_axis_ = None + # for table 'GDEF' + self.attachPoints_ = {} # "a" --> {3, 7} + self.ligCaretCoords_ = {} # "f_f_i" --> {300, 600} + self.ligCaretPoints_ = {} # "f_f_i" --> {3, 7} + self.glyphClassDefs_ = {} # "fi" --> (2, (file, line, column)) + self.markAttach_ = {} # "acute" --> (4, (file, line, column)) + self.markAttachClassID_ = {} # frozenset({"acute", "grave"}) --> 4 + self.markFilterSets_ = {} # frozenset({"acute", "grave"}) --> 4 + # for table 'OS/2' + self.os2_ = {} + # for table 'hhea' + self.hhea_ = {} + # for table 'vhea' + self.vhea_ = {} + # for table 'STAT' + self.stat_ = {} + # for conditionsets + self.conditionsets_ = {} + # We will often use exactly the same locations (i.e. the font's masters) + # for a large number of variable scalars. Instead of creating a model + # for each, let's share the models. + self.model_cache = {} + + def build(self, tables=None, debug=False): + if self.parseTree is None: + self.parseTree = Parser(self.file, self.glyphMap).parse() + self.parseTree.build(self) + # by default, build all the supported tables + if tables is None: + tables = self.supportedTables + else: + tables = frozenset(tables) + unsupported = tables - self.supportedTables + if unsupported: + unsupported_string = ", ".join(sorted(unsupported)) + raise NotImplementedError( + "The following tables were requested but are unsupported: " + f"{unsupported_string}." + ) + if "GSUB" in tables: + self.build_feature_aalt_() + if "head" in tables: + self.build_head() + if "hhea" in tables: + self.build_hhea() + if "vhea" in tables: + self.build_vhea() + if "name" in tables: + self.build_name() + if "OS/2" in tables: + self.build_OS_2() + if "STAT" in tables: + self.build_STAT() + for tag in ("GPOS", "GSUB"): + if tag not in tables: + continue + table = self.makeTable(tag) + if self.feature_variations_: + self.makeFeatureVariations(table, tag) + if ( + table.ScriptList.ScriptCount > 0 + or table.FeatureList.FeatureCount > 0 + or table.LookupList.LookupCount > 0 + ): + fontTable = self.font[tag] = newTable(tag) + fontTable.table = table + elif tag in self.font: + del self.font[tag] + if any(tag in self.font for tag in ("GPOS", "GSUB")) and "OS/2" in self.font: + self.font["OS/2"].usMaxContext = maxCtxFont(self.font) + if "GDEF" in tables: + gdef = self.buildGDEF() + if gdef: + self.font["GDEF"] = gdef + elif "GDEF" in self.font: + del self.font["GDEF"] + if "BASE" in tables: + base = self.buildBASE() + if base: + self.font["BASE"] = base + elif "BASE" in self.font: + del self.font["BASE"] + if debug or os.environ.get(LOOKUP_DEBUG_ENV_VAR): + self.buildDebg() + + def get_chained_lookup_(self, location, builder_class): + result = builder_class(self.font, location) + result.lookupflag = self.lookupflag_ + result.markFilterSet = self.lookupflag_markFilterSet_ + result.extension = self.use_extension_ + self.lookups_.append(result) + return result + + def add_lookup_to_feature_(self, lookup, feature_name): + for script, lang in self.language_systems: + key = (script, lang, feature_name) + self.features_.setdefault(key, []).append(lookup) + + def get_lookup_(self, location, builder_class, mapping=None): + if ( + self.cur_lookup_ + and type(self.cur_lookup_) == builder_class + and self.cur_lookup_.lookupflag == self.lookupflag_ + and self.cur_lookup_.markFilterSet == self.lookupflag_markFilterSet_ + and self.cur_lookup_.can_add_mapping(mapping) + ): + return self.cur_lookup_ + if self.cur_lookup_name_ and self.cur_lookup_: + raise FeatureLibError( + "Within a named lookup block, all rules must be of " + "the same lookup type and flag", + location, + ) + self.cur_lookup_ = builder_class(self.font, location) + self.cur_lookup_.lookupflag = self.lookupflag_ + self.cur_lookup_.markFilterSet = self.lookupflag_markFilterSet_ + self.cur_lookup_.extension = self.use_extension_ + self.lookups_.append(self.cur_lookup_) + if self.cur_lookup_name_: + # We are starting a lookup rule inside a named lookup block. + self.named_lookups_[self.cur_lookup_name_] = self.cur_lookup_ + if self.cur_feature_name_: + # We are starting a lookup rule inside a feature. This includes + # lookup rules inside named lookups inside features. + self.add_lookup_to_feature_(self.cur_lookup_, self.cur_feature_name_) + return self.cur_lookup_ + + def build_feature_aalt_(self): + if not self.aalt_features_ and not self.aalt_alternates_: + return + # > alternate glyphs will be sorted in the order that the source features + # > are named in the aalt definition, not the order of the feature definitions + # > in the file. Alternates defined explicitly ... will precede all others. + # https://github.com/fonttools/fonttools/issues/836 + alternates = {g: list(a) for g, a in self.aalt_alternates_.items()} + for location, name in self.aalt_features_ + [(None, "aalt")]: + feature = [ + (script, lang, feature, lookups) + for (script, lang, feature), lookups in self.features_.items() + if feature == name + ] + # "aalt" does not have to specify its own lookups, but it might. + if not feature and name != "aalt": + warnings.warn("%s: Feature %s has not been defined" % (location, name)) + continue + for script, lang, feature, lookups in feature: + for lookuplist in lookups: + if not isinstance(lookuplist, list): + lookuplist = [lookuplist] + for lookup in lookuplist: + for glyph, alts in lookup.getAlternateGlyphs().items(): + alts_for_glyph = alternates.setdefault(glyph, []) + alts_for_glyph.extend( + g for g in alts if g not in alts_for_glyph + ) + single = { + glyph: repl[0] for glyph, repl in alternates.items() if len(repl) == 1 + } + multi = {glyph: repl for glyph, repl in alternates.items() if len(repl) > 1} + if not single and not multi: + return + self.features_ = { + (script, lang, feature): lookups + for (script, lang, feature), lookups in self.features_.items() + if feature != "aalt" + } + old_lookups = self.lookups_ + self.lookups_ = [] + self.start_feature(self.aalt_location_, "aalt", self.aalt_use_extension_) + if single: + single_lookup = self.get_lookup_(location, SingleSubstBuilder) + single_lookup.mapping = single + if multi: + multi_lookup = self.get_lookup_(location, AlternateSubstBuilder) + multi_lookup.alternates = multi + self.end_feature() + self.lookups_.extend(old_lookups) + + def build_head(self): + if not self.fontRevision_: + return + table = self.font.get("head") + if not table: # this only happens for unit tests + table = self.font["head"] = newTable("head") + table.decompile(b"\0" * 54, self.font) + table.tableVersion = 1.0 + table.magicNumber = 0x5F0F3CF5 + table.created = table.modified = 3406620153 # 2011-12-13 11:22:33 + table.fontRevision = self.fontRevision_ + + def build_hhea(self): + if not self.hhea_: + return + table = self.font.get("hhea") + if not table: # this only happens for unit tests + table = self.font["hhea"] = newTable("hhea") + table.decompile(b"\0" * 36, self.font) + table.tableVersion = 0x00010000 + if "caretoffset" in self.hhea_: + table.caretOffset = self.hhea_["caretoffset"] + if "ascender" in self.hhea_: + table.ascent = self.hhea_["ascender"] + if "descender" in self.hhea_: + table.descent = self.hhea_["descender"] + if "linegap" in self.hhea_: + table.lineGap = self.hhea_["linegap"] + + def build_vhea(self): + if not self.vhea_: + return + table = self.font.get("vhea") + if not table: # this only happens for unit tests + table = self.font["vhea"] = newTable("vhea") + table.decompile(b"\0" * 36, self.font) + table.tableVersion = 0x00011000 + if "verttypoascender" in self.vhea_: + table.ascent = self.vhea_["verttypoascender"] + if "verttypodescender" in self.vhea_: + table.descent = self.vhea_["verttypodescender"] + if "verttypolinegap" in self.vhea_: + table.lineGap = self.vhea_["verttypolinegap"] + + def get_user_name_id(self, table): + # Try to find first unused font-specific name id + nameIDs = [name.nameID for name in table.names] + for user_name_id in range(256, 32767): + if user_name_id not in nameIDs: + return user_name_id + + def buildFeatureParams(self, tag): + params = None + if tag == "size": + params = otTables.FeatureParamsSize() + ( + params.DesignSize, + params.SubfamilyID, + params.RangeStart, + params.RangeEnd, + ) = self.size_parameters_ + if tag in self.featureNames_ids_: + params.SubfamilyNameID = self.featureNames_ids_[tag] + else: + params.SubfamilyNameID = 0 + elif tag in self.featureNames_: + if not self.featureNames_ids_: + # name table wasn't selected among the tables to build; skip + pass + else: + assert tag in self.featureNames_ids_ + params = otTables.FeatureParamsStylisticSet() + params.Version = 0 + params.UINameID = self.featureNames_ids_[tag] + elif tag in self.cv_parameters_: + params = otTables.FeatureParamsCharacterVariants() + params.Format = 0 + params.FeatUILabelNameID = self.cv_parameters_ids_.get( + (tag, "FeatUILabelNameID"), 0 + ) + params.FeatUITooltipTextNameID = self.cv_parameters_ids_.get( + (tag, "FeatUITooltipTextNameID"), 0 + ) + params.SampleTextNameID = self.cv_parameters_ids_.get( + (tag, "SampleTextNameID"), 0 + ) + params.NumNamedParameters = self.cv_num_named_params_.get(tag, 0) + params.FirstParamUILabelNameID = self.cv_parameters_ids_.get( + (tag, "ParamUILabelNameID_0"), 0 + ) + params.CharCount = len(self.cv_characters_[tag]) + params.Character = self.cv_characters_[tag] + return params + + def build_name(self): + if not self.names_: + return + table = self.font.get("name") + if not table: # this only happens for unit tests + table = self.font["name"] = newTable("name") + table.names = [] + for name in self.names_: + nameID, platformID, platEncID, langID, string = name + # For featureNames block, nameID is 'feature tag' + # For cvParameters blocks, nameID is ('feature tag', 'block name') + if not isinstance(nameID, int): + tag = nameID + if tag in self.featureNames_: + if tag not in self.featureNames_ids_: + self.featureNames_ids_[tag] = self.get_user_name_id(table) + assert self.featureNames_ids_[tag] is not None + nameID = self.featureNames_ids_[tag] + elif tag[0] in self.cv_parameters_: + if tag not in self.cv_parameters_ids_: + self.cv_parameters_ids_[tag] = self.get_user_name_id(table) + assert self.cv_parameters_ids_[tag] is not None + nameID = self.cv_parameters_ids_[tag] + table.setName(string, nameID, platformID, platEncID, langID) + table.names.sort() + + def build_OS_2(self): + if not self.os2_: + return + table = self.font.get("OS/2") + if not table: # this only happens for unit tests + table = self.font["OS/2"] = newTable("OS/2") + data = b"\0" * sstruct.calcsize(getTableModule("OS/2").OS2_format_0) + table.decompile(data, self.font) + version = 0 + if "fstype" in self.os2_: + table.fsType = self.os2_["fstype"] + if "panose" in self.os2_: + panose = getTableModule("OS/2").Panose() + ( + panose.bFamilyType, + panose.bSerifStyle, + panose.bWeight, + panose.bProportion, + panose.bContrast, + panose.bStrokeVariation, + panose.bArmStyle, + panose.bLetterForm, + panose.bMidline, + panose.bXHeight, + ) = self.os2_["panose"] + table.panose = panose + if "typoascender" in self.os2_: + table.sTypoAscender = self.os2_["typoascender"] + if "typodescender" in self.os2_: + table.sTypoDescender = self.os2_["typodescender"] + if "typolinegap" in self.os2_: + table.sTypoLineGap = self.os2_["typolinegap"] + if "winascent" in self.os2_: + table.usWinAscent = self.os2_["winascent"] + if "windescent" in self.os2_: + table.usWinDescent = self.os2_["windescent"] + if "vendor" in self.os2_: + table.achVendID = safeEval("'''" + self.os2_["vendor"] + "'''") + if "weightclass" in self.os2_: + table.usWeightClass = self.os2_["weightclass"] + if "widthclass" in self.os2_: + table.usWidthClass = self.os2_["widthclass"] + if "unicoderange" in self.os2_: + table.setUnicodeRanges(self.os2_["unicoderange"]) + if "codepagerange" in self.os2_: + pages = self.build_codepages_(self.os2_["codepagerange"]) + table.ulCodePageRange1, table.ulCodePageRange2 = pages + version = 1 + if "xheight" in self.os2_: + table.sxHeight = self.os2_["xheight"] + version = 2 + if "capheight" in self.os2_: + table.sCapHeight = self.os2_["capheight"] + version = 2 + if "loweropsize" in self.os2_: + table.usLowerOpticalPointSize = self.os2_["loweropsize"] + version = 5 + if "upperopsize" in self.os2_: + table.usUpperOpticalPointSize = self.os2_["upperopsize"] + version = 5 + + def checkattr(table, attrs): + for attr in attrs: + if not hasattr(table, attr): + setattr(table, attr, 0) + + table.version = max(version, table.version) + # this only happens for unit tests + if version >= 1: + checkattr(table, ("ulCodePageRange1", "ulCodePageRange2")) + if version >= 2: + checkattr( + table, + ( + "sxHeight", + "sCapHeight", + "usDefaultChar", + "usBreakChar", + "usMaxContext", + ), + ) + if version >= 5: + checkattr(table, ("usLowerOpticalPointSize", "usUpperOpticalPointSize")) + + def setElidedFallbackName(self, value, location): + # ElidedFallbackName is a convenience method for setting + # ElidedFallbackNameID so only one can be allowed + for token in ("ElidedFallbackName", "ElidedFallbackNameID"): + if token in self.stat_: + raise FeatureLibError( + f"{token} is already set.", + location, + ) + if isinstance(value, int): + self.stat_["ElidedFallbackNameID"] = value + elif isinstance(value, list): + self.stat_["ElidedFallbackName"] = value + else: + raise AssertionError(value) + + def addDesignAxis(self, designAxis, location): + if "DesignAxes" not in self.stat_: + self.stat_["DesignAxes"] = [] + if designAxis.tag in (r.tag for r in self.stat_["DesignAxes"]): + raise FeatureLibError( + f'DesignAxis already defined for tag "{designAxis.tag}".', + location, + ) + if designAxis.axisOrder in (r.axisOrder for r in self.stat_["DesignAxes"]): + raise FeatureLibError( + f"DesignAxis already defined for axis number {designAxis.axisOrder}.", + location, + ) + self.stat_["DesignAxes"].append(designAxis) + + def addAxisValueRecord(self, axisValueRecord, location): + if "AxisValueRecords" not in self.stat_: + self.stat_["AxisValueRecords"] = [] + # Check for duplicate AxisValueRecords + for record_ in self.stat_["AxisValueRecords"]: + if ( + {n.asFea() for n in record_.names} + == {n.asFea() for n in axisValueRecord.names} + and {n.asFea() for n in record_.locations} + == {n.asFea() for n in axisValueRecord.locations} + and record_.flags == axisValueRecord.flags + ): + raise FeatureLibError( + "An AxisValueRecord with these values is already defined.", + location, + ) + self.stat_["AxisValueRecords"].append(axisValueRecord) + + def build_STAT(self): + if not self.stat_: + return + + axes = self.stat_.get("DesignAxes") + if not axes: + raise FeatureLibError("DesignAxes not defined", None) + axisValueRecords = self.stat_.get("AxisValueRecords") + axisValues = {} + format4_locations = [] + for tag in axes: + axisValues[tag.tag] = [] + if axisValueRecords is not None: + for avr in axisValueRecords: + valuesDict = {} + if avr.flags > 0: + valuesDict["flags"] = avr.flags + if len(avr.locations) == 1: + location = avr.locations[0] + values = location.values + if len(values) == 1: # format1 + valuesDict.update({"value": values[0], "name": avr.names}) + if len(values) == 2: # format3 + valuesDict.update( + { + "value": values[0], + "linkedValue": values[1], + "name": avr.names, + } + ) + if len(values) == 3: # format2 + nominal, minVal, maxVal = values + valuesDict.update( + { + "nominalValue": nominal, + "rangeMinValue": minVal, + "rangeMaxValue": maxVal, + "name": avr.names, + } + ) + axisValues[location.tag].append(valuesDict) + else: + valuesDict.update( + { + "location": {i.tag: i.values[0] for i in avr.locations}, + "name": avr.names, + } + ) + format4_locations.append(valuesDict) + + designAxes = [ + { + "ordering": a.axisOrder, + "tag": a.tag, + "name": a.names, + "values": axisValues[a.tag], + } + for a in axes + ] + + nameTable = self.font.get("name") + if not nameTable: # this only happens for unit tests + nameTable = self.font["name"] = newTable("name") + nameTable.names = [] + + if "ElidedFallbackNameID" in self.stat_: + nameID = self.stat_["ElidedFallbackNameID"] + name = nameTable.getDebugName(nameID) + if not name: + raise FeatureLibError( + f"ElidedFallbackNameID {nameID} points " + "to a nameID that does not exist in the " + '"name" table', + None, + ) + elif "ElidedFallbackName" in self.stat_: + nameID = self.stat_["ElidedFallbackName"] + + otl.buildStatTable( + self.font, + designAxes, + locations=format4_locations, + elidedFallbackName=nameID, + ) + + def build_codepages_(self, pages): + pages2bits = { + 1252: 0, + 1250: 1, + 1251: 2, + 1253: 3, + 1254: 4, + 1255: 5, + 1256: 6, + 1257: 7, + 1258: 8, + 874: 16, + 932: 17, + 936: 18, + 949: 19, + 950: 20, + 1361: 21, + 869: 48, + 866: 49, + 865: 50, + 864: 51, + 863: 52, + 862: 53, + 861: 54, + 860: 55, + 857: 56, + 855: 57, + 852: 58, + 775: 59, + 737: 60, + 708: 61, + 850: 62, + 437: 63, + } + bits = [pages2bits[p] for p in pages if p in pages2bits] + pages = [] + for i in range(2): + pages.append("") + for j in range(i * 32, (i + 1) * 32): + if j in bits: + pages[i] += "1" + else: + pages[i] += "0" + return [binary2num(p[::-1]) for p in pages] + + def buildBASE(self): + if not self.base_horiz_axis_ and not self.base_vert_axis_: + return None + base = otTables.BASE() + base.Version = 0x00010000 + base.HorizAxis = self.buildBASEAxis(self.base_horiz_axis_) + base.VertAxis = self.buildBASEAxis(self.base_vert_axis_) + + result = newTable("BASE") + result.table = base + return result + + def buildBASECoord(self, c): + coord = otTables.BaseCoord() + coord.Format = 1 + coord.Coordinate = c + return coord + + def buildBASEAxis(self, axis): + if not axis: + return + bases, scripts, minmax = axis + axis = otTables.Axis() + axis.BaseTagList = otTables.BaseTagList() + axis.BaseTagList.BaselineTag = bases + axis.BaseTagList.BaseTagCount = len(bases) + axis.BaseScriptList = otTables.BaseScriptList() + axis.BaseScriptList.BaseScriptRecord = [] + axis.BaseScriptList.BaseScriptCount = len(scripts) + for script in sorted(scripts): + minmax_for_script = [ + record[1:] for record in minmax if record[0] == script[0] + ] + record = otTables.BaseScriptRecord() + record.BaseScriptTag = script[0] + record.BaseScript = otTables.BaseScript() + record.BaseScript.BaseValues = otTables.BaseValues() + record.BaseScript.BaseValues.DefaultIndex = bases.index(script[1]) + record.BaseScript.BaseValues.BaseCoord = [] + record.BaseScript.BaseValues.BaseCoordCount = len(script[2]) + record.BaseScript.BaseLangSysRecord = [] + + for c in script[2]: + record.BaseScript.BaseValues.BaseCoord.append(self.buildBASECoord(c)) + for language, min_coord, max_coord in sorted(minmax_for_script): + minmax_record = otTables.MinMax() + minmax_record.MinCoord = self.buildBASECoord(min_coord) + minmax_record.MaxCoord = self.buildBASECoord(max_coord) + minmax_record.FeatMinMaxCount = 0 + if language == "dflt": + record.BaseScript.DefaultMinMax = minmax_record + else: + lang_record = otTables.BaseLangSysRecord() + lang_record.BaseLangSysTag = language + lang_record.MinMax = minmax_record + record.BaseScript.BaseLangSysRecord.append(lang_record) + record.BaseScript.BaseLangSysCount = len( + record.BaseScript.BaseLangSysRecord + ) + axis.BaseScriptList.BaseScriptRecord.append(record) + return axis + + def buildGDEF(self): + gdef = otTables.GDEF() + gdef.GlyphClassDef = self.buildGDEFGlyphClassDef_() + gdef.AttachList = otl.buildAttachList(self.attachPoints_, self.glyphMap) + gdef.LigCaretList = otl.buildLigCaretList( + self.ligCaretCoords_, self.ligCaretPoints_, self.glyphMap + ) + gdef.MarkAttachClassDef = self.buildGDEFMarkAttachClassDef_() + gdef.MarkGlyphSetsDef = self.buildGDEFMarkGlyphSetsDef_() + gdef.Version = 0x00010002 if gdef.MarkGlyphSetsDef else 0x00010000 + if self.varstorebuilder: + store = self.varstorebuilder.finish() + if store: + gdef.Version = 0x00010003 + gdef.VarStore = store + varidx_map = store.optimize() + + gdef.remap_device_varidxes(varidx_map) + if "GPOS" in self.font: + self.font["GPOS"].table.remap_device_varidxes(varidx_map) + self.model_cache.clear() + if any( + ( + gdef.GlyphClassDef, + gdef.AttachList, + gdef.LigCaretList, + gdef.MarkAttachClassDef, + gdef.MarkGlyphSetsDef, + ) + ) or hasattr(gdef, "VarStore"): + result = newTable("GDEF") + result.table = gdef + return result + else: + return None + + def buildGDEFGlyphClassDef_(self): + if self.glyphClassDefs_: + classes = {g: c for (g, (c, _)) in self.glyphClassDefs_.items()} + else: + classes = {} + for lookup in self.lookups_: + classes.update(lookup.inferGlyphClasses()) + for markClass in self.parseTree.markClasses.values(): + for markClassDef in markClass.definitions: + for glyph in markClassDef.glyphSet(): + classes[glyph] = 3 + if classes: + result = otTables.GlyphClassDef() + result.classDefs = classes + return result + else: + return None + + def buildGDEFMarkAttachClassDef_(self): + classDefs = {g: c for g, (c, _) in self.markAttach_.items()} + if not classDefs: + return None + result = otTables.MarkAttachClassDef() + result.classDefs = classDefs + return result + + def buildGDEFMarkGlyphSetsDef_(self): + sets = [] + for glyphs, id_ in sorted( + self.markFilterSets_.items(), key=lambda item: item[1] + ): + sets.append(glyphs) + return otl.buildMarkGlyphSetsDef(sets, self.glyphMap) + + def buildDebg(self): + if "Debg" not in self.font: + self.font["Debg"] = newTable("Debg") + self.font["Debg"].data = {} + self.font["Debg"].data[LOOKUP_DEBUG_INFO_KEY] = self.lookup_locations + + def buildLookups_(self, tag): + assert tag in ("GPOS", "GSUB"), tag + for lookup in self.lookups_: + lookup.lookup_index = None + lookups = [] + for lookup in self.lookups_: + if lookup.table != tag: + continue + name = self.get_lookup_name_(lookup) + resolved = lookup.promote_lookup_type(is_named_lookup=name is not None) + if resolved is None: + raise FeatureLibError( + "Within a named lookup block, all rules must be of " + "the same lookup type and flag", + lookup.location, + ) + for l in resolved: + lookup.lookup_index = len(lookups) + self.lookup_locations[tag][str(lookup.lookup_index)] = LookupDebugInfo( + location=str(lookup.location), + name=name, + feature=None, + ) + lookups.append(l) + otLookups = [] + for l in lookups: + try: + otLookups.append(l.build()) + except OpenTypeLibError as e: + raise FeatureLibError(str(e), e.location) from e + except Exception as e: + location = self.lookup_locations[tag][str(l.lookup_index)].location + raise FeatureLibError(str(e), location) from e + return otLookups + + def makeTable(self, tag): + table = getattr(otTables, tag, None)() + table.Version = 0x00010000 + table.ScriptList = otTables.ScriptList() + table.ScriptList.ScriptRecord = [] + table.FeatureList = otTables.FeatureList() + table.FeatureList.FeatureRecord = [] + table.LookupList = otTables.LookupList() + table.LookupList.Lookup = self.buildLookups_(tag) + + # Build a table for mapping (tag, lookup_indices) to feature_index. + # For example, ('liga', (2,3,7)) --> 23. + feature_indices = {} + required_feature_indices = {} # ('latn', 'DEU') --> 23 + scripts = {} # 'latn' --> {'DEU': [23, 24]} for feature #23,24 + # Sort the feature table by feature tag: + # https://github.com/fonttools/fonttools/issues/568 + sortFeatureTag = lambda f: (f[0][2], f[0][1], f[0][0], f[1]) + for key, lookups in sorted(self.features_.items(), key=sortFeatureTag): + script, lang, feature_tag = key + # l.lookup_index will be None when a lookup is not needed + # for the table under construction. For example, substitution + # rules will have no lookup_index while building GPOS tables. + # We also deduplicate lookup indices, as they only get applied once + # within a given feature: + # https://github.com/fonttools/fonttools/issues/2946 + lookup_indices = tuple( + dict.fromkeys( + l.lookup_index for l in lookups if l.lookup_index is not None + ) + ) + # order doesn't matter, but lookup_indices preserves it. + # We want to combine identical sets of lookups (order doesn't matter) + # but also respect the order provided by the user (although there's + # a reasonable argument to just sort and dedupe, which fontc does) + lookup_key = frozenset(lookup_indices) + + size_feature = tag == "GPOS" and feature_tag == "size" + force_feature = self.any_feature_variations(feature_tag, tag) + if len(lookup_indices) == 0 and not size_feature and not force_feature: + continue + + for ix in lookup_indices: + try: + self.lookup_locations[tag][str(ix)] = self.lookup_locations[tag][ + str(ix) + ]._replace(feature=key) + except KeyError: + warnings.warn( + "feaLib.Builder subclass needs upgrading to " + "stash debug information. See fonttools#2065." + ) + + feature_key = (feature_tag, lookup_key) + feature_index = feature_indices.get(feature_key) + if feature_index is None: + feature_index = len(table.FeatureList.FeatureRecord) + frec = otTables.FeatureRecord() + frec.FeatureTag = feature_tag + frec.Feature = otTables.Feature() + frec.Feature.FeatureParams = self.buildFeatureParams(feature_tag) + frec.Feature.LookupListIndex = list(lookup_indices) + frec.Feature.LookupCount = len(lookup_indices) + table.FeatureList.FeatureRecord.append(frec) + feature_indices[feature_key] = feature_index + scripts.setdefault(script, {}).setdefault(lang, []).append(feature_index) + if self.required_features_.get((script, lang)) == feature_tag: + required_feature_indices[(script, lang)] = feature_index + + # Build ScriptList. + for script, lang_features in sorted(scripts.items()): + srec = otTables.ScriptRecord() + srec.ScriptTag = script + srec.Script = otTables.Script() + srec.Script.DefaultLangSys = None + srec.Script.LangSysRecord = [] + for lang, feature_indices in sorted(lang_features.items()): + langrec = otTables.LangSysRecord() + langrec.LangSys = otTables.LangSys() + langrec.LangSys.LookupOrder = None + + req_feature_index = required_feature_indices.get((script, lang)) + if req_feature_index is None: + langrec.LangSys.ReqFeatureIndex = 0xFFFF + else: + langrec.LangSys.ReqFeatureIndex = req_feature_index + + langrec.LangSys.FeatureIndex = [ + i for i in feature_indices if i != req_feature_index + ] + langrec.LangSys.FeatureCount = len(langrec.LangSys.FeatureIndex) + + if lang == "dflt": + srec.Script.DefaultLangSys = langrec.LangSys + else: + langrec.LangSysTag = lang + srec.Script.LangSysRecord.append(langrec) + srec.Script.LangSysCount = len(srec.Script.LangSysRecord) + table.ScriptList.ScriptRecord.append(srec) + + table.ScriptList.ScriptCount = len(table.ScriptList.ScriptRecord) + table.FeatureList.FeatureCount = len(table.FeatureList.FeatureRecord) + table.LookupList.LookupCount = len(table.LookupList.Lookup) + return table + + def makeFeatureVariations(self, table, table_tag): + feature_vars = {} + has_any_variations = False + # Sort out which lookups to build, gather their indices + for (_, _, feature_tag), variations in self.feature_variations_.items(): + feature_vars[feature_tag] = [] + for conditionset, builders in variations.items(): + raw_conditionset = self.conditionsets_[conditionset] + indices = [] + for b in builders: + if b.table != table_tag: + continue + assert b.lookup_index is not None + indices.append(b.lookup_index) + has_any_variations = True + feature_vars[feature_tag].append((raw_conditionset, indices)) + + if has_any_variations: + for feature_tag, conditions_and_lookups in feature_vars.items(): + addFeatureVariationsRaw( + self.font, table, conditions_and_lookups, feature_tag + ) + + def any_feature_variations(self, feature_tag, table_tag): + for (_, _, feature), variations in self.feature_variations_.items(): + if feature != feature_tag: + continue + for conditionset, builders in variations.items(): + if any(b.table == table_tag for b in builders): + return True + return False + + def get_lookup_name_(self, lookup): + rev = {v: k for k, v in self.named_lookups_.items()} + if lookup in rev: + return rev[lookup] + return None + + def add_language_system(self, location, script, language): + # OpenType Feature File Specification, section 4.b.i + if script == "DFLT" and language == "dflt" and self.default_language_systems_: + raise FeatureLibError( + 'If "languagesystem DFLT dflt" is present, it must be ' + "the first of the languagesystem statements", + location, + ) + if script == "DFLT": + if self.seen_non_DFLT_script_: + raise FeatureLibError( + 'languagesystems using the "DFLT" script tag must ' + "precede all other languagesystems", + location, + ) + else: + self.seen_non_DFLT_script_ = True + if (script, language) in self.default_language_systems_: + raise FeatureLibError( + '"languagesystem %s %s" has already been specified' + % (script.strip(), language.strip()), + location, + ) + self.default_language_systems_.add((script, language)) + + def get_default_language_systems_(self): + # OpenType Feature File specification, 4.b.i. languagesystem: + # If no "languagesystem" statement is present, then the + # implementation must behave exactly as though the following + # statement were present at the beginning of the feature file: + # languagesystem DFLT dflt; + if self.default_language_systems_: + return frozenset(self.default_language_systems_) + else: + return frozenset({("DFLT", "dflt")}) + + def start_feature(self, location, name, use_extension=False): + if use_extension and name != "aalt": + raise FeatureLibError( + "'useExtension' keyword for feature blocks is allowed only for 'aalt' feature", + location, + ) + self.language_systems = self.get_default_language_systems_() + self.script_ = "DFLT" + self.cur_lookup_ = None + self.cur_feature_name_ = name + self.lookupflag_ = 0 + self.lookupflag_markFilterSet_ = None + self.use_extension_ = use_extension + if name == "aalt": + self.aalt_location_ = location + self.aalt_use_extension_ = use_extension + + def end_feature(self): + assert self.cur_feature_name_ is not None + self.cur_feature_name_ = None + self.language_systems = None + self.cur_lookup_ = None + self.lookupflag_ = 0 + self.lookupflag_markFilterSet_ = None + self.use_extension_ = False + + def start_lookup_block(self, location, name, use_extension=False): + if name in self.named_lookups_: + raise FeatureLibError( + 'Lookup "%s" has already been defined' % name, location + ) + if self.cur_feature_name_ == "aalt": + raise FeatureLibError( + "Lookup blocks cannot be placed inside 'aalt' features; " + "move it out, and then refer to it with a lookup statement", + location, + ) + self.cur_lookup_name_ = name + self.named_lookups_[name] = None + self.cur_lookup_ = None + self.use_extension_ = use_extension + if self.cur_feature_name_ is None: + self.lookupflag_ = 0 + self.lookupflag_markFilterSet_ = None + + def end_lookup_block(self): + assert self.cur_lookup_name_ is not None + self.cur_lookup_name_ = None + self.cur_lookup_ = None + self.use_extension_ = False + if self.cur_feature_name_ is None: + self.lookupflag_ = 0 + self.lookupflag_markFilterSet_ = None + + def add_lookup_call(self, lookup_name): + assert lookup_name in self.named_lookups_, lookup_name + self.cur_lookup_ = None + lookup = self.named_lookups_[lookup_name] + if lookup is not None: # skip empty named lookup + self.add_lookup_to_feature_(lookup, self.cur_feature_name_) + + def set_font_revision(self, location, revision): + self.fontRevision_ = revision + + def set_language(self, location, language, include_default, required): + assert len(language) == 4 + if self.cur_feature_name_ in ("aalt", "size"): + raise FeatureLibError( + "Language statements are not allowed " + 'within "feature %s"' % self.cur_feature_name_, + location, + ) + if self.cur_feature_name_ is None: + raise FeatureLibError( + "Language statements are not allowed " + "within standalone lookup blocks", + location, + ) + self.cur_lookup_ = None + + key = (self.script_, language, self.cur_feature_name_) + lookups = self.features_.get((key[0], "dflt", key[2])) + if (language == "dflt" or include_default) and lookups: + self.features_[key] = lookups[:] + else: + # if we aren't including default we need to manually remove the + # default lookups, which were added to all declared langsystems + # as they were encountered (we don't remove all lookups because + # we want to allow duplicate script/lang statements; + # see https://github.com/fonttools/fonttools/issues/3748 + cur_lookups = self.features_.get(key, []) + self.features_[key] = [x for x in cur_lookups if x not in lookups] + self.language_systems = frozenset([(self.script_, language)]) + + if required: + key = (self.script_, language) + if key in self.required_features_: + raise FeatureLibError( + "Language %s (script %s) has already " + "specified feature %s as its required feature" + % ( + language.strip(), + self.script_.strip(), + self.required_features_[key].strip(), + ), + location, + ) + self.required_features_[key] = self.cur_feature_name_ + + def getMarkAttachClass_(self, location, glyphs): + glyphs = frozenset(glyphs) + id_ = self.markAttachClassID_.get(glyphs) + if id_ is not None: + return id_ + id_ = len(self.markAttachClassID_) + 1 + self.markAttachClassID_[glyphs] = id_ + for glyph in glyphs: + if glyph in self.markAttach_: + _, loc = self.markAttach_[glyph] + raise FeatureLibError( + "Glyph %s already has been assigned " + "a MarkAttachmentType at %s" % (glyph, loc), + location, + ) + self.markAttach_[glyph] = (id_, location) + return id_ + + def getMarkFilterSet_(self, location, glyphs): + glyphs = frozenset(glyphs) + id_ = self.markFilterSets_.get(glyphs) + if id_ is not None: + return id_ + id_ = len(self.markFilterSets_) + self.markFilterSets_[glyphs] = id_ + return id_ + + def set_lookup_flag(self, location, value, markAttach, markFilter): + value = value & 0xFF + if markAttach is not None: + markAttachClass = self.getMarkAttachClass_(location, markAttach) + value = value | (markAttachClass << 8) + if markFilter is not None: + markFilterSet = self.getMarkFilterSet_(location, markFilter) + value = value | 0x10 + self.lookupflag_markFilterSet_ = markFilterSet + else: + self.lookupflag_markFilterSet_ = None + self.lookupflag_ = value + + def set_script(self, location, script): + if self.cur_feature_name_ in ("aalt", "size"): + raise FeatureLibError( + "Script statements are not allowed " + 'within "feature %s"' % self.cur_feature_name_, + location, + ) + if self.cur_feature_name_ is None: + raise FeatureLibError( + "Script statements are not allowed " "within standalone lookup blocks", + location, + ) + if self.language_systems == {(script, "dflt")}: + # Nothing to do. + return + self.cur_lookup_ = None + self.script_ = script + self.lookupflag_ = 0 + self.lookupflag_markFilterSet_ = None + self.set_language(location, "dflt", include_default=True, required=False) + + def find_lookup_builders_(self, lookups): + """Helper for building chain contextual substitutions + + Given a list of lookup names, finds the LookupBuilder for each name. + If an input name is None, it gets mapped to a None LookupBuilder. + """ + lookup_builders = [] + for lookuplist in lookups: + if lookuplist is not None: + lookup_builders.append( + [self.named_lookups_.get(l.name) for l in lookuplist] + ) + else: + lookup_builders.append(None) + return lookup_builders + + def add_attach_points(self, location, glyphs, contourPoints): + for glyph in glyphs: + self.attachPoints_.setdefault(glyph, set()).update(contourPoints) + + def add_feature_reference(self, location, featureName): + if self.cur_feature_name_ != "aalt": + raise FeatureLibError( + 'Feature references are only allowed inside "feature aalt"', location + ) + self.aalt_features_.append((location, featureName)) + + def add_featureName(self, tag): + self.featureNames_.add(tag) + + def add_cv_parameter(self, tag): + self.cv_parameters_.add(tag) + + def add_to_cv_num_named_params(self, tag): + """Adds new items to ``self.cv_num_named_params_`` + or increments the count of existing items.""" + if tag in self.cv_num_named_params_: + self.cv_num_named_params_[tag] += 1 + else: + self.cv_num_named_params_[tag] = 1 + + def add_cv_character(self, character, tag): + self.cv_characters_[tag].append(character) + + def set_base_axis(self, bases, scripts, vertical, minmax=[]): + if vertical: + self.base_vert_axis_ = (bases, scripts, minmax) + else: + self.base_horiz_axis_ = (bases, scripts, minmax) + + def set_size_parameters( + self, location, DesignSize, SubfamilyID, RangeStart, RangeEnd + ): + if self.cur_feature_name_ != "size": + raise FeatureLibError( + "Parameters statements are not allowed " + 'within "feature %s"' % self.cur_feature_name_, + location, + ) + self.size_parameters_ = [DesignSize, SubfamilyID, RangeStart, RangeEnd] + for script, lang in self.language_systems: + key = (script, lang, self.cur_feature_name_) + self.features_.setdefault(key, []) + + # GSUB rules + + def add_any_subst_(self, location, mapping): + lookup = self.get_lookup_(location, AnySubstBuilder, mapping=mapping) + for key, value in mapping.items(): + if key in lookup.mapping: + if value == lookup.mapping[key]: + log.info( + 'Removing duplicate substitution from "%s" to "%s" at %s', + ", ".join(key), + ", ".join(value), + location, + ) + else: + raise FeatureLibError( + 'Already defined substitution for "%s"' % ", ".join(key), + location, + ) + lookup.mapping[key] = value + + # GSUB 1 + def add_single_subst(self, location, prefix, suffix, mapping, forceChain): + if self.cur_feature_name_ == "aalt": + for from_glyph, to_glyph in mapping.items(): + alts = self.aalt_alternates_.setdefault(from_glyph, []) + if to_glyph not in alts: + alts.append(to_glyph) + return + if prefix or suffix or forceChain: + self.add_single_subst_chained_(location, prefix, suffix, mapping) + return + + self.add_any_subst_( + location, + {(key,): (value,) for key, value in mapping.items()}, + ) + + # GSUB 2 + def add_multiple_subst( + self, location, prefix, glyph, suffix, replacements, forceChain=False + ): + if prefix or suffix or forceChain: + self.add_multi_subst_chained_(location, prefix, glyph, suffix, replacements) + return + self.add_any_subst_( + location, + {(glyph,): tuple(replacements)}, + ) + + # GSUB 3 + def add_alternate_subst(self, location, prefix, glyph, suffix, replacement): + if self.cur_feature_name_ == "aalt": + alts = self.aalt_alternates_.setdefault(glyph, []) + alts.extend(g for g in replacement if g not in alts) + return + if prefix or suffix: + chain = self.get_lookup_(location, ChainContextSubstBuilder) + lookup = self.get_chained_lookup_(location, AlternateSubstBuilder) + chain.rules.append(ChainContextualRule(prefix, [{glyph}], suffix, [lookup])) + else: + lookup = self.get_lookup_(location, AlternateSubstBuilder) + if glyph in lookup.alternates: + raise FeatureLibError( + 'Already defined alternates for glyph "%s"' % glyph, location + ) + # We allow empty replacement glyphs here. + lookup.alternates[glyph] = replacement + + # GSUB 4 + def add_ligature_subst( + self, location, prefix, glyphs, suffix, replacement, forceChain + ): + if prefix or suffix or forceChain: + self.add_ligature_subst_chained_( + location, prefix, glyphs, suffix, replacement + ) + return + if not all(glyphs): + raise FeatureLibError("Empty glyph class in substitution", location) + + # OpenType feature file syntax, section 5.d, "Ligature substitution": + # "Since the OpenType specification does not allow ligature + # substitutions to be specified on target sequences that contain + # glyph classes, the implementation software will enumerate + # all specific glyph sequences if glyph classes are detected" + self.add_any_subst_( + location, + {g: (replacement,) for g in itertools.product(*glyphs)}, + ) + + # GSUB 5/6 + def add_chain_context_subst(self, location, prefix, glyphs, suffix, lookups): + if not all(glyphs) or not all(prefix) or not all(suffix): + raise FeatureLibError( + "Empty glyph class in contextual substitution", location + ) + lookup = self.get_lookup_(location, ChainContextSubstBuilder) + lookup.rules.append( + ChainContextualRule( + prefix, glyphs, suffix, self.find_lookup_builders_(lookups) + ) + ) + + def add_single_subst_chained_(self, location, prefix, suffix, mapping): + if not mapping or not all(prefix) or not all(suffix): + raise FeatureLibError( + "Empty glyph class in contextual substitution", location + ) + # https://github.com/fonttools/fonttools/issues/512 + # https://github.com/fonttools/fonttools/issues/2150 + chain = self.get_lookup_(location, ChainContextSubstBuilder) + sub = chain.find_chainable_subst(mapping, SingleSubstBuilder) + if sub is None: + sub = self.get_chained_lookup_(location, SingleSubstBuilder) + sub.mapping.update(mapping) + chain.rules.append( + ChainContextualRule(prefix, [list(mapping.keys())], suffix, [sub]) + ) + + def add_multi_subst_chained_(self, location, prefix, glyph, suffix, replacements): + if not all(prefix) or not all(suffix): + raise FeatureLibError( + "Empty glyph class in contextual substitution", location + ) + # https://github.com/fonttools/fonttools/issues/3551 + chain = self.get_lookup_(location, ChainContextSubstBuilder) + sub = chain.find_chainable_subst({glyph: replacements}, MultipleSubstBuilder) + if sub is None: + sub = self.get_chained_lookup_(location, MultipleSubstBuilder) + sub.mapping[glyph] = replacements + chain.rules.append(ChainContextualRule(prefix, [{glyph}], suffix, [sub])) + + def add_ligature_subst_chained_( + self, location, prefix, glyphs, suffix, replacement + ): + # https://github.com/fonttools/fonttools/issues/3701 + if not all(prefix) or not all(suffix): + raise FeatureLibError( + "Empty glyph class in contextual substitution", location + ) + chain = self.get_lookup_(location, ChainContextSubstBuilder) + sub = chain.find_chainable_ligature_subst(glyphs, replacement) + if sub is None: + sub = self.get_chained_lookup_(location, LigatureSubstBuilder) + + for g in itertools.product(*glyphs): + existing = sub.ligatures.get(g, replacement) + if existing != replacement: + raise FeatureLibError( + f"Conflicting ligature sub rules: '{g}' maps to '{existing}' and '{replacement}'", + location, + ) + + sub.ligatures[g] = replacement + + chain.rules.append(ChainContextualRule(prefix, glyphs, suffix, [sub])) + + # GSUB 8 + def add_reverse_chain_single_subst(self, location, old_prefix, old_suffix, mapping): + if not mapping: + raise FeatureLibError("Empty glyph class in substitution", location) + lookup = self.get_lookup_(location, ReverseChainSingleSubstBuilder) + lookup.rules.append((old_prefix, old_suffix, mapping)) + + # GPOS rules + + # GPOS 1 + def add_single_pos(self, location, prefix, suffix, pos, forceChain): + if prefix or suffix or forceChain: + self.add_single_pos_chained_(location, prefix, suffix, pos) + else: + lookup = self.get_lookup_(location, SinglePosBuilder) + for glyphs, value in pos: + if not glyphs: + raise FeatureLibError( + "Empty glyph class in positioning rule", location + ) + otValueRecord = self.makeOpenTypeValueRecord( + location, value, pairPosContext=False + ) + for glyph in glyphs: + try: + lookup.add_pos(location, glyph, otValueRecord) + except OpenTypeLibError as e: + raise FeatureLibError(str(e), e.location) from e + + # GPOS 2 + def add_class_pair_pos(self, location, glyphclass1, value1, glyphclass2, value2): + if not glyphclass1 or not glyphclass2: + raise FeatureLibError("Empty glyph class in positioning rule", location) + lookup = self.get_lookup_(location, PairPosBuilder) + v1 = self.makeOpenTypeValueRecord(location, value1, pairPosContext=True) + v2 = self.makeOpenTypeValueRecord(location, value2, pairPosContext=True) + cls1 = tuple(sorted(set(glyphclass1))) + cls2 = tuple(sorted(set(glyphclass2))) + lookup.addClassPair(location, cls1, v1, cls2, v2) + + def add_specific_pair_pos(self, location, glyph1, value1, glyph2, value2): + if not glyph1 or not glyph2: + raise FeatureLibError("Empty glyph class in positioning rule", location) + lookup = self.get_lookup_(location, PairPosBuilder) + v1 = self.makeOpenTypeValueRecord(location, value1, pairPosContext=True) + v2 = self.makeOpenTypeValueRecord(location, value2, pairPosContext=True) + lookup.addGlyphPair(location, glyph1, v1, glyph2, v2) + + # GPOS 3 + def add_cursive_pos(self, location, glyphclass, entryAnchor, exitAnchor): + if not glyphclass: + raise FeatureLibError("Empty glyph class in positioning rule", location) + lookup = self.get_lookup_(location, CursivePosBuilder) + lookup.add_attachment( + location, + glyphclass, + self.makeOpenTypeAnchor(location, entryAnchor), + self.makeOpenTypeAnchor(location, exitAnchor), + ) + + # GPOS 4 + def add_mark_base_pos(self, location, bases, marks): + builder = self.get_lookup_(location, MarkBasePosBuilder) + self.add_marks_(location, builder, marks) + if not bases: + raise FeatureLibError("Empty glyph class in positioning rule", location) + for baseAnchor, markClass in marks: + otBaseAnchor = self.makeOpenTypeAnchor(location, baseAnchor) + for base in bases: + builder.bases.setdefault(base, {})[markClass.name] = otBaseAnchor + + # GPOS 5 + def add_mark_lig_pos(self, location, ligatures, components): + builder = self.get_lookup_(location, MarkLigPosBuilder) + componentAnchors = [] + if not ligatures: + raise FeatureLibError("Empty glyph class in positioning rule", location) + for marks in components: + anchors = {} + self.add_marks_(location, builder, marks) + for ligAnchor, markClass in marks: + anchors[markClass.name] = self.makeOpenTypeAnchor(location, ligAnchor) + componentAnchors.append(anchors) + for glyph in ligatures: + builder.ligatures[glyph] = componentAnchors + + # GPOS 6 + def add_mark_mark_pos(self, location, baseMarks, marks): + builder = self.get_lookup_(location, MarkMarkPosBuilder) + self.add_marks_(location, builder, marks) + if not baseMarks: + raise FeatureLibError("Empty glyph class in positioning rule", location) + for baseAnchor, markClass in marks: + otBaseAnchor = self.makeOpenTypeAnchor(location, baseAnchor) + for baseMark in baseMarks: + builder.baseMarks.setdefault(baseMark, {})[ + markClass.name + ] = otBaseAnchor + + # GPOS 7/8 + def add_chain_context_pos(self, location, prefix, glyphs, suffix, lookups): + if not all(glyphs) or not all(prefix) or not all(suffix): + raise FeatureLibError( + "Empty glyph class in contextual positioning rule", location + ) + lookup = self.get_lookup_(location, ChainContextPosBuilder) + lookup.rules.append( + ChainContextualRule( + prefix, glyphs, suffix, self.find_lookup_builders_(lookups) + ) + ) + + def add_single_pos_chained_(self, location, prefix, suffix, pos): + if not pos or not all(prefix) or not all(suffix): + raise FeatureLibError( + "Empty glyph class in contextual positioning rule", location + ) + # https://github.com/fonttools/fonttools/issues/514 + chain = self.get_lookup_(location, ChainContextPosBuilder) + targets = [] + for _, _, _, lookups in chain.rules: + targets.extend(lookups) + subs = [] + for glyphs, value in pos: + if value is None: + subs.append(None) + continue + otValue = self.makeOpenTypeValueRecord( + location, value, pairPosContext=False + ) + sub = chain.find_chainable_single_pos(targets, glyphs, otValue) + if sub is None: + sub = self.get_chained_lookup_(location, SinglePosBuilder) + targets.append(sub) + for glyph in glyphs: + sub.add_pos(location, glyph, otValue) + subs.append(sub) + assert len(pos) == len(subs), (pos, subs) + chain.rules.append( + ChainContextualRule(prefix, [g for g, v in pos], suffix, subs) + ) + + def add_marks_(self, location, lookupBuilder, marks): + """Helper for add_mark_{base,liga,mark}_pos.""" + for _, markClass in marks: + for markClassDef in markClass.definitions: + for mark in markClassDef.glyphs.glyphSet(): + if mark not in lookupBuilder.marks: + otMarkAnchor = self.makeOpenTypeAnchor( + location, copy.deepcopy(markClassDef.anchor) + ) + lookupBuilder.marks[mark] = (markClass.name, otMarkAnchor) + else: + existingMarkClass = lookupBuilder.marks[mark][0] + if markClass.name != existingMarkClass: + raise FeatureLibError( + "Glyph %s cannot be in both @%s and @%s" + % (mark, existingMarkClass, markClass.name), + location, + ) + + def add_subtable_break(self, location): + self.cur_lookup_.add_subtable_break(location) + + def setGlyphClass_(self, location, glyph, glyphClass): + oldClass, oldLocation = self.glyphClassDefs_.get(glyph, (None, None)) + if oldClass and oldClass != glyphClass: + raise FeatureLibError( + "Glyph %s was assigned to a different class at %s" + % (glyph, oldLocation), + location, + ) + self.glyphClassDefs_[glyph] = (glyphClass, location) + + def add_glyphClassDef( + self, location, baseGlyphs, ligatureGlyphs, markGlyphs, componentGlyphs + ): + for glyph in baseGlyphs: + self.setGlyphClass_(location, glyph, 1) + for glyph in ligatureGlyphs: + self.setGlyphClass_(location, glyph, 2) + for glyph in markGlyphs: + self.setGlyphClass_(location, glyph, 3) + for glyph in componentGlyphs: + self.setGlyphClass_(location, glyph, 4) + + def add_ligatureCaretByIndex_(self, location, glyphs, carets): + for glyph in glyphs: + if glyph not in self.ligCaretPoints_: + self.ligCaretPoints_[glyph] = carets + + def makeLigCaret(self, location, caret): + if not isinstance(caret, VariableScalar): + return caret + default, device = self.makeVariablePos(location, caret) + if device is not None: + return (default, device) + return default + + def add_ligatureCaretByPos_(self, location, glyphs, carets): + carets = [self.makeLigCaret(location, caret) for caret in carets] + for glyph in glyphs: + if glyph not in self.ligCaretCoords_: + self.ligCaretCoords_[glyph] = carets + + def add_name_record(self, location, nameID, platformID, platEncID, langID, string): + self.names_.append([nameID, platformID, platEncID, langID, string]) + + def add_os2_field(self, key, value): + self.os2_[key] = value + + def add_hhea_field(self, key, value): + self.hhea_[key] = value + + def add_vhea_field(self, key, value): + self.vhea_[key] = value + + def add_conditionset(self, location, key, value): + if "fvar" not in self.font: + raise FeatureLibError( + "Cannot add feature variations to a font without an 'fvar' table", + location, + ) + + if key in self.conditionsets_: + raise FeatureLibError( + f"Condition set '{key}' has the same name as a previous condition set", + location, + ) + + # Normalize + axisMap = { + axis.axisTag: (axis.minValue, axis.defaultValue, axis.maxValue) + for axis in self.axes + } + + value = { + tag: ( + normalizeValue(bottom, axisMap[tag]), + normalizeValue(top, axisMap[tag]), + ) + for tag, (bottom, top) in value.items() + } + + # NOTE: This might result in rounding errors (off-by-ones) compared to + # rules in Designspace files, since we're working with what's in the + # `avar` table rather than the original values. + if "avar" in self.font: + mapping = self.font["avar"].segments + value = { + axis: tuple( + piecewiseLinearMap(v, mapping[axis]) if axis in mapping else v + for v in condition_range + ) + for axis, condition_range in value.items() + } + + self.conditionsets_[key] = value + + def makeVariablePos(self, location, varscalar): + if not self.varstorebuilder: + raise FeatureLibError( + "Can't define a variable scalar in a non-variable font", location + ) + + varscalar.axes = self.axes + if not varscalar.does_vary: + return varscalar.default, None + + try: + default, index = varscalar.add_to_variation_store( + self.varstorebuilder, self.model_cache, self.font.get("avar") + ) + except VarLibError as e: + raise FeatureLibError( + "Failed to compute deltas for variable scalar", location + ) from e + + device = None + if index is not None and index != 0xFFFFFFFF: + device = buildVarDevTable(index) + + return default, device + + def makeAnchorPos(self, varscalar, deviceTable, location): + device = None + if not isinstance(varscalar, VariableScalar): + if deviceTable is not None: + device = otl.buildDevice(dict(deviceTable)) + return varscalar, device + default, device = self.makeVariablePos(location, varscalar) + if device is not None and deviceTable is not None: + raise FeatureLibError( + "Can't define a device coordinate and variable scalar", location + ) + return default, device + + def makeOpenTypeAnchor(self, location, anchor): + """ast.Anchor --> otTables.Anchor""" + if anchor is None: + return None + deviceX, deviceY = None, None + if anchor.xDeviceTable is not None: + deviceX = otl.buildDevice(dict(anchor.xDeviceTable)) + if anchor.yDeviceTable is not None: + deviceY = otl.buildDevice(dict(anchor.yDeviceTable)) + x, deviceX = self.makeAnchorPos(anchor.x, anchor.xDeviceTable, location) + y, deviceY = self.makeAnchorPos(anchor.y, anchor.yDeviceTable, location) + otlanchor = otl.buildAnchor(x, y, anchor.contourpoint, deviceX, deviceY) + return otlanchor + + _VALUEREC_ATTRS = { + name[0].lower() + name[1:]: (name, isDevice) + for _, name, isDevice, _ in otBase.valueRecordFormat + if not name.startswith("Reserved") + } + + def makeOpenTypeValueRecord(self, location, v, pairPosContext): + """ast.ValueRecord --> otBase.ValueRecord""" + if not v: + return None + + vr = {} + for astName, (otName, isDevice) in self._VALUEREC_ATTRS.items(): + val = getattr(v, astName, None) + if not val: + continue + if isDevice: + vr[otName] = otl.buildDevice(dict(val)) + elif isinstance(val, VariableScalar): + otDeviceName = otName[0:4] + "Device" + feaDeviceName = otDeviceName[0].lower() + otDeviceName[1:] + if getattr(v, feaDeviceName): + raise FeatureLibError( + "Can't define a device coordinate and variable scalar", location + ) + vr[otName], device = self.makeVariablePos(location, val) + if device is not None: + vr[otDeviceName] = device + else: + vr[otName] = val + + if pairPosContext and not vr: + vr = {"YAdvance": 0} if v.vertical else {"XAdvance": 0} + valRec = otl.buildValue(vr) + return valRec diff --git a/.venv/lib/python3.13/site-packages/fontTools/feaLib/error.py b/.venv/lib/python3.13/site-packages/fontTools/feaLib/error.py new file mode 100644 index 0000000000000000000000000000000000000000..c5fed4934835300c2e3a2ebac5ac4a73732e52af --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/feaLib/error.py @@ -0,0 +1,22 @@ +class FeatureLibError(Exception): + def __init__(self, message, location=None): + Exception.__init__(self, message) + self.location = location + + def __str__(self): + message = Exception.__str__(self) + if self.location: + return f"{self.location}: {message}" + else: + return message + + +class IncludedFeaNotFound(FeatureLibError): + def __str__(self): + assert self.location is not None + + message = ( + "The following feature file should be included but cannot be found: " + f"{Exception.__str__(self)}" + ) + return f"{self.location}: {message}" diff --git a/.venv/lib/python3.13/site-packages/fontTools/feaLib/lexer.c b/.venv/lib/python3.13/site-packages/fontTools/feaLib/lexer.c new file mode 100644 index 0000000000000000000000000000000000000000..5f00bfdd681becde947f8309f4eb566491c3dc8c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/feaLib/lexer.c @@ -0,0 +1,17029 @@ +/* Generated by Cython 3.2.2 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "name": "fontTools.feaLib.lexer", + "sources": [ + "Lib/fontTools/feaLib/lexer.py" + ] + }, + "module_name": "fontTools.feaLib.lexer" +} +END: Cython Metadata */ + +#ifndef PY_SSIZE_T_CLEAN +#define PY_SSIZE_T_CLEAN +#endif /* PY_SSIZE_T_CLEAN */ +/* InitLimitedAPI */ +#if defined(Py_LIMITED_API) + #if !defined(CYTHON_LIMITED_API) + #define CYTHON_LIMITED_API 1 + #endif +#elif defined(CYTHON_LIMITED_API) + #ifdef _MSC_VER + #pragma message ("Limited API usage is enabled with 'CYTHON_LIMITED_API' but 'Py_LIMITED_API' does not define a Python target version. Consider setting 'Py_LIMITED_API' instead.") + #else + #warning Limited API usage is enabled with 'CYTHON_LIMITED_API' but 'Py_LIMITED_API' does not define a Python target version. Consider setting 'Py_LIMITED_API' instead. + #endif +#endif + +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x03080000 + #error Cython requires Python 3.8+. +#else +#define __PYX_ABI_VERSION "3_2_2" +#define CYTHON_HEX_VERSION 0x030202F0 +#define CYTHON_FUTURE_DIVISION 1 +/* CModulePreamble */ +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(_WIN32) && !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#define __PYX_LIMITED_VERSION_HEX PY_VERSION_HEX +#if defined(GRAALVM_PYTHON) + /* For very preliminary testing purposes. Most variables are set the same as PyPy. + The existence of this section does not imply that anything works or is even tested */ + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 1 + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 0 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 1 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif + #undef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 +#elif defined(PYPY_VERSION) + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #ifndef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 1 + #endif + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #if PY_VERSION_HEX < 0x03090000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING 0 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PYPY_VERSION_NUM >= 0x07030C00) + #endif + #undef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC (PYPY_VERSION_NUM >= 0x07031100) + #endif + #undef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 +#elif defined(CYTHON_LIMITED_API) + #ifdef Py_LIMITED_API + #undef __PYX_LIMITED_VERSION_HEX + #define __PYX_LIMITED_VERSION_HEX Py_LIMITED_API + #endif + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 1 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 1 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #endif + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 0 + #endif + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL (__PYX_LIMITED_VERSION_HEX >= 0x030C0000) + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #undef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING 0 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #endif + #ifndef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND (__PYX_LIMITED_VERSION_HEX >= 0x030A0000) + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif + #ifndef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 1 + #endif + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #ifdef Py_GIL_DISABLED + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 1 + #else + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #endif + #if PY_VERSION_HEX < 0x030A0000 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #elif !defined(CYTHON_USE_TYPE_SLOTS) + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #ifndef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #ifndef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #elif !defined(CYTHON_USE_PYLIST_INTERNALS) + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING || PY_VERSION_HEX >= 0x030B00A2 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 1 + #elif !defined(CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS) + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #elif !defined(CYTHON_FAST_GIL) + #define CYTHON_FAST_GIL (PY_VERSION_HEX < 0x030C00A6) + #endif + #ifndef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 1 + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #ifndef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING (PY_VERSION_HEX >= 0x030d00B1) + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #ifndef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #elif !defined(CYTHON_USE_DICT_VERSIONS) + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX < 0x030C00A5 && !CYTHON_USE_MODULE_STATE) + #endif + #ifndef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 1 + #endif + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 + #endif + #ifndef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS (!CYTHON_COMPILING_IN_CPYTHON_FREETHREADING) + #endif + #if defined(CYTHON_IMMORTAL_CONSTANTS) && PY_VERSION_HEX < 0x030C0000 + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 // definitely won't work + #elif !defined(CYTHON_IMMORTAL_CONSTANTS) + #define CYTHON_IMMORTAL_CONSTANTS (PY_VERSION_HEX >= 0x030C0000 && !CYTHON_USE_MODULE_STATE && CYTHON_COMPILING_IN_CPYTHON_FREETHREADING) + #endif +#endif +#ifndef CYTHON_COMPRESS_STRINGS + #define CYTHON_COMPRESS_STRINGS 1 +#endif +#ifndef CYTHON_FAST_PYCCALL +#define CYTHON_FAST_PYCCALL CYTHON_FAST_PYCALL +#endif +#ifndef CYTHON_VECTORCALL +#if CYTHON_COMPILING_IN_LIMITED_API +#define CYTHON_VECTORCALL (__PYX_LIMITED_VERSION_HEX >= 0x030C0000) +#else +#define CYTHON_VECTORCALL (CYTHON_FAST_PYCCALL) +#endif +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(maybe_unused) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(maybe_unused) + #define CYTHON_UNUSED [[maybe_unused]] + #endif + #endif + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR + #define CYTHON_MAYBE_UNUSED_VAR(x) CYTHON_UNUSED_VAR(x) +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON && !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_USE_CPP_STD_MOVE + #if defined(__cplusplus) && (\ + __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)) + #define CYTHON_USE_CPP_STD_MOVE 1 + #else + #define CYTHON_USE_CPP_STD_MOVE 0 + #endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#include +typedef uintptr_t __pyx_uintptr_t; +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(fallthrough) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif +#ifndef Py_UNREACHABLE + #define Py_UNREACHABLE() assert(0); abort() +#endif +#ifdef __cplusplus + template + struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);}; + #define __PYX_IS_UNSIGNED(type) (__PYX_IS_UNSIGNED_IMPL::value) +#else + #define __PYX_IS_UNSIGNED(type) (((type)-1) > 0) +#endif +#if CYTHON_COMPILING_IN_PYPY == 1 + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX < 0x030A0000) +#else + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX < 0x03090000) +#endif +#define __PYX_REINTERPRET_FUNCION(func_pointer, other_pointer) ((func_pointer)(void(*)(void))(other_pointer)) + +/* CInitCode */ +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +/* PythonCompatibility */ +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#define __Pyx_BUILTIN_MODULE_NAME "builtins" +#define __Pyx_DefaultClassType PyType_Type +#if CYTHON_COMPILING_IN_LIMITED_API + #ifndef CO_OPTIMIZED + static int CO_OPTIMIZED; + #endif + #ifndef CO_NEWLOCALS + static int CO_NEWLOCALS; + #endif + #ifndef CO_VARARGS + static int CO_VARARGS; + #endif + #ifndef CO_VARKEYWORDS + static int CO_VARKEYWORDS; + #endif + #ifndef CO_ASYNC_GENERATOR + static int CO_ASYNC_GENERATOR; + #endif + #ifndef CO_GENERATOR + static int CO_GENERATOR; + #endif + #ifndef CO_COROUTINE + static int CO_COROUTINE; + #endif +#else + #ifndef CO_COROUTINE + #define CO_COROUTINE 0x80 + #endif + #ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x200 + #endif +#endif +static int __Pyx_init_co_variables(void); +#if PY_VERSION_HEX >= 0x030900A4 || defined(Py_IS_TYPE) + #define __Pyx_IS_TYPE(ob, type) Py_IS_TYPE(ob, type) +#else + #define __Pyx_IS_TYPE(ob, type) (((const PyObject*)ob)->ob_type == (type)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_Is) + #define __Pyx_Py_Is(x, y) Py_Is(x, y) +#else + #define __Pyx_Py_Is(x, y) ((x) == (y)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsNone) + #define __Pyx_Py_IsNone(ob) Py_IsNone(ob) +#else + #define __Pyx_Py_IsNone(ob) __Pyx_Py_Is((ob), Py_None) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsTrue) + #define __Pyx_Py_IsTrue(ob) Py_IsTrue(ob) +#else + #define __Pyx_Py_IsTrue(ob) __Pyx_Py_Is((ob), Py_True) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsFalse) + #define __Pyx_Py_IsFalse(ob) Py_IsFalse(ob) +#else + #define __Pyx_Py_IsFalse(ob) __Pyx_Py_Is((ob), Py_False) +#endif +#define __Pyx_NoneAsNull(obj) (__Pyx_Py_IsNone(obj) ? NULL : (obj)) +#if PY_VERSION_HEX >= 0x030900F0 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyObject_GC_IsFinalized(o) PyObject_GC_IsFinalized(o) +#else + #define __Pyx_PyObject_GC_IsFinalized(o) _PyGC_FINALIZED(o) +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef Py_TPFLAGS_SEQUENCE + #define Py_TPFLAGS_SEQUENCE 0 +#endif +#ifndef Py_TPFLAGS_MAPPING + #define Py_TPFLAGS_MAPPING 0 +#endif +#ifndef Py_TPFLAGS_IMMUTABLETYPE + #define Py_TPFLAGS_IMMUTABLETYPE (1UL << 8) +#endif +#ifndef Py_TPFLAGS_DISALLOW_INSTANTIATION + #define Py_TPFLAGS_DISALLOW_INSTANTIATION (1UL << 7) +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#ifndef METH_FASTCALL + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #if PY_VERSION_HEX >= 0x030d00A4 + # define __Pyx_PyCFunctionFast PyCFunctionFast + # define __Pyx_PyCFunctionFastWithKeywords PyCFunctionFastWithKeywords + #else + # define __Pyx_PyCFunctionFast _PyCFunctionFast + # define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords + #endif +#endif +#if CYTHON_METH_FASTCALL + #define __Pyx_METH_FASTCALL METH_FASTCALL + #define __Pyx_PyCFunction_FastCall __Pyx_PyCFunctionFast + #define __Pyx_PyCFunction_FastCallWithKeywords __Pyx_PyCFunctionFastWithKeywords +#else + #define __Pyx_METH_FASTCALL METH_VARARGS + #define __Pyx_PyCFunction_FastCall PyCFunction + #define __Pyx_PyCFunction_FastCallWithKeywords PyCFunctionWithKeywords +#endif +#if CYTHON_VECTORCALL + #define __pyx_vectorcallfunc vectorcallfunc + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET PY_VECTORCALL_ARGUMENTS_OFFSET + #define __Pyx_PyVectorcall_NARGS(n) PyVectorcall_NARGS((size_t)(n)) +#else + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET 0 + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(n)) +#endif +#if PY_VERSION_HEX >= 0x030900B1 +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_CheckExact(func) +#else +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_Check(func) +#endif +#define __Pyx_CyOrPyCFunction_Check(func) PyCFunction_Check(func) +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) (((PyCFunctionObject*)(func))->m_ml->ml_meth) +#elif !CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(func) +#endif +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FLAGS(func) (((PyCFunctionObject*)(func))->m_ml->ml_flags) +static CYTHON_INLINE PyObject* __Pyx_CyOrPyCFunction_GET_SELF(PyObject *func) { + return (__Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_STATIC) ? NULL : ((PyCFunctionObject*)func)->m_self; +} +#endif +static CYTHON_INLINE int __Pyx__IsSameCFunction(PyObject *func, void (*cfunc)(void)) { +#if CYTHON_COMPILING_IN_LIMITED_API + return PyCFunction_Check(func) && PyCFunction_GetFunction(func) == (PyCFunction) cfunc; +#else + return PyCFunction_Check(func) && PyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +#endif +} +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCFunction(func, cfunc) +#if PY_VERSION_HEX < 0x03090000 || (CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000) + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) ((void)m, PyType_FromSpecWithBases(s, b)) + typedef PyObject *(*__Pyx_PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *); +#else + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) PyType_FromModuleAndSpec(m, s, b) + #define __Pyx_PyCMethod PyCMethod +#endif +#ifndef METH_METHOD + #define METH_METHOD 0x200 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) +#elif CYTHON_COMPILING_IN_GRAAL && defined(GRAALPY_VERSION_NUM) && GRAALPY_VERSION_NUM > 0x19000000 + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) GraalPyFrame_SetLineNumber((frame), (lineno)) +#elif CYTHON_COMPILING_IN_GRAAL + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) _PyFrame_SetLineNumber((frame), (lineno)) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyThreadState_Current PyThreadState_Get() +#elif !CYTHON_FAST_THREAD_STATE + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyThreadState_Current PyThreadState_GetUnchecked() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#endif +#if CYTHON_USE_MODULE_STATE +static CYTHON_INLINE void *__Pyx__PyModule_GetState(PyObject *op) +{ + void *result; + result = PyModule_GetState(op); + if (!result) + Py_FatalError("Couldn't find the module state"); + return result; +} +#define __Pyx_PyModule_GetState(o) (__pyx_mstatetype *)__Pyx__PyModule_GetState(o) +#else +#define __Pyx_PyModule_GetState(op) ((void)op,__pyx_mstate_global) +#endif +#define __Pyx_PyObject_GetSlot(obj, name, func_ctype) __Pyx_PyType_GetSlot(Py_TYPE((PyObject *) obj), name, func_ctype) +#define __Pyx_PyObject_TryGetSlot(obj, name, func_ctype) __Pyx_PyType_TryGetSlot(Py_TYPE(obj), name, func_ctype) +#define __Pyx_PyObject_GetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_GetSubSlot(Py_TYPE(obj), sub, name, func_ctype) +#define __Pyx_PyObject_TryGetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_TryGetSubSlot(Py_TYPE(obj), sub, name, func_ctype) +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((type)->name) + #define __Pyx_PyType_TryGetSlot(type, name, func_ctype) __Pyx_PyType_GetSlot(type, name, func_ctype) + #define __Pyx_PyType_GetSubSlot(type, sub, name, func_ctype) (((type)->sub) ? ((type)->sub->name) : NULL) + #define __Pyx_PyType_TryGetSubSlot(type, sub, name, func_ctype) __Pyx_PyType_GetSubSlot(type, sub, name, func_ctype) +#else + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((func_ctype) PyType_GetSlot((type), Py_##name)) + #define __Pyx_PyType_TryGetSlot(type, name, func_ctype)\ + ((__PYX_LIMITED_VERSION_HEX >= 0x030A0000 ||\ + (PyType_GetFlags(type) & Py_TPFLAGS_HEAPTYPE) || __Pyx_get_runtime_version() >= 0x030A0000) ?\ + __Pyx_PyType_GetSlot(type, name, func_ctype) : NULL) + #define __Pyx_PyType_GetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_GetSlot(obj, name, func_ctype) + #define __Pyx_PyType_TryGetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_TryGetSlot(obj, name, func_ctype) +#endif +#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) +#define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStrWithError(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStr(PyObject *dict, PyObject *name) { + PyObject *res = __Pyx_PyDict_GetItemStrWithError(dict, name); + if (res == NULL) PyErr_Clear(); + return res; +} +#elif !CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000 +#define __Pyx_PyDict_GetItemStrWithError PyDict_GetItemWithError +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#else +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict, PyObject *name) { +#if CYTHON_COMPILING_IN_PYPY + return PyDict_GetItem(dict, name); +#else + PyDictEntry *ep; + PyDictObject *mp = (PyDictObject*) dict; + long hash = ((PyStringObject *) name)->ob_shash; + assert(hash != -1); + ep = (mp->ma_lookup)(mp, name, hash); + if (ep == NULL) { + return NULL; + } + return ep->me_value; +#endif +} +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#endif +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags) + #define __Pyx_PyType_HasFeature(type, feature) ((__Pyx_PyType_GetFlags(type) & (feature)) != 0) +#else + #define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp)) + #define __Pyx_PyType_HasFeature(type, feature) PyType_HasFeature(type, feature) +#endif +#define __Pyx_PyObject_GetIterNextFunc(iterator) __Pyx_PyObject_GetSlot(iterator, tp_iternext, iternextfunc) +#if CYTHON_USE_TYPE_SPECS +#define __Pyx_PyHeapTypeObject_GC_Del(obj) {\ + PyTypeObject *type = Py_TYPE((PyObject*)obj);\ + assert(__Pyx_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE));\ + PyObject_GC_Del(obj);\ + Py_DECREF(type);\ +} +#else +#define __Pyx_PyHeapTypeObject_GC_Del(obj) PyObject_GC_Del(obj) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_ReadChar(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((void)u, 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((void)u, (0)) + #define __Pyx_PyUnicode_DATA(u) ((void*)u) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)k, PyUnicode_ReadChar((PyObject*)(d), i)) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GetLength(u)) +#else + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_READY(op) (0) + #else + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #endif + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) ((int)PyUnicode_KIND(u)) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, (Py_UCS4) ch) + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #else + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length)) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #endif + #endif +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #if !defined(PyUnicode_DecodeUnicodeEscape) + #define PyUnicode_DecodeUnicodeEscape(s, size, errors) PyUnicode_Decode(s, size, "unicode_escape", errors) + #endif + #if !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) + #endif + #if !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) + #endif + #if !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) + #endif +#endif +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && PyUnstable_Object_IsUniquelyReferenced(obj)) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#elif CYTHON_COMPILING_IN_CPYTHON + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#else + #define __Pyx_PySequence_ListKeepNew(obj) PySequence_List(obj) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) __Pyx_IS_TYPE(obj, &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +enum __Pyx_ReferenceSharing { + __Pyx_ReferenceSharing_DefinitelyUnique, // We created it so we know it's unshared - no need to check + __Pyx_ReferenceSharing_OwnStrongReference, + __Pyx_ReferenceSharing_FunctionArgument, + __Pyx_ReferenceSharing_SharedReference, // Never trust it to be unshared because it's a global or similar +}; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && PY_VERSION_HEX >= 0x030E0000 +#define __Pyx_IS_UNIQUELY_REFERENCED(o, sharing)\ + (sharing == __Pyx_ReferenceSharing_DefinitelyUnique ? 1 :\ + (sharing == __Pyx_ReferenceSharing_FunctionArgument ? PyUnstable_Object_IsUniqueReferencedTemporary(o) :\ + (sharing == __Pyx_ReferenceSharing_OwnStrongReference ? PyUnstable_Object_IsUniquelyReferenced(o) : 0))) +#elif (CYTHON_COMPILING_IN_CPYTHON && !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING) || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_IS_UNIQUELY_REFERENCED(o, sharing) (((void)sharing), Py_REFCNT(o) == 1) +#else +#define __Pyx_IS_UNIQUELY_REFERENCED(o, sharing) (((void)o), ((void)sharing), 0) +#endif +#if CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + #define __Pyx_PyList_GetItemRef(o, i) PyList_GetItemRef(o, i) + #elif CYTHON_COMPILING_IN_LIMITED_API || !CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PyList_GetItemRef(o, i) (likely((i) >= 0) ? PySequence_GetItem(o, i) : (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) + #else + #define __Pyx_PyList_GetItemRef(o, i) PySequence_ITEM(o, i) + #endif +#elif CYTHON_COMPILING_IN_LIMITED_API || !CYTHON_ASSUME_SAFE_MACROS + #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + #define __Pyx_PyList_GetItemRef(o, i) PyList_GetItemRef(o, i) + #else + #define __Pyx_PyList_GetItemRef(o, i) __Pyx_XNewRef(PyList_GetItem(o, i)) + #endif +#else + #define __Pyx_PyList_GetItemRef(o, i) __Pyx_NewRef(PyList_GET_ITEM(o, i)) +#endif +#if CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS && !CYTHON_COMPILING_IN_LIMITED_API && CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PyList_GetItemRefFast(o, i, unsafe_shared) (__Pyx_IS_UNIQUELY_REFERENCED(o, unsafe_shared) ?\ + __Pyx_NewRef(PyList_GET_ITEM(o, i)) : __Pyx_PyList_GetItemRef(o, i)) +#else + #define __Pyx_PyList_GetItemRefFast(o, i, unsafe_shared) __Pyx_PyList_GetItemRef(o, i) +#endif +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 +#define __Pyx_PyDict_GetItemRef(dict, key, result) PyDict_GetItemRef(dict, key, result) +#elif CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS +static CYTHON_INLINE int __Pyx_PyDict_GetItemRef(PyObject *dict, PyObject *key, PyObject **result) { + *result = PyObject_GetItem(dict, key); + if (*result == NULL) { + if (PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_Clear(); + return 0; + } + return -1; + } + return 1; +} +#else +static CYTHON_INLINE int __Pyx_PyDict_GetItemRef(PyObject *dict, PyObject *key, PyObject **result) { + *result = PyDict_GetItemWithError(dict, key); + if (*result == NULL) { + return PyErr_Occurred() ? -1 : 0; + } + Py_INCREF(*result); + return 1; +} +#endif +#if defined(CYTHON_DEBUG_VISIT_CONST) && CYTHON_DEBUG_VISIT_CONST + #define __Pyx_VISIT_CONST(obj) Py_VISIT(obj) +#else + #define __Pyx_VISIT_CONST(obj) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_ITEM(o, i) PySequence_ITEM(o, i) + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) (PyTuple_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyTuple_GET_ITEM(o, i) PyTuple_GET_ITEM(o, i) + #define __Pyx_PyList_SET_ITEM(o, i, v) (PyList_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyList_GET_ITEM(o, i) PyList_GET_ITEM(o, i) +#else + #define __Pyx_PySequence_ITEM(o, i) PySequence_GetItem(o, i) + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) PyTuple_SetItem(o, i, v) + #define __Pyx_PyTuple_GET_ITEM(o, i) PyTuple_GetItem(o, i) + #define __Pyx_PyList_SET_ITEM(o, i, v) PyList_SetItem(o, i, v) + #define __Pyx_PyList_GET_ITEM(o, i) PyList_GetItem(o, i) +#endif +#if CYTHON_ASSUME_SAFE_SIZE + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_GET_SIZE(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_GET_SIZE(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_GET_SIZE(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_GET_SIZE(o) + #define __Pyx_PyUnicode_GET_LENGTH(o) PyUnicode_GET_LENGTH(o) +#else + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_Size(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_Size(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_Size(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_Size(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_Size(o) + #define __Pyx_PyUnicode_GET_LENGTH(o) PyUnicode_GetLength(o) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_InternFromString) + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) +#endif +#define __Pyx_PyLong_FromHash_t PyLong_FromSsize_t +#define __Pyx_PyLong_AsHash_t __Pyx_PyIndex_AsSsize_t +#if __PYX_LIMITED_VERSION_HEX >= 0x030A0000 + #define __Pyx_PySendResult PySendResult +#else + typedef enum { + PYGEN_RETURN = 0, + PYGEN_ERROR = -1, + PYGEN_NEXT = 1, + } __Pyx_PySendResult; +#endif +#if CYTHON_COMPILING_IN_LIMITED_API || PY_VERSION_HEX < 0x030A00A3 + typedef __Pyx_PySendResult (*__Pyx_pyiter_sendfunc)(PyObject *iter, PyObject *value, PyObject **result); +#else + #define __Pyx_pyiter_sendfunc sendfunc +#endif +#if !CYTHON_USE_AM_SEND +#define __PYX_HAS_PY_AM_SEND 0 +#elif __PYX_LIMITED_VERSION_HEX >= 0x030A0000 +#define __PYX_HAS_PY_AM_SEND 1 +#else +#define __PYX_HAS_PY_AM_SEND 2 // our own backported implementation +#endif +#if __PYX_HAS_PY_AM_SEND < 2 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods +#else + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + __Pyx_pyiter_sendfunc am_send; + } __Pyx_PyAsyncMethodsStruct; + #define __Pyx_SlotTpAsAsync(s) ((PyAsyncMethods*)(s)) +#endif +#if CYTHON_USE_AM_SEND && PY_VERSION_HEX < 0x030A00F0 + #define __Pyx_TPFLAGS_HAVE_AM_SEND (1UL << 21) +#else + #define __Pyx_TPFLAGS_HAVE_AM_SEND (0) +#endif +#if PY_VERSION_HEX >= 0x03090000 +#define __Pyx_PyInterpreterState_Get() PyInterpreterState_Get() +#else +#define __Pyx_PyInterpreterState_Get() PyThreadState_Get()->interp +#endif +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030A0000 +#ifdef __cplusplus +extern "C" +#endif +PyAPI_FUNC(void *) PyMem_Calloc(size_t nelem, size_t elsize); +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static int __Pyx_init_co_variable(PyObject *inspect, const char* name, int *write_to) { + int value; + PyObject *py_value = PyObject_GetAttrString(inspect, name); + if (!py_value) return 0; + value = (int) PyLong_AsLong(py_value); + Py_DECREF(py_value); + *write_to = value; + return value != -1 || !PyErr_Occurred(); +} +static int __Pyx_init_co_variables(void) { + PyObject *inspect; + int result; + inspect = PyImport_ImportModule("inspect"); + result = +#if !defined(CO_OPTIMIZED) + __Pyx_init_co_variable(inspect, "CO_OPTIMIZED", &CO_OPTIMIZED) && +#endif +#if !defined(CO_NEWLOCALS) + __Pyx_init_co_variable(inspect, "CO_NEWLOCALS", &CO_NEWLOCALS) && +#endif +#if !defined(CO_VARARGS) + __Pyx_init_co_variable(inspect, "CO_VARARGS", &CO_VARARGS) && +#endif +#if !defined(CO_VARKEYWORDS) + __Pyx_init_co_variable(inspect, "CO_VARKEYWORDS", &CO_VARKEYWORDS) && +#endif +#if !defined(CO_ASYNC_GENERATOR) + __Pyx_init_co_variable(inspect, "CO_ASYNC_GENERATOR", &CO_ASYNC_GENERATOR) && +#endif +#if !defined(CO_GENERATOR) + __Pyx_init_co_variable(inspect, "CO_GENERATOR", &CO_GENERATOR) && +#endif +#if !defined(CO_COROUTINE) + __Pyx_init_co_variable(inspect, "CO_COROUTINE", &CO_COROUTINE) && +#endif + 1; + Py_DECREF(inspect); + return result ? 0 : -1; +} +#else +static int __Pyx_init_co_variables(void) { + return 0; // It's a limited API-only feature +} +#endif + +/* MathInitCode */ +#if defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS) + #ifndef _USE_MATH_DEFINES + #define _USE_MATH_DEFINES + #endif +#endif +#include +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#ifndef CYTHON_CLINE_IN_TRACEBACK_RUNTIME +#define CYTHON_CLINE_IN_TRACEBACK_RUNTIME 0 +#endif +#ifndef CYTHON_CLINE_IN_TRACEBACK +#define CYTHON_CLINE_IN_TRACEBACK CYTHON_CLINE_IN_TRACEBACK_RUNTIME +#endif +#if CYTHON_CLINE_IN_TRACEBACK +#define __PYX_MARK_ERR_POS(f_index, lineno) { __pyx_filename = __pyx_f[f_index]; (void) __pyx_filename; __pyx_lineno = lineno; (void) __pyx_lineno; __pyx_clineno = __LINE__; (void) __pyx_clineno; } +#else +#define __PYX_MARK_ERR_POS(f_index, lineno) { __pyx_filename = __pyx_f[f_index]; (void) __pyx_filename; __pyx_lineno = lineno; (void) __pyx_lineno; (void) __pyx_clineno; } +#endif +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifdef CYTHON_EXTERN_C + #undef __PYX_EXTERN_C + #define __PYX_EXTERN_C CYTHON_EXTERN_C +#elif defined(__PYX_EXTERN_C) + #ifdef _MSC_VER + #pragma message ("Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead.") + #else + #warning Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead. + #endif +#else + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__fontTools__feaLib__lexer +#define __PYX_HAVE_API__fontTools__feaLib__lexer +/* Early includes */ +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s); +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char*); +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyByteArray_AsString(s) PyByteArray_AS_STRING(s) +#else + #define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AsString(s)) + #define __Pyx_PyByteArray_AsString(s) PyByteArray_AsString(s) +#endif +#define __Pyx_PyObject_AsWritableString(s) ((char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +#define __Pyx_PyUnicode_FromOrdinal(o) PyUnicode_FromOrdinal((int)o) +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +static CYTHON_INLINE PyObject *__Pyx_NewRef(PyObject *obj) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030a0000 || defined(Py_NewRef) + return Py_NewRef(obj); +#else + Py_INCREF(obj); + return obj; +#endif +} +static CYTHON_INLINE PyObject *__Pyx_XNewRef(PyObject *obj) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030a0000 || defined(Py_XNewRef) + return Py_XNewRef(obj); +#else + Py_XINCREF(obj); + return obj; +#endif +} +static CYTHON_INLINE PyObject *__Pyx_Owned_Py_None(int b); +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_Long(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyLong_FromSize_t(size_t); +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*); +#if CYTHON_ASSUME_SAFE_MACROS +#define __Pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#define __Pyx_PyFloat_AS_DOUBLE(x) PyFloat_AS_DOUBLE(x) +#else +#define __Pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#define __Pyx_PyFloat_AS_DOUBLE(x) PyFloat_AsDouble(x) +#endif +#define __Pyx_PyFloat_AsFloat(x) ((float) __Pyx_PyFloat_AsDouble(x)) +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_VERSION_HEX >= 0x030C00A7 + #ifndef _PyLong_SIGN_MASK + #define _PyLong_SIGN_MASK 3 + #endif + #ifndef _PyLong_NON_SIZE_BITS + #define _PyLong_NON_SIZE_BITS 3 + #endif + #define __Pyx_PyLong_Sign(x) (((PyLongObject*)x)->long_value.lv_tag & _PyLong_SIGN_MASK) + #define __Pyx_PyLong_IsNeg(x) ((__Pyx_PyLong_Sign(x) & 2) != 0) + #define __Pyx_PyLong_IsNonNeg(x) (!__Pyx_PyLong_IsNeg(x)) + #define __Pyx_PyLong_IsZero(x) (__Pyx_PyLong_Sign(x) & 1) + #define __Pyx_PyLong_IsPos(x) (__Pyx_PyLong_Sign(x) == 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) (__Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) ((Py_ssize_t) (((PyLongObject*)x)->long_value.lv_tag >> _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_SignedDigitCount(x)\ + ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * __Pyx_PyLong_DigitCount(x)) + #if defined(PyUnstable_Long_IsCompact) && defined(PyUnstable_Long_CompactValue) + #define __Pyx_PyLong_IsCompact(x) PyUnstable_Long_IsCompact((PyLongObject*) x) + #define __Pyx_PyLong_CompactValue(x) PyUnstable_Long_CompactValue((PyLongObject*) x) + #else + #define __Pyx_PyLong_IsCompact(x) (((PyLongObject*)x)->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_CompactValue(x) ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * (Py_ssize_t) __Pyx_PyLong_Digits(x)[0]) + #endif + typedef Py_ssize_t __Pyx_compact_pylong; + typedef size_t __Pyx_compact_upylong; + #else + #define __Pyx_PyLong_IsNeg(x) (Py_SIZE(x) < 0) + #define __Pyx_PyLong_IsNonNeg(x) (Py_SIZE(x) >= 0) + #define __Pyx_PyLong_IsZero(x) (Py_SIZE(x) == 0) + #define __Pyx_PyLong_IsPos(x) (Py_SIZE(x) > 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) ((Py_SIZE(x) == 0) ? 0 : __Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) __Pyx_sst_abs(Py_SIZE(x)) + #define __Pyx_PyLong_SignedDigitCount(x) Py_SIZE(x) + #define __Pyx_PyLong_IsCompact(x) (Py_SIZE(x) == 0 || Py_SIZE(x) == 1 || Py_SIZE(x) == -1) + #define __Pyx_PyLong_CompactValue(x)\ + ((Py_SIZE(x) == 0) ? (sdigit) 0 : ((Py_SIZE(x) < 0) ? -(sdigit)__Pyx_PyLong_Digits(x)[0] : (sdigit)__Pyx_PyLong_Digits(x)[0])) + typedef sdigit __Pyx_compact_pylong; + typedef digit __Pyx_compact_upylong; + #endif + #if PY_VERSION_HEX >= 0x030C00A5 + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->long_value.ob_digit) + #else + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->ob_digit) + #endif +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 + #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#elif __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeASCII(c_str, size, NULL) +#else + #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +/* PretendToInitialize */ +#ifdef __cplusplus +#if __cplusplus > 201103L +#include +#endif +template +static void __Pyx_pretend_to_initialize(T* ptr) { +#if __cplusplus > 201103L + if ((std::is_trivially_default_constructible::value)) +#endif + *ptr = T(); + (void)ptr; +} +#else +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } +#endif + + +#if !CYTHON_USE_MODULE_STATE +static PyObject *__pyx_m = NULL; +#endif +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * const __pyx_cfilenm = __FILE__; +static const char *__pyx_filename; + +/* #### Code section: filename_table ### */ + +static const char* const __pyx_f[] = { + "Lib/fontTools/feaLib/lexer.py", +}; +/* #### Code section: utility_code_proto_before_types ### */ +/* Atomics.proto (used by UnpackUnboundCMethod) */ +#include +#ifndef CYTHON_ATOMICS + #define CYTHON_ATOMICS 1 +#endif +#define __PYX_CYTHON_ATOMICS_ENABLED() CYTHON_ATOMICS +#define __PYX_GET_CYTHON_COMPILING_IN_CPYTHON_FREETHREADING() CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __pyx_atomic_int_type int +#define __pyx_nonatomic_int_type int +#if CYTHON_ATOMICS && (defined(__STDC_VERSION__) &&\ + (__STDC_VERSION__ >= 201112L) &&\ + !defined(__STDC_NO_ATOMICS__)) + #include +#elif CYTHON_ATOMICS && (defined(__cplusplus) && (\ + (__cplusplus >= 201103L) ||\ + (defined(_MSC_VER) && _MSC_VER >= 1700))) + #include +#endif +#if CYTHON_ATOMICS && (defined(__STDC_VERSION__) &&\ + (__STDC_VERSION__ >= 201112L) &&\ + !defined(__STDC_NO_ATOMICS__) &&\ + ATOMIC_INT_LOCK_FREE == 2) + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type atomic_int + #define __pyx_atomic_ptr_type atomic_uintptr_t + #define __pyx_nonatomic_ptr_type uintptr_t + #define __pyx_atomic_incr_relaxed(value) atomic_fetch_add_explicit(value, 1, memory_order_relaxed) + #define __pyx_atomic_incr_acq_rel(value) atomic_fetch_add_explicit(value, 1, memory_order_acq_rel) + #define __pyx_atomic_decr_acq_rel(value) atomic_fetch_sub_explicit(value, 1, memory_order_acq_rel) + #define __pyx_atomic_sub(value, arg) atomic_fetch_sub(value, arg) + #define __pyx_atomic_int_cmp_exchange(value, expected, desired) atomic_compare_exchange_strong(value, expected, desired) + #define __pyx_atomic_load(value) atomic_load(value) + #define __pyx_atomic_store(value, new_value) atomic_store(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) atomic_load_explicit(value, memory_order_relaxed) + #define __pyx_atomic_pointer_load_acquire(value) atomic_load_explicit(value, memory_order_acquire) + #define __pyx_atomic_pointer_exchange(value, new_value) atomic_exchange(value, (__pyx_nonatomic_ptr_type)new_value) + #define __pyx_atomic_pointer_cmp_exchange(value, expected, desired) atomic_compare_exchange_strong(value, expected, desired) + #if defined(__PYX_DEBUG_ATOMICS) && defined(_MSC_VER) + #pragma message ("Using standard C atomics") + #elif defined(__PYX_DEBUG_ATOMICS) + #warning "Using standard C atomics" + #endif +#elif CYTHON_ATOMICS && (defined(__cplusplus) && (\ + (__cplusplus >= 201103L) ||\ +\ + (defined(_MSC_VER) && _MSC_VER >= 1700)) &&\ + ATOMIC_INT_LOCK_FREE == 2) + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type std::atomic_int + #define __pyx_atomic_ptr_type std::atomic_uintptr_t + #define __pyx_nonatomic_ptr_type uintptr_t + #define __pyx_atomic_incr_relaxed(value) std::atomic_fetch_add_explicit(value, 1, std::memory_order_relaxed) + #define __pyx_atomic_incr_acq_rel(value) std::atomic_fetch_add_explicit(value, 1, std::memory_order_acq_rel) + #define __pyx_atomic_decr_acq_rel(value) std::atomic_fetch_sub_explicit(value, 1, std::memory_order_acq_rel) + #define __pyx_atomic_sub(value, arg) std::atomic_fetch_sub(value, arg) + #define __pyx_atomic_int_cmp_exchange(value, expected, desired) std::atomic_compare_exchange_strong(value, expected, desired) + #define __pyx_atomic_load(value) std::atomic_load(value) + #define __pyx_atomic_store(value, new_value) std::atomic_store(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) std::atomic_load_explicit(value, std::memory_order_relaxed) + #define __pyx_atomic_pointer_load_acquire(value) std::atomic_load_explicit(value, std::memory_order_acquire) + #define __pyx_atomic_pointer_exchange(value, new_value) std::atomic_exchange(value, (__pyx_nonatomic_ptr_type)new_value) + #define __pyx_atomic_pointer_cmp_exchange(value, expected, desired) std::atomic_compare_exchange_strong(value, expected, desired) + #if defined(__PYX_DEBUG_ATOMICS) && defined(_MSC_VER) + #pragma message ("Using standard C++ atomics") + #elif defined(__PYX_DEBUG_ATOMICS) + #warning "Using standard C++ atomics" + #endif +#elif CYTHON_ATOMICS && (__GNUC__ >= 5 || (__GNUC__ == 4 &&\ + (__GNUC_MINOR__ > 1 ||\ + (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ >= 2)))) + #define __pyx_atomic_ptr_type void* + #define __pyx_nonatomic_ptr_type void* + #define __pyx_atomic_incr_relaxed(value) __sync_fetch_and_add(value, 1) + #define __pyx_atomic_incr_acq_rel(value) __sync_fetch_and_add(value, 1) + #define __pyx_atomic_decr_acq_rel(value) __sync_fetch_and_sub(value, 1) + #define __pyx_atomic_sub(value, arg) __sync_fetch_and_sub(value, arg) + static CYTHON_INLINE int __pyx_atomic_int_cmp_exchange(__pyx_atomic_int_type* value, __pyx_nonatomic_int_type* expected, __pyx_nonatomic_int_type desired) { + __pyx_nonatomic_int_type old = __sync_val_compare_and_swap(value, *expected, desired); + int result = old == *expected; + *expected = old; + return result; + } + #define __pyx_atomic_load(value) __sync_fetch_and_add(value, 0) + #define __pyx_atomic_store(value, new_value) __sync_lock_test_and_set(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) __sync_fetch_and_add(value, 0) + #define __pyx_atomic_pointer_load_acquire(value) __sync_fetch_and_add(value, 0) + #define __pyx_atomic_pointer_exchange(value, new_value) __sync_lock_test_and_set(value, (__pyx_atomic_ptr_type)new_value) + static CYTHON_INLINE int __pyx_atomic_pointer_cmp_exchange(__pyx_atomic_ptr_type* value, __pyx_nonatomic_ptr_type* expected, __pyx_nonatomic_ptr_type desired) { + __pyx_nonatomic_ptr_type old = __sync_val_compare_and_swap(value, *expected, desired); + int result = old == *expected; + *expected = old; + return result; + } + #ifdef __PYX_DEBUG_ATOMICS + #warning "Using GNU atomics" + #endif +#elif CYTHON_ATOMICS && defined(_MSC_VER) + #include + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type long + #define __pyx_atomic_ptr_type void* + #undef __pyx_nonatomic_int_type + #define __pyx_nonatomic_int_type long + #define __pyx_nonatomic_ptr_type void* + #pragma intrinsic (_InterlockedExchangeAdd, _InterlockedExchange, _InterlockedCompareExchange, _InterlockedCompareExchangePointer, _InterlockedExchangePointer) + #define __pyx_atomic_incr_relaxed(value) _InterlockedExchangeAdd(value, 1) + #define __pyx_atomic_incr_acq_rel(value) _InterlockedExchangeAdd(value, 1) + #define __pyx_atomic_decr_acq_rel(value) _InterlockedExchangeAdd(value, -1) + #define __pyx_atomic_sub(value, arg) _InterlockedExchangeAdd(value, -arg) + static CYTHON_INLINE int __pyx_atomic_int_cmp_exchange(__pyx_atomic_int_type* value, __pyx_nonatomic_int_type* expected, __pyx_nonatomic_int_type desired) { + __pyx_nonatomic_int_type old = _InterlockedCompareExchange(value, desired, *expected); + int result = old == *expected; + *expected = old; + return result; + } + #define __pyx_atomic_load(value) _InterlockedExchangeAdd(value, 0) + #define __pyx_atomic_store(value, new_value) _InterlockedExchange(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) *(void * volatile *)value + #define __pyx_atomic_pointer_load_acquire(value) _InterlockedCompareExchangePointer(value, 0, 0) + #define __pyx_atomic_pointer_exchange(value, new_value) _InterlockedExchangePointer(value, (__pyx_atomic_ptr_type)new_value) + static CYTHON_INLINE int __pyx_atomic_pointer_cmp_exchange(__pyx_atomic_ptr_type* value, __pyx_nonatomic_ptr_type* expected, __pyx_nonatomic_ptr_type desired) { + __pyx_atomic_ptr_type old = _InterlockedCompareExchangePointer(value, desired, *expected); + int result = old == *expected; + *expected = old; + return result; + } + #ifdef __PYX_DEBUG_ATOMICS + #pragma message ("Using MSVC atomics") + #endif +#else + #undef CYTHON_ATOMICS + #define CYTHON_ATOMICS 0 + #ifdef __PYX_DEBUG_ATOMICS + #warning "Not using atomics" + #endif +#endif + +/* CriticalSectionsDefinition.proto (used by CriticalSections) */ +#if !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __Pyx_PyCriticalSection void* +#define __Pyx_PyCriticalSection2 void* +#define __Pyx_PyCriticalSection_End(cs) +#define __Pyx_PyCriticalSection2_End(cs) +#else +#define __Pyx_PyCriticalSection PyCriticalSection +#define __Pyx_PyCriticalSection2 PyCriticalSection2 +#define __Pyx_PyCriticalSection_End PyCriticalSection_End +#define __Pyx_PyCriticalSection2_End PyCriticalSection2_End +#endif + +/* CriticalSections.proto (used by ParseKeywordsImpl) */ +#if !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __Pyx_PyCriticalSection_Begin(cs, arg) (void)(cs) +#define __Pyx_PyCriticalSection2_Begin(cs, arg1, arg2) (void)(cs) +#else +#define __Pyx_PyCriticalSection_Begin PyCriticalSection_Begin +#define __Pyx_PyCriticalSection2_Begin PyCriticalSection2_Begin +#endif +#if PY_VERSION_HEX < 0x030d0000 || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_BEGIN_CRITICAL_SECTION(o) { +#define __Pyx_END_CRITICAL_SECTION() } +#else +#define __Pyx_BEGIN_CRITICAL_SECTION Py_BEGIN_CRITICAL_SECTION +#define __Pyx_END_CRITICAL_SECTION Py_END_CRITICAL_SECTION +#endif + +/* IncludeStructmemberH.proto (used by FixUpExtensionType) */ +#include + +/* #### Code section: numeric_typedefs ### */ +/* #### Code section: complex_type_declarations ### */ +/* #### Code section: type_declarations ### */ + +/*--- Type declarations ---*/ +/* #### Code section: utility_code_proto ### */ + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, Py_ssize_t); + void (*DECREF)(void*, PyObject*, Py_ssize_t); + void (*GOTREF)(void*, PyObject*, Py_ssize_t); + void (*GIVEREF)(void*, PyObject*, Py_ssize_t); + void* (*SetupContext)(const char*, Py_ssize_t, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_XINCREF(r) do { if((r) == NULL); else {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) == NULL); else {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) == NULL); else {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) == NULL); else {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContextNogil() + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_Py_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; Py_XDECREF(tmp);\ + } while (0) +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* PyErrExceptionMatches.proto (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* PyThreadStateGet.proto (used by PyErrFetchRestore) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#if PY_VERSION_HEX >= 0x030C00A6 +#define __Pyx_PyErr_Occurred() (__pyx_tstate->current_exception != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->current_exception ? (PyObject*) Py_TYPE(__pyx_tstate->current_exception) : (PyObject*) NULL) +#else +#define __Pyx_PyErr_Occurred() (__pyx_tstate->curexc_type != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->curexc_type) +#endif +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() (PyErr_Occurred() != NULL) +#define __Pyx_PyErr_CurrentExceptionType() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A6 +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* PyObjectGetAttrStr.proto (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* PyObjectGetAttrStrNoError.proto (used by GetBuiltinName) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* TupleAndListFromArray.proto (used by fastcall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n); +#endif +#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n); +#endif + +/* IncludeStringH.proto (used by BytesEquals) */ +#include + +/* BytesEquals.proto (used by UnicodeEquals) */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); + +/* UnicodeEquals.proto (used by fastcall) */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); + +/* fastcall.proto */ +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_ArgRef_VARARGS(args, i) __Pyx_PySequence_ITEM(args, i) +#elif CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_ArgRef_VARARGS(args, i) __Pyx_NewRef(__Pyx_PyTuple_GET_ITEM(args, i)) +#else + #define __Pyx_ArgRef_VARARGS(args, i) __Pyx_XNewRef(PyTuple_GetItem(args, i)) +#endif +#define __Pyx_NumKwargs_VARARGS(kwds) PyDict_Size(kwds) +#define __Pyx_KwValues_VARARGS(args, nargs) NULL +#define __Pyx_GetKwValue_VARARGS(kw, kwvalues, s) __Pyx_PyDict_GetItemStrWithError(kw, s) +#define __Pyx_KwargsAsDict_VARARGS(kw, kwvalues) PyDict_Copy(kw) +#if CYTHON_METH_FASTCALL + #define __Pyx_ArgRef_FASTCALL(args, i) __Pyx_NewRef(args[i]) + #define __Pyx_NumKwargs_FASTCALL(kwds) __Pyx_PyTuple_GET_SIZE(kwds) + #define __Pyx_KwValues_FASTCALL(args, nargs) ((args) + (nargs)) + static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 || CYTHON_COMPILING_IN_LIMITED_API + CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues); + #else + #define __Pyx_KwargsAsDict_FASTCALL(kw, kwvalues) _PyStack_AsDict(kwvalues, kw) + #endif +#else + #define __Pyx_ArgRef_FASTCALL __Pyx_ArgRef_VARARGS + #define __Pyx_NumKwargs_FASTCALL __Pyx_NumKwargs_VARARGS + #define __Pyx_KwValues_FASTCALL __Pyx_KwValues_VARARGS + #define __Pyx_GetKwValue_FASTCALL __Pyx_GetKwValue_VARARGS + #define __Pyx_KwargsAsDict_FASTCALL __Pyx_KwargsAsDict_VARARGS +#endif +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) PyTuple_GetSlice(args, start, stop) +#if CYTHON_METH_FASTCALL || (CYTHON_COMPILING_IN_CPYTHON && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) __Pyx_PyTuple_FromArray(args + start, stop - start) +#else +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) PyTuple_GetSlice(args, start, stop) +#endif + +/* py_dict_items.proto (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d); + +/* CallCFunction.proto (used by CallUnboundCMethod0) */ +#define __Pyx_CallCFunction(cfunc, self, args)\ + ((PyCFunction)(void(*)(void))(cfunc)->func)(self, args) +#define __Pyx_CallCFunctionWithKeywords(cfunc, self, args, kwargs)\ + ((PyCFunctionWithKeywords)(void(*)(void))(cfunc)->func)(self, args, kwargs) +#define __Pyx_CallCFunctionFast(cfunc, self, args, nargs)\ + ((__Pyx_PyCFunctionFast)(void(*)(void))(PyCFunction)(cfunc)->func)(self, args, nargs) +#define __Pyx_CallCFunctionFastWithKeywords(cfunc, self, args, nargs, kwnames)\ + ((__Pyx_PyCFunctionFastWithKeywords)(void(*)(void))(PyCFunction)(cfunc)->func)(self, args, nargs, kwnames) + +/* PyObjectCall.proto (used by PyObjectFastCall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* PyObjectCallMethO.proto (used by PyObjectFastCall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectFastCall.proto (used by PyObjectCallOneArg) */ +#define __Pyx_PyObject_FastCall(func, args, nargs) __Pyx_PyObject_FastCallDict(func, args, (size_t)(nargs), NULL) +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject * const*args, size_t nargs, PyObject *kwargs); + +/* PyObjectCallOneArg.proto (used by CallUnboundCMethod0) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* UnpackUnboundCMethod.proto (used by CallUnboundCMethod0) */ +typedef struct { + PyObject *type; + PyObject **method_name; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && CYTHON_ATOMICS + __pyx_atomic_int_type initialized; +#endif + PyCFunction func; + PyObject *method; + int flag; +} __Pyx_CachedCFunction; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +static CYTHON_INLINE int __Pyx_CachedCFunction_GetAndSetInitializing(__Pyx_CachedCFunction *cfunc) { +#if !CYTHON_ATOMICS + return 1; +#else + __pyx_nonatomic_int_type expected = 0; + if (__pyx_atomic_int_cmp_exchange(&cfunc->initialized, &expected, 1)) { + return 0; + } + return expected; +#endif +} +static CYTHON_INLINE void __Pyx_CachedCFunction_SetFinishedInitializing(__Pyx_CachedCFunction *cfunc) { +#if CYTHON_ATOMICS + __pyx_atomic_store(&cfunc->initialized, 2); +#endif +} +#else +#define __Pyx_CachedCFunction_GetAndSetInitializing(cfunc) 2 +#define __Pyx_CachedCFunction_SetFinishedInitializing(cfunc) +#endif + +/* CallUnboundCMethod0.proto */ +CYTHON_UNUSED +static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self); +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self); +#else +#define __Pyx_CallUnboundCMethod0(cfunc, self) __Pyx__CallUnboundCMethod0(cfunc, self) +#endif + +/* py_dict_values.proto (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Values(PyObject* d); + +/* OwnedDictNext.proto (used by ParseKeywordsImpl) */ +#if CYTHON_AVOID_BORROWED_REFS +static int __Pyx_PyDict_NextRef(PyObject *p, PyObject **ppos, PyObject **pkey, PyObject **pvalue); +#else +CYTHON_INLINE +static int __Pyx_PyDict_NextRef(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue); +#endif + +/* RaiseDoubleKeywords.proto (used by ParseKeywordsImpl) */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywordsImpl.export */ +static int __Pyx_ParseKeywordsTuple( + PyObject *kwds, + PyObject * const *kwvalues, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs +); +static int __Pyx_ParseKeywordDictToDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name +); +static int __Pyx_ParseKeywordDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs +); + +/* CallUnboundCMethod2.proto */ +CYTHON_UNUSED +static PyObject* __Pyx__CallUnboundCMethod2(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg1, PyObject* arg2); +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject *__Pyx_CallUnboundCMethod2(__Pyx_CachedCFunction *cfunc, PyObject *self, PyObject *arg1, PyObject *arg2); +#else +#define __Pyx_CallUnboundCMethod2(cfunc, self, arg1, arg2) __Pyx__CallUnboundCMethod2(cfunc, self, arg1, arg2) +#endif + +/* ParseKeywords.proto */ +static CYTHON_INLINE int __Pyx_ParseKeywords( + PyObject *kwds, PyObject *const *kwvalues, PyObject ** const argnames[], + PyObject *kwds2, PyObject *values[], + Py_ssize_t num_pos_args, Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs +); + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* PyObjectDelAttr.proto (used by PyObjectSetAttrStr) */ +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030d0000 +#define __Pyx_PyObject_DelAttr(o, n) PyObject_SetAttr(o, n, NULL) +#else +#define __Pyx_PyObject_DelAttr(o, n) PyObject_DelAttr(o, n) +#endif + +/* PyObjectSetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +#define __Pyx_PyObject_DelAttrStr(o,n) __Pyx_PyObject_SetAttrStr(o, n, NULL) +static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr_name, PyObject* value); +#else +#define __Pyx_PyObject_DelAttrStr(o,n) __Pyx_PyObject_DelAttr(o,n) +#define __Pyx_PyObject_SetAttrStr(o,n,v) PyObject_SetAttr(o,n,v) +#endif + +/* PyDictVersioning.proto (used by GetModuleGlobalName) */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __Pyx_XNewRef(__pyx_dict_cached_value);\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* GetModuleGlobalName.proto */ +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) do {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_mstate_global->__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +#define __Pyx_GetModuleGlobalNameUncached(var, name) do {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif + +/* PyObjectFastCallMethod.proto */ +#if CYTHON_VECTORCALL && PY_VERSION_HEX >= 0x03090000 +#define __Pyx_PyObject_FastCallMethod(name, args, nargsf) PyObject_VectorcallMethod(name, args, nargsf, NULL) +#else +static PyObject *__Pyx_PyObject_FastCallMethod(PyObject *name, PyObject *const *args, size_t nargsf); +#endif + +/* RaiseTooManyValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +/* RaiseNeedMoreValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +/* IterFinish.proto */ +static CYTHON_INLINE int __Pyx_IterFinish(void); + +/* UnpackItemEndCheck.proto */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); + +/* PyLongBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static CYTHON_INLINE PyObject* __Pyx_PyLong_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyLong_AddObjC(op1, op2, intval, inplace, zerodivision_check)\ + (inplace ? PyNumber_InPlaceAdd(op1, op2) : PyNumber_Add(op1, op2)) +#endif + +/* PyStopIteration_Check.proto */ +#define __Pyx_PyExc_StopIteration_Check(obj) __Pyx_TypeCheck(obj, PyExc_StopIteration) + +/* RaiseException.export */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* GetItemInt.proto */ +#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck, has_gil, unsafe_shared)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck, unsafe_shared) :\ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ + __Pyx_GetItemInt_Generic(o, to_py_func(i)))) +#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck, has_gil, unsafe_shared)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck, unsafe_shared) :\ + (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck, int unsafe_shared); +#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck, has_gil, unsafe_shared)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck, unsafe_shared) :\ + (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck, int unsafe_shared); +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, + int is_list, int wraparound, int boundscheck, int unsafe_shared); + +/* ObjectGetItem.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject *key); +#else +#define __Pyx_PyObject_GetItem(obj, key) PyObject_GetItem(obj, key) +#endif + +/* SliceObject.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice( + PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop, + PyObject** py_start, PyObject** py_stop, PyObject** py_slice, + int has_cstart, int has_cstop, int wraparound); + +/* PyLongBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static CYTHON_INLINE PyObject* __Pyx_PyLong_SubtractObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyLong_SubtractObjC(op1, op2, intval, inplace, zerodivision_check)\ + (inplace ? PyNumber_InPlaceSubtract(op1, op2) : PyNumber_Subtract(op1, op2)) +#endif + +/* PySequenceContains.proto */ +static CYTHON_INLINE int __Pyx_PySequence_ContainsTF(PyObject* item, PyObject* seq, int eq) { + int result = PySequence_Contains(seq, item); + return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); +} + +/* PyUnicodeContains.proto */ +static CYTHON_INLINE int __Pyx_PyUnicode_ContainsTF(PyObject* substring, PyObject* text, int eq) { + int result = PyUnicode_Contains(text, substring); + return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); +} + +/* pybytes_as_double.proto (used by pynumber_float) */ +static double __Pyx_SlowPyString_AsDouble(PyObject *obj); +static double __Pyx__PyBytes_AsDouble(PyObject *obj, const char* start, Py_ssize_t length); +static CYTHON_INLINE double __Pyx_PyBytes_AsDouble(PyObject *obj) { + char* as_c_string; + Py_ssize_t size; +#if CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE + as_c_string = PyBytes_AS_STRING(obj); + size = PyBytes_GET_SIZE(obj); +#else + if (PyBytes_AsStringAndSize(obj, &as_c_string, &size) < 0) { + return (double)-1; + } +#endif + return __Pyx__PyBytes_AsDouble(obj, as_c_string, size); +} +static CYTHON_INLINE double __Pyx_PyByteArray_AsDouble(PyObject *obj) { + char* as_c_string; + Py_ssize_t size; +#if CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE + as_c_string = PyByteArray_AS_STRING(obj); + size = PyByteArray_GET_SIZE(obj); +#else + as_c_string = PyByteArray_AsString(obj); + if (as_c_string == NULL) { + return (double)-1; + } + size = PyByteArray_Size(obj); +#endif + return __Pyx__PyBytes_AsDouble(obj, as_c_string, size); +} + +/* pyunicode_as_double.proto (used by pynumber_float) */ +#if !CYTHON_COMPILING_IN_PYPY && CYTHON_ASSUME_SAFE_MACROS +static const char* __Pyx__PyUnicode_AsDouble_Copy(const void* data, const int kind, char* buffer, Py_ssize_t start, Py_ssize_t end) { + int last_was_punctuation; + Py_ssize_t i; + last_was_punctuation = 1; + for (i=start; i <= end; i++) { + Py_UCS4 chr = PyUnicode_READ(kind, data, i); + int is_punctuation = (chr == '_') | (chr == '.'); + *buffer = (char)chr; + buffer += (chr != '_'); + if (unlikely(chr > 127)) goto parse_failure; + if (unlikely(last_was_punctuation & is_punctuation)) goto parse_failure; + last_was_punctuation = is_punctuation; + } + if (unlikely(last_was_punctuation)) goto parse_failure; + *buffer = '\0'; + return buffer; +parse_failure: + return NULL; +} +static double __Pyx__PyUnicode_AsDouble_inf_nan(const void* data, int kind, Py_ssize_t start, Py_ssize_t length) { + int matches = 1; + Py_UCS4 chr; + Py_UCS4 sign = PyUnicode_READ(kind, data, start); + int is_signed = (sign == '-') | (sign == '+'); + start += is_signed; + length -= is_signed; + switch (PyUnicode_READ(kind, data, start)) { + #ifdef Py_NAN + case 'n': + case 'N': + if (unlikely(length != 3)) goto parse_failure; + chr = PyUnicode_READ(kind, data, start+1); + matches &= (chr == 'a') | (chr == 'A'); + chr = PyUnicode_READ(kind, data, start+2); + matches &= (chr == 'n') | (chr == 'N'); + if (unlikely(!matches)) goto parse_failure; + return (sign == '-') ? -Py_NAN : Py_NAN; + #endif + case 'i': + case 'I': + if (unlikely(length < 3)) goto parse_failure; + chr = PyUnicode_READ(kind, data, start+1); + matches &= (chr == 'n') | (chr == 'N'); + chr = PyUnicode_READ(kind, data, start+2); + matches &= (chr == 'f') | (chr == 'F'); + if (likely(length == 3 && matches)) + return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL; + if (unlikely(length != 8)) goto parse_failure; + chr = PyUnicode_READ(kind, data, start+3); + matches &= (chr == 'i') | (chr == 'I'); + chr = PyUnicode_READ(kind, data, start+4); + matches &= (chr == 'n') | (chr == 'N'); + chr = PyUnicode_READ(kind, data, start+5); + matches &= (chr == 'i') | (chr == 'I'); + chr = PyUnicode_READ(kind, data, start+6); + matches &= (chr == 't') | (chr == 'T'); + chr = PyUnicode_READ(kind, data, start+7); + matches &= (chr == 'y') | (chr == 'Y'); + if (unlikely(!matches)) goto parse_failure; + return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL; + case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + break; + default: + goto parse_failure; + } + return 0.0; +parse_failure: + return -1.0; +} +static double __Pyx_PyUnicode_AsDouble_WithSpaces(PyObject *obj) { + double value; + const char *last; + char *end; + Py_ssize_t start, length = PyUnicode_GET_LENGTH(obj); + const int kind = PyUnicode_KIND(obj); + const void* data = PyUnicode_DATA(obj); + start = 0; + while (Py_UNICODE_ISSPACE(PyUnicode_READ(kind, data, start))) + start++; + while (start < length - 1 && Py_UNICODE_ISSPACE(PyUnicode_READ(kind, data, length - 1))) + length--; + length -= start; + if (unlikely(length <= 0)) goto fallback; + value = __Pyx__PyUnicode_AsDouble_inf_nan(data, kind, start, length); + if (unlikely(value == -1.0)) goto fallback; + if (value != 0.0) return value; + if (length < 40) { + char number[40]; + last = __Pyx__PyUnicode_AsDouble_Copy(data, kind, number, start, start + length); + if (unlikely(!last)) goto fallback; + value = PyOS_string_to_double(number, &end, NULL); + } else { + char *number = (char*) PyMem_Malloc((length + 1) * sizeof(char)); + if (unlikely(!number)) goto fallback; + last = __Pyx__PyUnicode_AsDouble_Copy(data, kind, number, start, start + length); + if (unlikely(!last)) { + PyMem_Free(number); + goto fallback; + } + value = PyOS_string_to_double(number, &end, NULL); + PyMem_Free(number); + } + if (likely(end == last) || (value == (double)-1 && PyErr_Occurred())) { + return value; + } +fallback: + return __Pyx_SlowPyString_AsDouble(obj); +} +#endif +static CYTHON_INLINE double __Pyx_PyUnicode_AsDouble(PyObject *obj) { +#if !CYTHON_COMPILING_IN_PYPY && CYTHON_ASSUME_SAFE_MACROS + if (unlikely(__Pyx_PyUnicode_READY(obj) == -1)) + return (double)-1; + if (likely(PyUnicode_IS_ASCII(obj))) { + const char *s; + Py_ssize_t length; + s = PyUnicode_AsUTF8AndSize(obj, &length); + return __Pyx__PyBytes_AsDouble(obj, s, length); + } + return __Pyx_PyUnicode_AsDouble_WithSpaces(obj); +#else + return __Pyx_SlowPyString_AsDouble(obj); +#endif +} + +/* pynumber_float.proto */ +static CYTHON_INLINE PyObject* __Pyx__PyNumber_Float(PyObject* obj); +#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : __Pyx__PyNumber_Float(x)) + +/* PyObjectVectorCallKwBuilder.proto */ +CYTHON_UNUSED static int __Pyx_VectorcallBuilder_AddArg_Check(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n); +#if CYTHON_VECTORCALL +#if PY_VERSION_HEX >= 0x03090000 +#define __Pyx_Object_Vectorcall_CallFromBuilder PyObject_Vectorcall +#else +#define __Pyx_Object_Vectorcall_CallFromBuilder _PyObject_Vectorcall +#endif +#define __Pyx_MakeVectorcallBuilderKwds(n) PyTuple_New(n) +static int __Pyx_VectorcallBuilder_AddArg(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n); +static int __Pyx_VectorcallBuilder_AddArgStr(const char *key, PyObject *value, PyObject *builder, PyObject **args, int n); +#else +#define __Pyx_Object_Vectorcall_CallFromBuilder __Pyx_PyObject_FastCallDict +#define __Pyx_MakeVectorcallBuilderKwds(n) __Pyx_PyDict_NewPresized(n) +#define __Pyx_VectorcallBuilder_AddArg(key, value, builder, args, n) PyDict_SetItem(builder, key, value) +#define __Pyx_VectorcallBuilder_AddArgStr(key, value, builder, args, n) PyDict_SetItemString(builder, key, value) +#endif + +/* PyFileNotFoundError_Check.proto */ +#define __Pyx_PyExc_FileNotFoundError_Check(obj) __Pyx_TypeCheck(obj, PyExc_FileNotFoundError) + +/* IterNextPlain.proto (used by IterNext) */ +static CYTHON_INLINE PyObject *__Pyx_PyIter_Next_Plain(PyObject *iterator); +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 +static PyObject *__Pyx_GetBuiltinNext_LimitedAPI(void); +#endif + +/* IterNext.proto */ +#define __Pyx_PyIter_Next(obj) __Pyx_PyIter_Next2(obj, NULL) +static CYTHON_INLINE PyObject *__Pyx_PyIter_Next2(PyObject *, PyObject *); + +/* GetTopmostException.proto (used by SaveResetException) */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); +#endif + +/* SaveResetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +#else +#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) +#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) +#endif + +/* GetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* PyObjectCallNoArg.proto (used by PyObjectCallMethod0) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); + +/* PyObjectGetMethod.proto (used by PyObjectCallMethod0) */ +#if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))) +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); +#endif + +/* PyObjectCallMethod0.proto (used by pop) */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name); + +/* pop.proto */ +static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L); +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE +static CYTHON_INLINE PyObject* __Pyx_PyList_Pop(PyObject* L); +#define __Pyx_PyObject_Pop(L) (likely(PyList_CheckExact(L)) ?\ + __Pyx_PyList_Pop(L) : __Pyx__PyObject_Pop(L)) +#else +#define __Pyx_PyList_Pop(L) __Pyx__PyObject_Pop(L) +#define __Pyx_PyObject_Pop(L) __Pyx__PyObject_Pop(L) +#endif + +/* ListAppend.proto (used by append) */ +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) { + PyListObject* L = (PyListObject*) list; + Py_ssize_t len = Py_SIZE(list); + if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) { + Py_INCREF(x); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + L->ob_item[len] = x; + #else + PyList_SET_ITEM(list, len, x); + #endif + __Pyx_SET_SIZE(list, len + 1); + return 0; + } + return PyList_Append(list, x); +} +#else +#define __Pyx_PyList_Append(L,x) PyList_Append(L,x) +#endif + +/* PyObjectCall2Args.proto (used by PyObjectCallMethod1) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + +/* PyObjectCallMethod1.proto (used by append) */ +static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg); + +/* append.proto */ +static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x); + +/* SwapException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSwap(type, value, tb) __Pyx__ExceptionSwap(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* HasAttr.proto */ +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 +#define __Pyx_HasAttr(o, n) PyObject_HasAttrWithError(o, n) +#else +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *, PyObject *); +#endif + +/* GetAttr3.proto */ +static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); + +/* ImportImpl.export */ +static PyObject *__Pyx__Import(PyObject *name, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject *qualname, PyObject *moddict, int level); + +/* Import.proto */ +static CYTHON_INLINE PyObject *__Pyx_Import(PyObject *name, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject *qualname, int level); + +/* ImportFrom.proto */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); + +/* Py3UpdateBases.proto */ +static PyObject* __Pyx_PEP560_update_bases(PyObject *bases); + +/* CalculateMetaclass.proto */ +static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases); + +/* SetNameInClass.proto */ +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 +#define __Pyx_SetNameInClass(ns, name, value)\ + (likely(PyDict_CheckExact(ns)) ? _PyDict_SetItem_KnownHash(ns, name, value, ((PyASCIIObject *) name)->hash) : PyObject_SetItem(ns, name, value)) +#elif CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_SetNameInClass(ns, name, value)\ + (likely(PyDict_CheckExact(ns)) ? PyDict_SetItem(ns, name, value) : PyObject_SetItem(ns, name, value)) +#else +#define __Pyx_SetNameInClass(ns, name, value) PyObject_SetItem(ns, name, value) +#endif + +/* dict_setdefault.proto (used by FetchCommonType) */ +static CYTHON_INLINE PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value); + +/* LimitedApiGetTypeDict.proto (used by SetItemOnTypeDict) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_GetTypeDict(PyTypeObject *tp); +#endif + +/* SetItemOnTypeDict.proto (used by FixUpExtensionType) */ +static int __Pyx__SetItemOnTypeDict(PyTypeObject *tp, PyObject *k, PyObject *v); +#define __Pyx_SetItemOnTypeDict(tp, k, v) __Pyx__SetItemOnTypeDict((PyTypeObject*)tp, k, v) + +/* FixUpExtensionType.proto (used by FetchCommonType) */ +static CYTHON_INLINE int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type); + +/* AddModuleRef.proto (used by FetchSharedCythonModule) */ +#if ((CYTHON_COMPILING_IN_CPYTHON_FREETHREADING ) ||\ + __PYX_LIMITED_VERSION_HEX < 0x030d0000) + static PyObject *__Pyx_PyImport_AddModuleRef(const char *name); +#else + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#endif + +/* FetchSharedCythonModule.proto (used by FetchCommonType) */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void); + +/* FetchCommonType.proto (used by CommonTypesMetaclass) */ +static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases); + +/* CommonTypesMetaclass.proto (used by CythonFunctionShared) */ +static int __pyx_CommonTypesMetaclass_init(PyObject *module); +#define __Pyx_CommonTypesMetaclass_USED + +/* CallTypeTraverse.proto (used by CythonFunctionShared) */ +#if !CYTHON_USE_TYPE_SPECS || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x03090000) +#define __Pyx_call_type_traverse(o, always_call, visit, arg) 0 +#else +static int __Pyx_call_type_traverse(PyObject *o, int always_call, visitproc visit, void *arg); +#endif + +/* PyMethodNew.proto (used by CythonFunctionShared) */ +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ); + +/* PyVectorcallFastCallDict.proto (used by CythonFunctionShared) */ +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw); +#endif + +/* CythonFunctionShared.proto (used by CythonFunction) */ +#define __Pyx_CyFunction_USED +#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 +#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 +#define __Pyx_CYFUNCTION_CCLASS 0x04 +#define __Pyx_CYFUNCTION_COROUTINE 0x08 +#define __Pyx_CyFunction_GetClosure(f)\ + (((__pyx_CyFunctionObject *) (f))->func_closure) +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_CyFunction_GetClassObj(f)\ + (((__pyx_CyFunctionObject *) (f))->func_classobj) +#else + #define __Pyx_CyFunction_GetClassObj(f)\ + ((PyObject*) ((PyCMethodObject *) (f))->mm_class) +#endif +#define __Pyx_CyFunction_SetClassObj(f, classobj)\ + __Pyx__CyFunction_SetClassObj((__pyx_CyFunctionObject *) (f), (classobj)) +#define __Pyx_CyFunction_Defaults(type, f)\ + ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) +#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ + ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) +typedef struct { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject_HEAD + PyObject *func; +#elif PY_VERSION_HEX < 0x030900B1 + PyCFunctionObject func; +#else + PyCMethodObject func; +#endif +#if CYTHON_COMPILING_IN_LIMITED_API && CYTHON_METH_FASTCALL + __pyx_vectorcallfunc func_vectorcall; +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_weakreflist; +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_dict; +#endif + PyObject *func_name; + PyObject *func_qualname; + PyObject *func_doc; + PyObject *func_globals; + PyObject *func_code; + PyObject *func_closure; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_classobj; +#endif + PyObject *defaults; + int flags; + PyObject *defaults_tuple; + PyObject *defaults_kwdict; + PyObject *(*defaults_getter)(PyObject *); + PyObject *func_annotations; + PyObject *func_is_coroutine; +} __pyx_CyFunctionObject; +#undef __Pyx_CyOrPyCFunction_Check +#define __Pyx_CyFunction_Check(obj) __Pyx_TypeCheck(obj, __pyx_mstate_global->__pyx_CyFunctionType) +#define __Pyx_CyOrPyCFunction_Check(obj) __Pyx_TypeCheck2(obj, __pyx_mstate_global->__pyx_CyFunctionType, &PyCFunction_Type) +#define __Pyx_CyFunction_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_mstate_global->__pyx_CyFunctionType) +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void (*cfunc)(void)); +#undef __Pyx_IsSameCFunction +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCyOrCFunction(func, cfunc) +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj); +static CYTHON_INLINE PyObject *__Pyx_CyFunction_InitDefaults(PyObject *func, + PyTypeObject *defaults_type); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, + PyObject *tuple); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, + PyObject *dict); +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, + PyObject *dict); +static int __pyx_CyFunction_init(PyObject *module); +#if CYTHON_METH_FASTCALL +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +#if CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall) +#else +#define __Pyx_CyFunction_func_vectorcall(f) (((PyCFunctionObject*)f)->vectorcall) +#endif +#endif + +/* CythonFunction.proto */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); + +/* PyObjectLookupSpecial.proto (used by Py3ClassCreate) */ +#if CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS +#define __Pyx_PyObject_LookupSpecialNoError(obj, attr_name) __Pyx__PyObject_LookupSpecial(obj, attr_name, 0) +#define __Pyx_PyObject_LookupSpecial(obj, attr_name) __Pyx__PyObject_LookupSpecial(obj, attr_name, 1) +static CYTHON_INLINE PyObject* __Pyx__PyObject_LookupSpecial(PyObject* obj, PyObject* attr_name, int with_error); +#else +#define __Pyx_PyObject_LookupSpecialNoError(o,n) __Pyx_PyObject_GetAttrStrNoError(o,n) +#define __Pyx_PyObject_LookupSpecial(o,n) __Pyx_PyObject_GetAttrStr(o,n) +#endif + +/* Py3ClassCreate.proto */ +static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *qualname, + PyObject *mkw, PyObject *modname, PyObject *doc); +static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, + PyObject *mkw, int calculate_metaclass, int allow_py2_metaclass); + +/* CLineInTraceback.proto (used by AddTraceback) */ +#if CYTHON_CLINE_IN_TRACEBACK && CYTHON_CLINE_IN_TRACEBACK_RUNTIME +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#else +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#endif + +/* CodeObjectCache.proto (used by AddTraceback) */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject __Pyx_CachedCodeObjectType; +#else +typedef PyCodeObject __Pyx_CachedCodeObjectType; +#endif +typedef struct { + __Pyx_CachedCodeObjectType* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_atomic_int_type accessor_count; + #endif +}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static __Pyx_CachedCodeObjectType *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, __Pyx_CachedCodeObjectType* code_object); + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* GCCDiagnostics.proto */ +#if !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define __Pyx_HAS_GCC_DIAGNOSTIC +#endif + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyLong_From_long(long value); + +/* FormatTypeName.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%U" +#define __Pyx_DECREF_TypeName(obj) Py_XDECREF(obj) +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 +#define __Pyx_PyType_GetFullyQualifiedName PyType_GetFullyQualifiedName +#else +static __Pyx_TypeName __Pyx_PyType_GetFullyQualifiedName(PyTypeObject* tp); +#endif +#else // !LIMITED_API +typedef const char *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%.200s" +#define __Pyx_PyType_GetFullyQualifiedName(tp) ((tp)->tp_name) +#define __Pyx_DECREF_TypeName(obj) +#endif + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyLong_As_long(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyLong_As_int(PyObject *); + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) __Pyx_IsAnySubtype2(Py_TYPE(obj), (PyTypeObject *)type1, (PyTypeObject *)type2) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) (PyObject_TypeCheck(obj, (PyTypeObject *)type1) || PyObject_TypeCheck(obj, (PyTypeObject *)type2)) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2) { + return PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2); +} +#endif +#define __Pyx_PyErr_ExceptionMatches2(err1, err2) __Pyx_PyErr_GivenExceptionMatches2(__Pyx_PyErr_CurrentExceptionType(), err1, err2) +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) +#ifdef PyExceptionInstance_Check + #define __Pyx_PyBaseException_Check(obj) PyExceptionInstance_Check(obj) +#else + #define __Pyx_PyBaseException_Check(obj) __Pyx_TypeCheck(obj, PyExc_BaseException) +#endif + +/* GetRuntimeVersion.proto */ +#if __PYX_LIMITED_VERSION_HEX < 0x030b0000 +static unsigned long __Pyx_cached_runtime_version = 0; +static void __Pyx_init_runtime_version(void); +#else +#define __Pyx_init_runtime_version() +#endif +static unsigned long __Pyx_get_runtime_version(void); + +/* CheckBinaryVersion.proto */ +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer); + +/* DecompressString.proto */ +static PyObject *__Pyx_DecompressString(const char *s, Py_ssize_t length, int algo); + +/* MultiPhaseInitModuleState.proto */ +#if CYTHON_PEP489_MULTI_PHASE_INIT && CYTHON_USE_MODULE_STATE +static PyObject *__Pyx_State_FindModule(void*); +static int __Pyx_State_AddModule(PyObject* module, void*); +static int __Pyx_State_RemoveModule(void*); +#elif CYTHON_USE_MODULE_STATE +#define __Pyx_State_FindModule PyState_FindModule +#define __Pyx_State_AddModule PyState_AddModule +#define __Pyx_State_RemoveModule PyState_RemoveModule +#endif + +/* #### Code section: module_declarations ### */ +/* CythonABIVersion.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API + #if CYTHON_METH_FASTCALL + #define __PYX_FASTCALL_ABI_SUFFIX "_fastcall" + #else + #define __PYX_FASTCALL_ABI_SUFFIX + #endif + #define __PYX_LIMITED_ABI_SUFFIX "limited" __PYX_FASTCALL_ABI_SUFFIX __PYX_AM_SEND_ABI_SUFFIX +#else + #define __PYX_LIMITED_ABI_SUFFIX +#endif +#if __PYX_HAS_PY_AM_SEND == 1 + #define __PYX_AM_SEND_ABI_SUFFIX +#elif __PYX_HAS_PY_AM_SEND == 2 + #define __PYX_AM_SEND_ABI_SUFFIX "amsendbackport" +#else + #define __PYX_AM_SEND_ABI_SUFFIX "noamsend" +#endif +#ifndef __PYX_MONITORING_ABI_SUFFIX + #define __PYX_MONITORING_ABI_SUFFIX +#endif +#if CYTHON_USE_TP_FINALIZE + #define __PYX_TP_FINALIZE_ABI_SUFFIX +#else + #define __PYX_TP_FINALIZE_ABI_SUFFIX "nofinalize" +#endif +#if CYTHON_USE_FREELISTS || !defined(__Pyx_AsyncGen_USED) + #define __PYX_FREELISTS_ABI_SUFFIX +#else + #define __PYX_FREELISTS_ABI_SUFFIX "nofreelists" +#endif +#define CYTHON_ABI __PYX_ABI_VERSION __PYX_LIMITED_ABI_SUFFIX __PYX_MONITORING_ABI_SUFFIX __PYX_TP_FINALIZE_ABI_SUFFIX __PYX_FREELISTS_ABI_SUFFIX __PYX_AM_SEND_ABI_SUFFIX +#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI +#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "." + + +/* Module declarations from "cython" */ + +/* Module declarations from "fontTools.feaLib.lexer" */ +/* #### Code section: typeinfo ### */ +/* #### Code section: before_global_var ### */ +#define __Pyx_MODULE_NAME "fontTools.feaLib.lexer" +extern int __pyx_module_is_main_fontTools__feaLib__lexer; +int __pyx_module_is_main_fontTools__feaLib__lexer = 0; + +/* Implementation of "fontTools.feaLib.lexer" */ +/* #### Code section: global_var ### */ +static PyObject *__pyx_builtin_object; +static PyObject *__pyx_builtin_staticmethod; +static PyObject *__pyx_builtin_open; +/* #### Code section: string_decls ### */ +/* #### Code section: decls ### */ +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_text, PyObject *__pyx_v_filename); /* proto */ +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_2__iter__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_4next(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_6__next__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_8location_(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_10next_(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_12scan_over_(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_valid); /* proto */ +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_14scan_until_(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_stop_at); /* proto */ +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_16scan_anonymous_block(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_tag); /* proto */ +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_featurefile, PyObject *__pyx_v_includeDir); /* proto */ +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer_2__iter__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer_4next(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer_6__next__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer_8make_lexer_(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_file_or_path); /* proto */ +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer_10scan_anonymous_block(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_tag); /* proto */ +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_17NonIncludingLexer___next__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ +/* #### Code section: late_includes ### */ +/* #### Code section: module_state ### */ +/* SmallCodeConfig */ +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif + +typedef struct { + PyObject *__pyx_d; + PyObject *__pyx_b; + PyObject *__pyx_cython_runtime; + PyObject *__pyx_empty_tuple; + PyObject *__pyx_empty_bytes; + PyObject *__pyx_empty_unicode; + __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_items; + __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_pop; + __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_values; + __Pyx_CachedCFunction __pyx_umethod_PyList_Type_pop; + PyObject *__pyx_tuple[4]; + PyObject *__pyx_codeobj_tab[16]; + PyObject *__pyx_string_tab[197]; + PyObject *__pyx_number_tab[6]; +/* #### Code section: module_state_contents ### */ +/* IterNextPlain.module_state_decls */ +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 +PyObject *__Pyx_GetBuiltinNext_LimitedAPI_cache; +#endif + +/* CommonTypesMetaclass.module_state_decls */ +PyTypeObject *__pyx_CommonTypesMetaclassType; + +/* CachedMethodType.module_state_decls */ +#if CYTHON_COMPILING_IN_LIMITED_API +PyObject *__Pyx_CachedMethodType; +#endif + +/* CythonFunctionShared.module_state_decls */ +PyTypeObject *__pyx_CyFunctionType; + +/* CodeObjectCache.module_state_decls */ +struct __Pyx_CodeObjectCache __pyx_code_cache; + +/* #### Code section: module_state_end ### */ +} __pyx_mstatetype; + +#if CYTHON_USE_MODULE_STATE +#ifdef __cplusplus +namespace { +extern struct PyModuleDef __pyx_moduledef; +} /* anonymous namespace */ +#else +static struct PyModuleDef __pyx_moduledef; +#endif + +#define __pyx_mstate_global (__Pyx_PyModule_GetState(__Pyx_State_FindModule(&__pyx_moduledef))) + +#define __pyx_m (__Pyx_State_FindModule(&__pyx_moduledef)) +#else +static __pyx_mstatetype __pyx_mstate_global_static = +#ifdef __cplusplus + {}; +#else + {0}; +#endif +static __pyx_mstatetype * const __pyx_mstate_global = &__pyx_mstate_global_static; +#endif +/* #### Code section: constant_name_defines ### */ +#define __pyx_kp_u_ __pyx_string_tab[0] +#define __pyx_kp_u_0 __pyx_string_tab[1] +#define __pyx_kp_u_0123456789 __pyx_string_tab[2] +#define __pyx_kp_u_0123456789ABCDEFabcdef __pyx_string_tab[3] +#define __pyx_kp_u_A_Lexer_that_follows_include_sta __pyx_string_tab[4] +#define __pyx_kp_u_A_Za_z_0_9 __pyx_string_tab[5] +#define __pyx_kp_u_Expected_after_file_name __pyx_string_tab[6] +#define __pyx_kp_u_Expected_before_file_name __pyx_string_tab[7] +#define __pyx_kp_u_Expected_file_name __pyx_string_tab[8] +#define __pyx_kp_u_Expected_glyph_class_name __pyx_string_tab[9] +#define __pyx_kp_u_Expected_s_to_terminate_anonymou __pyx_string_tab[10] +#define __pyx_kp_u_Expected_to_terminate_string __pyx_string_tab[11] +#define __pyx_kp_u_Glyph_class_names_must_consist_o __pyx_string_tab[12] +#define __pyx_kp_u_Lexer_that_does_not_follow_inclu __pyx_string_tab[13] +#define __pyx_kp_u_Lib_fontTools_feaLib_lexer_py __pyx_string_tab[14] +#define __pyx_kp_u_Too_many_recursive_includes __pyx_string_tab[15] +#define __pyx_kp_u_Unexpected_character_r __pyx_string_tab[16] +#define __pyx_kp_u__10 __pyx_string_tab[17] +#define __pyx_kp_u__11 __pyx_string_tab[18] +#define __pyx_kp_u__12 __pyx_string_tab[19] +#define __pyx_kp_u__13 __pyx_string_tab[20] +#define __pyx_kp_u__14 __pyx_string_tab[21] +#define __pyx_kp_u__15 __pyx_string_tab[22] +#define __pyx_kp_u__16 __pyx_string_tab[23] +#define __pyx_kp_u__17 __pyx_string_tab[24] +#define __pyx_kp_u__18 __pyx_string_tab[25] +#define __pyx_kp_u__2 __pyx_string_tab[26] +#define __pyx_kp_u__3 __pyx_string_tab[27] +#define __pyx_kp_u__4 __pyx_string_tab[28] +#define __pyx_kp_u__5 __pyx_string_tab[29] +#define __pyx_kp_u__6 __pyx_string_tab[30] +#define __pyx_kp_u__7 __pyx_string_tab[31] +#define __pyx_kp_u__8 __pyx_string_tab[32] +#define __pyx_kp_u__9 __pyx_string_tab[33] +#define __pyx_kp_u_features __pyx_string_tab[34] +#define __pyx_kp_u_s __pyx_string_tab[35] +#define __pyx_kp_u_s_2 __pyx_string_tab[36] +#define __pyx_kp_u_utf_8_sig __pyx_string_tab[37] +#define __pyx_n_u_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef __pyx_string_tab[38] +#define __pyx_n_u_ANONYMOUS_BLOCK __pyx_string_tab[39] +#define __pyx_n_u_CHAR_DIGIT __pyx_string_tab[40] +#define __pyx_n_u_CHAR_HEXDIGIT __pyx_string_tab[41] +#define __pyx_n_u_CHAR_LETTER __pyx_string_tab[42] +#define __pyx_n_u_CHAR_NAME_CONTINUATION __pyx_string_tab[43] +#define __pyx_n_u_CHAR_NAME_START __pyx_string_tab[44] +#define __pyx_n_u_CHAR_NEWLINE __pyx_string_tab[45] +#define __pyx_n_u_CHAR_SYMBOL __pyx_string_tab[46] +#define __pyx_n_u_CHAR_WHITESPACE __pyx_string_tab[47] +#define __pyx_n_u_CID __pyx_string_tab[48] +#define __pyx_n_u_COMMENT __pyx_string_tab[49] +#define __pyx_n_u_FILENAME __pyx_string_tab[50] +#define __pyx_n_u_FLOAT __pyx_string_tab[51] +#define __pyx_n_u_FeatureLibError __pyx_string_tab[52] +#define __pyx_n_u_FeatureLibLocation __pyx_string_tab[53] +#define __pyx_n_u_GLYPHCLASS __pyx_string_tab[54] +#define __pyx_n_u_HEXADECIMAL __pyx_string_tab[55] +#define __pyx_n_u_IncludedFeaNotFound __pyx_string_tab[56] +#define __pyx_n_u_IncludingLexer __pyx_string_tab[57] +#define __pyx_n_u_IncludingLexer___init __pyx_string_tab[58] +#define __pyx_n_u_IncludingLexer___iter __pyx_string_tab[59] +#define __pyx_n_u_IncludingLexer___next __pyx_string_tab[60] +#define __pyx_n_u_IncludingLexer_make_lexer __pyx_string_tab[61] +#define __pyx_n_u_IncludingLexer_next __pyx_string_tab[62] +#define __pyx_n_u_IncludingLexer_scan_anonymous_bl __pyx_string_tab[63] +#define __pyx_n_u_Lexer __pyx_string_tab[64] +#define __pyx_n_u_Lexer___init __pyx_string_tab[65] +#define __pyx_n_u_Lexer___iter __pyx_string_tab[66] +#define __pyx_n_u_Lexer___next __pyx_string_tab[67] +#define __pyx_n_u_Lexer_location __pyx_string_tab[68] +#define __pyx_n_u_Lexer_next __pyx_string_tab[69] +#define __pyx_n_u_Lexer_next_2 __pyx_string_tab[70] +#define __pyx_n_u_Lexer_scan_anonymous_block __pyx_string_tab[71] +#define __pyx_n_u_Lexer_scan_over __pyx_string_tab[72] +#define __pyx_n_u_Lexer_scan_until __pyx_string_tab[73] +#define __pyx_n_u_MODE_FILENAME __pyx_string_tab[74] +#define __pyx_n_u_MODE_NORMAL __pyx_string_tab[75] +#define __pyx_n_u_NAME __pyx_string_tab[76] +#define __pyx_n_u_NEWLINE __pyx_string_tab[77] +#define __pyx_n_u_NORMAL __pyx_string_tab[78] +#define __pyx_n_u_NUMBER __pyx_string_tab[79] +#define __pyx_n_u_NUMBERS __pyx_string_tab[80] +#define __pyx_n_u_NonIncludingLexer __pyx_string_tab[81] +#define __pyx_n_u_NonIncludingLexer___next __pyx_string_tab[82] +#define __pyx_n_u_OCTAL __pyx_string_tab[83] +#define __pyx_n_u_Pyx_PyDict_NextRef __pyx_string_tab[84] +#define __pyx_n_u_RE_GLYPHCLASS __pyx_string_tab[85] +#define __pyx_n_u_STRING __pyx_string_tab[86] +#define __pyx_n_u_SYMBOL __pyx_string_tab[87] +#define __pyx_n_u_append __pyx_string_tab[88] +#define __pyx_n_u_asyncio_coroutines __pyx_string_tab[89] +#define __pyx_n_u_class_getitem __pyx_string_tab[90] +#define __pyx_n_u_cline_in_traceback __pyx_string_tab[91] +#define __pyx_n_u_close __pyx_string_tab[92] +#define __pyx_n_u_closing __pyx_string_tab[93] +#define __pyx_n_u_column __pyx_string_tab[94] +#define __pyx_n_u_compile __pyx_string_tab[95] +#define __pyx_n_u_cur_char __pyx_string_tab[96] +#define __pyx_n_u_curpath __pyx_string_tab[97] +#define __pyx_n_u_data __pyx_string_tab[98] +#define __pyx_n_u_dirname __pyx_string_tab[99] +#define __pyx_n_u_doc __pyx_string_tab[100] +#define __pyx_n_u_encoding __pyx_string_tab[101] +#define __pyx_n_u_err __pyx_string_tab[102] +#define __pyx_n_u_featurefile __pyx_string_tab[103] +#define __pyx_n_u_featurefilepath __pyx_string_tab[104] +#define __pyx_n_u_file_or_path __pyx_string_tab[105] +#define __pyx_n_u_filename __pyx_string_tab[106] +#define __pyx_n_u_filename_2 __pyx_string_tab[107] +#define __pyx_n_u_fileobj __pyx_string_tab[108] +#define __pyx_n_u_fname_location __pyx_string_tab[109] +#define __pyx_n_u_fname_token __pyx_string_tab[110] +#define __pyx_n_u_fname_type __pyx_string_tab[111] +#define __pyx_n_u_fontTools_feaLib_error __pyx_string_tab[112] +#define __pyx_n_u_fontTools_feaLib_lexer __pyx_string_tab[113] +#define __pyx_n_u_fontTools_feaLib_location __pyx_string_tab[114] +#define __pyx_n_u_func __pyx_string_tab[115] +#define __pyx_n_u_getcwd __pyx_string_tab[116] +#define __pyx_n_u_glyphclass __pyx_string_tab[117] +#define __pyx_n_u_include __pyx_string_tab[118] +#define __pyx_n_u_includeDir __pyx_string_tab[119] +#define __pyx_n_u_init __pyx_string_tab[120] +#define __pyx_n_u_is_coroutine __pyx_string_tab[121] +#define __pyx_n_u_isabs __pyx_string_tab[122] +#define __pyx_n_u_items __pyx_string_tab[123] +#define __pyx_n_u_iter __pyx_string_tab[124] +#define __pyx_n_u_join __pyx_string_tab[125] +#define __pyx_n_u_lexer __pyx_string_tab[126] +#define __pyx_n_u_lexers __pyx_string_tab[127] +#define __pyx_n_u_limit __pyx_string_tab[128] +#define __pyx_n_u_line __pyx_string_tab[129] +#define __pyx_n_u_line_start __pyx_string_tab[130] +#define __pyx_n_u_location __pyx_string_tab[131] +#define __pyx_n_u_location_2 __pyx_string_tab[132] +#define __pyx_n_u_main __pyx_string_tab[133] +#define __pyx_n_u_make_lexer __pyx_string_tab[134] +#define __pyx_n_u_match __pyx_string_tab[135] +#define __pyx_n_u_maxsplit __pyx_string_tab[136] +#define __pyx_n_u_metaclass __pyx_string_tab[137] +#define __pyx_n_u_mode __pyx_string_tab[138] +#define __pyx_n_u_module __pyx_string_tab[139] +#define __pyx_n_u_mro_entries __pyx_string_tab[140] +#define __pyx_n_u_name __pyx_string_tab[141] +#define __pyx_n_u_name_2 __pyx_string_tab[142] +#define __pyx_n_u_next __pyx_string_tab[143] +#define __pyx_n_u_next_2 __pyx_string_tab[144] +#define __pyx_n_u_next_3 __pyx_string_tab[145] +#define __pyx_n_u_next_char __pyx_string_tab[146] +#define __pyx_n_u_object __pyx_string_tab[147] +#define __pyx_n_u_open __pyx_string_tab[148] +#define __pyx_n_u_os __pyx_string_tab[149] +#define __pyx_n_u_p __pyx_string_tab[150] +#define __pyx_n_u_path __pyx_string_tab[151] +#define __pyx_n_u_pop __pyx_string_tab[152] +#define __pyx_n_u_pos __pyx_string_tab[153] +#define __pyx_n_u_prepare __pyx_string_tab[154] +#define __pyx_n_u_qualname __pyx_string_tab[155] +#define __pyx_n_u_r __pyx_string_tab[156] +#define __pyx_n_u_re __pyx_string_tab[157] +#define __pyx_n_u_read __pyx_string_tab[158] +#define __pyx_n_u_regexp __pyx_string_tab[159] +#define __pyx_n_u_scan_anonymous_block __pyx_string_tab[160] +#define __pyx_n_u_scan_over __pyx_string_tab[161] +#define __pyx_n_u_scan_until __pyx_string_tab[162] +#define __pyx_n_u_self __pyx_string_tab[163] +#define __pyx_n_u_set_name __pyx_string_tab[164] +#define __pyx_n_u_setdefault __pyx_string_tab[165] +#define __pyx_n_u_split __pyx_string_tab[166] +#define __pyx_n_u_start __pyx_string_tab[167] +#define __pyx_n_u_staticmethod __pyx_string_tab[168] +#define __pyx_n_u_stop_at __pyx_string_tab[169] +#define __pyx_n_u_string __pyx_string_tab[170] +#define __pyx_n_u_strip __pyx_string_tab[171] +#define __pyx_n_u_sub __pyx_string_tab[172] +#define __pyx_n_u_tag __pyx_string_tab[173] +#define __pyx_n_u_test __pyx_string_tab[174] +#define __pyx_n_u_text __pyx_string_tab[175] +#define __pyx_n_u_text_2 __pyx_string_tab[176] +#define __pyx_n_u_text_length __pyx_string_tab[177] +#define __pyx_n_u_token __pyx_string_tab[178] +#define __pyx_n_u_token_type __pyx_string_tab[179] +#define __pyx_n_u_valid __pyx_string_tab[180] +#define __pyx_n_u_values __pyx_string_tab[181] +#define __pyx_n_u_xX __pyx_string_tab[182] +#define __pyx_kp_b_iso88591_A_4z_c_q_L_a_Kq_Q_4r_V1D_1_3awc __pyx_string_tab[183] +#define __pyx_kp_b_iso88591_A_7_Z_Q_j_a_d_U_1_we1_7_9HA_1_6 __pyx_string_tab[184] +#define __pyx_kp_b_iso88591_A_D_b_nD_F_3c_HA __pyx_string_tab[185] +#define __pyx_kp_b_iso88591_A_D_b_nD_F_3gQ_HA __pyx_string_tab[186] +#define __pyx_kp_b_iso88591_A_Kq_Q_4z_A_t1_1A_6_A_q_4q_D_r_v __pyx_string_tab[187] +#define __pyx_kp_b_iso88591_A_M_IQ_HA_O1_IQ_Cq_IU __pyx_string_tab[188] +#define __pyx_kp_b_iso88591_A_V2T_b_k_N_ha __pyx_string_tab[189] +#define __pyx_kp_b_iso88591_A_d_D_G_d_1_HD_U_F_Q_M_uA_gU_2U __pyx_string_tab[190] +#define __pyx_kp_b_iso88591_A_fA_U_G1 __pyx_string_tab[191] +#define __pyx_kp_b_iso88591_A_q __pyx_string_tab[192] +#define __pyx_kp_b_iso88591_A_t1D __pyx_string_tab[193] +#define __pyx_kp_b_iso88591_A_t82R_4AQ __pyx_string_tab[194] +#define __pyx_kp_b_iso88591_A_t9A __pyx_string_tab[195] +#define __pyx_kp_b_iso88591_q_Kq_L_t81Ba_N __pyx_string_tab[196] +#define __pyx_int_0 __pyx_number_tab[0] +#define __pyx_int_1 __pyx_number_tab[1] +#define __pyx_int_2 __pyx_number_tab[2] +#define __pyx_int_8 __pyx_number_tab[3] +#define __pyx_int_10 __pyx_number_tab[4] +#define __pyx_int_16 __pyx_number_tab[5] +/* #### Code section: module_state_clear ### */ +#if CYTHON_USE_MODULE_STATE +static CYTHON_SMALL_CODE int __pyx_m_clear(PyObject *m) { + __pyx_mstatetype *clear_module_state = __Pyx_PyModule_GetState(m); + if (!clear_module_state) return 0; + Py_CLEAR(clear_module_state->__pyx_d); + Py_CLEAR(clear_module_state->__pyx_b); + Py_CLEAR(clear_module_state->__pyx_cython_runtime); + Py_CLEAR(clear_module_state->__pyx_empty_tuple); + Py_CLEAR(clear_module_state->__pyx_empty_bytes); + Py_CLEAR(clear_module_state->__pyx_empty_unicode); + #if CYTHON_PEP489_MULTI_PHASE_INIT + __Pyx_State_RemoveModule(NULL); + #endif + for (int i=0; i<4; ++i) { Py_CLEAR(clear_module_state->__pyx_tuple[i]); } + for (int i=0; i<16; ++i) { Py_CLEAR(clear_module_state->__pyx_codeobj_tab[i]); } + for (int i=0; i<197; ++i) { Py_CLEAR(clear_module_state->__pyx_string_tab[i]); } + for (int i=0; i<6; ++i) { Py_CLEAR(clear_module_state->__pyx_number_tab[i]); } +/* #### Code section: module_state_clear_contents ### */ +/* CommonTypesMetaclass.module_state_clear */ +Py_CLEAR(clear_module_state->__pyx_CommonTypesMetaclassType); + +/* CythonFunctionShared.module_state_clear */ +Py_CLEAR(clear_module_state->__pyx_CyFunctionType); + +/* #### Code section: module_state_clear_end ### */ +return 0; +} +#endif +/* #### Code section: module_state_traverse ### */ +#if CYTHON_USE_MODULE_STATE +static CYTHON_SMALL_CODE int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { + __pyx_mstatetype *traverse_module_state = __Pyx_PyModule_GetState(m); + if (!traverse_module_state) return 0; + Py_VISIT(traverse_module_state->__pyx_d); + Py_VISIT(traverse_module_state->__pyx_b); + Py_VISIT(traverse_module_state->__pyx_cython_runtime); + __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_tuple); + __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_bytes); + __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_unicode); + for (int i=0; i<4; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_tuple[i]); } + for (int i=0; i<16; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_codeobj_tab[i]); } + for (int i=0; i<197; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_string_tab[i]); } + for (int i=0; i<6; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_number_tab[i]); } +/* #### Code section: module_state_traverse_contents ### */ +/* CommonTypesMetaclass.module_state_traverse */ +Py_VISIT(traverse_module_state->__pyx_CommonTypesMetaclassType); + +/* CythonFunctionShared.module_state_traverse */ +Py_VISIT(traverse_module_state->__pyx_CyFunctionType); + +/* #### Code section: module_state_traverse_end ### */ +return 0; +} +#endif +/* #### Code section: module_code ### */ + +/* "fontTools/feaLib/lexer.py":43 + * MODE_FILENAME_ = "FILENAME" + * + * def __init__(self, text, filename): # <<<<<<<<<<<<<< + * self.filename_ = filename + * self.line_ = 1 +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_1__init__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_6feaLib_5lexer_5Lexer___init__, "Lexer.__init__(self, text, filename)"); +static PyMethodDef __pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_1__init__ = {"__init__", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_1__init__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_6feaLib_5lexer_5Lexer___init__}; +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_1__init__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_text = 0; + PyObject *__pyx_v_filename = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_text,&__pyx_mstate_global->__pyx_n_u_filename,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 43, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 43, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 43, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 43, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "__init__", 0) < (0)) __PYX_ERR(0, 43, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 3; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, i); __PYX_ERR(0, 43, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 43, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 43, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 43, __pyx_L3_error) + } + __pyx_v_self = values[0]; + __pyx_v_text = values[1]; + __pyx_v_filename = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 43, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_6feaLib_5lexer_5Lexer___init__(__pyx_self, __pyx_v_self, __pyx_v_text, __pyx_v_filename); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_text, PyObject *__pyx_v_filename) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + Py_ssize_t __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__init__", 0); + + /* "fontTools/feaLib/lexer.py":44 + * + * def __init__(self, text, filename): + * self.filename_ = filename # <<<<<<<<<<<<<< + * self.line_ = 1 + * self.pos_ = 0 +*/ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_filename_2, __pyx_v_filename) < (0)) __PYX_ERR(0, 44, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":45 + * def __init__(self, text, filename): + * self.filename_ = filename + * self.line_ = 1 # <<<<<<<<<<<<<< + * self.pos_ = 0 + * self.line_start_ = 0 +*/ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_line, __pyx_mstate_global->__pyx_int_1) < (0)) __PYX_ERR(0, 45, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":46 + * self.filename_ = filename + * self.line_ = 1 + * self.pos_ = 0 # <<<<<<<<<<<<<< + * self.line_start_ = 0 + * self.text_ = text +*/ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos, __pyx_mstate_global->__pyx_int_0) < (0)) __PYX_ERR(0, 46, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":47 + * self.line_ = 1 + * self.pos_ = 0 + * self.line_start_ = 0 # <<<<<<<<<<<<<< + * self.text_ = text + * self.text_length_ = len(text) +*/ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_line_start, __pyx_mstate_global->__pyx_int_0) < (0)) __PYX_ERR(0, 47, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":48 + * self.pos_ = 0 + * self.line_start_ = 0 + * self.text_ = text # <<<<<<<<<<<<<< + * self.text_length_ = len(text) + * self.mode_ = Lexer.MODE_NORMAL_ +*/ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_text_2, __pyx_v_text) < (0)) __PYX_ERR(0, 48, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":49 + * self.line_start_ = 0 + * self.text_ = text + * self.text_length_ = len(text) # <<<<<<<<<<<<<< + * self.mode_ = Lexer.MODE_NORMAL_ + * +*/ + __pyx_t_1 = PyObject_Length(__pyx_v_text); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 49, __pyx_L1_error) + __pyx_t_2 = PyLong_FromSsize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 49, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_text_length, __pyx_t_2) < (0)) __PYX_ERR(0, 49, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":50 + * self.text_ = text + * self.text_length_ = len(text) + * self.mode_ = Lexer.MODE_NORMAL_ # <<<<<<<<<<<<<< + * + * def __iter__(self): +*/ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 50, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_MODE_NORMAL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 50, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_mode, __pyx_t_3) < (0)) __PYX_ERR(0, 50, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/feaLib/lexer.py":43 + * MODE_FILENAME_ = "FILENAME" + * + * def __init__(self, text, filename): # <<<<<<<<<<<<<< + * self.filename_ = filename + * self.line_ = 1 +*/ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/feaLib/lexer.py":52 + * self.mode_ = Lexer.MODE_NORMAL_ + * + * def __iter__(self): # <<<<<<<<<<<<<< + * return self + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_3__iter__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_6feaLib_5lexer_5Lexer_2__iter__, "Lexer.__iter__(self)"); +static PyMethodDef __pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_3__iter__ = {"__iter__", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_3__iter__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_6feaLib_5lexer_5Lexer_2__iter__}; +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_3__iter__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 52, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 52, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "__iter__", 0) < (0)) __PYX_ERR(0, 52, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("__iter__", 1, 1, 1, i); __PYX_ERR(0, 52, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 52, __pyx_L3_error) + } + __pyx_v_self = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__iter__", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 52, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_2__iter__(__pyx_self, __pyx_v_self); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_2__iter__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__iter__", 0); + + /* "fontTools/feaLib/lexer.py":53 + * + * def __iter__(self): + * return self # <<<<<<<<<<<<<< + * + * def next(self): # Python 2 +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self); + __pyx_r = __pyx_v_self; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":52 + * self.mode_ = Lexer.MODE_NORMAL_ + * + * def __iter__(self): # <<<<<<<<<<<<<< + * return self + * +*/ + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/feaLib/lexer.py":55 + * return self + * + * def next(self): # Python 2 # <<<<<<<<<<<<<< + * return self.__next__() + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_5next(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_6feaLib_5lexer_5Lexer_4next, "Lexer.next(self)"); +static PyMethodDef __pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_5next = {"next", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_5next, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_6feaLib_5lexer_5Lexer_4next}; +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_5next(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("next (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 55, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 55, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "next", 0) < (0)) __PYX_ERR(0, 55, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("next", 1, 1, 1, i); __PYX_ERR(0, 55, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 55, __pyx_L3_error) + } + __pyx_v_self = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("next", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 55, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.next", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_4next(__pyx_self, __pyx_v_self); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_4next(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + size_t __pyx_t_3; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("next", 0); + + /* "fontTools/feaLib/lexer.py":56 + * + * def next(self): # Python 2 + * return self.__next__() # <<<<<<<<<<<<<< + * + * def __next__(self): # Python 3 +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_next, __pyx_callargs+__pyx_t_3, (1-__pyx_t_3) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":55 + * return self + * + * def next(self): # Python 2 # <<<<<<<<<<<<<< + * return self.__next__() + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.next", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/feaLib/lexer.py":58 + * return self.__next__() + * + * def __next__(self): # Python 3 # <<<<<<<<<<<<<< + * while True: + * token_type, token, location = self.next_() +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_7__next__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_6feaLib_5lexer_5Lexer_6__next__, "Lexer.__next__(self)"); +static PyMethodDef __pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_7__next__ = {"__next__", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_7__next__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_6feaLib_5lexer_5Lexer_6__next__}; +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_7__next__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__next__ (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 58, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 58, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "__next__", 0) < (0)) __PYX_ERR(0, 58, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("__next__", 1, 1, 1, i); __PYX_ERR(0, 58, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 58, __pyx_L3_error) + } + __pyx_v_self = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__next__", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 58, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_6__next__(__pyx_self, __pyx_v_self); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_6__next__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_v_token_type = NULL; + PyObject *__pyx_v_token = NULL; + PyObject *__pyx_v_location = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + size_t __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *(*__pyx_t_7)(PyObject *); + int __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__next__", 0); + + /* "fontTools/feaLib/lexer.py":59 + * + * def __next__(self): # Python 3 + * while True: # <<<<<<<<<<<<<< + * token_type, token, location = self.next_() + * if token_type != Lexer.NEWLINE: +*/ + while (1) { + + /* "fontTools/feaLib/lexer.py":60 + * def __next__(self): # Python 3 + * while True: + * token_type, token, location = self.next_() # <<<<<<<<<<<<<< + * if token_type != Lexer.NEWLINE: + * return (token_type, token, location) +*/ + __pyx_t_2 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_next_2, __pyx_callargs+__pyx_t_3, (1-__pyx_t_3) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 60, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 3)) { + if (size > 3) __Pyx_RaiseTooManyValuesError(3); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 60, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_4); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 2); + __Pyx_INCREF(__pyx_t_5); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 60, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 60, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyList_GetItemRefFast(sequence, 2, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 60, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_5); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 60, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 60, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 60, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_6 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 60, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); + index = 0; __pyx_t_2 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_4 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_4)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + index = 2; __pyx_t_5 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_5)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_5); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 3) < (0)) __PYX_ERR(0, 60, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 60, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __Pyx_XDECREF_SET(__pyx_v_token_type, __pyx_t_2); + __pyx_t_2 = 0; + __Pyx_XDECREF_SET(__pyx_v_token, __pyx_t_4); + __pyx_t_4 = 0; + __Pyx_XDECREF_SET(__pyx_v_location, __pyx_t_5); + __pyx_t_5 = 0; + + /* "fontTools/feaLib/lexer.py":61 + * while True: + * token_type, token, location = self.next_() + * if token_type != Lexer.NEWLINE: # <<<<<<<<<<<<<< + * return (token_type, token, location) + * +*/ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 61, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_NEWLINE); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 61, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyObject_RichCompare(__pyx_v_token_type, __pyx_t_5, Py_NE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 61, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 61, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_8) { + + /* "fontTools/feaLib/lexer.py":62 + * token_type, token, location = self.next_() + * if token_type != Lexer.NEWLINE: + * return (token_type, token, location) # <<<<<<<<<<<<<< + * + * def location_(self): +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_token_type); + __Pyx_GIVEREF(__pyx_v_token_type); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_token_type) != (0)) __PYX_ERR(0, 62, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_token); + __Pyx_GIVEREF(__pyx_v_token); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_token) != (0)) __PYX_ERR(0, 62, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 62, __pyx_L1_error); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":61 + * while True: + * token_type, token, location = self.next_() + * if token_type != Lexer.NEWLINE: # <<<<<<<<<<<<<< + * return (token_type, token, location) + * +*/ + } + } + + /* "fontTools/feaLib/lexer.py":58 + * return self.__next__() + * + * def __next__(self): # Python 3 # <<<<<<<<<<<<<< + * while True: + * token_type, token, location = self.next_() +*/ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_token_type); + __Pyx_XDECREF(__pyx_v_token); + __Pyx_XDECREF(__pyx_v_location); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/feaLib/lexer.py":64 + * return (token_type, token, location) + * + * def location_(self): # <<<<<<<<<<<<<< + * column = self.pos_ - self.line_start_ + 1 + * return FeatureLibLocation(self.filename_ or "", self.line_, column) +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_9location_(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_6feaLib_5lexer_5Lexer_8location_, "Lexer.location_(self)"); +static PyMethodDef __pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_9location_ = {"location_", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_9location_, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_6feaLib_5lexer_5Lexer_8location_}; +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_9location_(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("location_ (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 64, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 64, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "location_", 0) < (0)) __PYX_ERR(0, 64, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("location_", 1, 1, 1, i); __PYX_ERR(0, 64, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 64, __pyx_L3_error) + } + __pyx_v_self = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("location_", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 64, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.location_", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_8location_(__pyx_self, __pyx_v_self); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_8location_(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_v_column = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + size_t __pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("location_", 0); + + /* "fontTools/feaLib/lexer.py":65 + * + * def location_(self): + * column = self.pos_ - self.line_start_ + 1 # <<<<<<<<<<<<<< + * return FeatureLibLocation(self.filename_ or "", self.line_, column) + * +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 65, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_line_start); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 65, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Subtract(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 65, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyLong_AddObjC(__pyx_t_3, __pyx_mstate_global->__pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 65, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_column = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":66 + * def location_(self): + * column = self.pos_ - self.line_start_ + 1 + * return FeatureLibLocation(self.filename_ or "", self.line_, column) # <<<<<<<<<<<<<< + * + * def next_(self): +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_FeatureLibLocation); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 66, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_filename_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 66, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(0, 66, __pyx_L1_error) + if (!__pyx_t_6) { + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } else { + __Pyx_INCREF(__pyx_t_5); + __pyx_t_4 = __pyx_t_5; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L3_bool_binop_done; + } + __Pyx_INCREF(__pyx_mstate_global->__pyx_kp_u_features); + __pyx_t_4 = __pyx_mstate_global->__pyx_kp_u_features; + __pyx_L3_bool_binop_done:; + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_line); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 66, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_3); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_3, __pyx_t_4, __pyx_t_5, __pyx_v_column}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_7, (4-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 66, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":64 + * return (token_type, token, location) + * + * def location_(self): # <<<<<<<<<<<<<< + * column = self.pos_ - self.line_start_ + 1 + * return FeatureLibLocation(self.filename_ or "", self.line_, column) +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.location_", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_column); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/feaLib/lexer.py":68 + * return FeatureLibLocation(self.filename_ or "", self.line_, column) + * + * def next_(self): # <<<<<<<<<<<<<< + * self.scan_over_(Lexer.CHAR_WHITESPACE_) + * location = self.location_() +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_11next_(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_6feaLib_5lexer_5Lexer_10next_, "Lexer.next_(self)"); +static PyMethodDef __pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_11next_ = {"next_", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_11next_, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_6feaLib_5lexer_5Lexer_10next_}; +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_11next_(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("next_ (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 68, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 68, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "next_", 0) < (0)) __PYX_ERR(0, 68, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("next_", 1, 1, 1, i); __PYX_ERR(0, 68, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 68, __pyx_L3_error) + } + __pyx_v_self = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("next_", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 68, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.next_", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_10next_(__pyx_self, __pyx_v_self); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_10next_(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_v_location = NULL; + PyObject *__pyx_v_start = NULL; + PyObject *__pyx_v_text = NULL; + Py_ssize_t __pyx_v_limit; + PyObject *__pyx_v_cur_char = NULL; + PyObject *__pyx_v_next_char = NULL; + PyObject *__pyx_v_glyphclass = NULL; + PyObject *__pyx_v_token = NULL; + PyObject *__pyx_v_string = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + size_t __pyx_t_5; + Py_ssize_t __pyx_t_6; + int __pyx_t_7; + int __pyx_t_8; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("next_", 0); + + /* "fontTools/feaLib/lexer.py":69 + * + * def next_(self): + * self.scan_over_(Lexer.CHAR_WHITESPACE_) # <<<<<<<<<<<<<< + * location = self.location_() + * start = self.pos_ +*/ + __pyx_t_2 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 69, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_CHAR_WHITESPACE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 69, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_t_4}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_over, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 69, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/feaLib/lexer.py":70 + * def next_(self): + * self.scan_over_(Lexer.CHAR_WHITESPACE_) + * location = self.location_() # <<<<<<<<<<<<<< + * start = self.pos_ + * text = self.text_ +*/ + __pyx_t_4 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_4); + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_4, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_location, __pyx_callargs+__pyx_t_5, (1-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_v_location = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/feaLib/lexer.py":71 + * self.scan_over_(Lexer.CHAR_WHITESPACE_) + * location = self.location_() + * start = self.pos_ # <<<<<<<<<<<<<< + * text = self.text_ + * limit = len(text) +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_start = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/feaLib/lexer.py":72 + * location = self.location_() + * start = self.pos_ + * text = self.text_ # <<<<<<<<<<<<<< + * limit = len(text) + * if start >= limit: +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_text_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 72, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_text = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/feaLib/lexer.py":73 + * start = self.pos_ + * text = self.text_ + * limit = len(text) # <<<<<<<<<<<<<< + * if start >= limit: + * raise StopIteration() +*/ + __pyx_t_6 = PyObject_Length(__pyx_v_text); if (unlikely(__pyx_t_6 == ((Py_ssize_t)-1))) __PYX_ERR(0, 73, __pyx_L1_error) + __pyx_v_limit = __pyx_t_6; + + /* "fontTools/feaLib/lexer.py":74 + * text = self.text_ + * limit = len(text) + * if start >= limit: # <<<<<<<<<<<<<< + * raise StopIteration() + * cur_char = text[start] +*/ + __pyx_t_1 = PyLong_FromSsize_t(__pyx_v_limit); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 74, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_start, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 74, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 74, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(__pyx_t_7)) { + + /* "fontTools/feaLib/lexer.py":75 + * limit = len(text) + * if start >= limit: + * raise StopIteration() # <<<<<<<<<<<<<< + * cur_char = text[start] + * next_char = text[start + 1] if start + 1 < limit else None +*/ + __pyx_t_1 = NULL; + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, NULL}; + __pyx_t_4 = __Pyx_PyObject_FastCall((PyObject*)(((PyTypeObject*)PyExc_StopIteration)), __pyx_callargs+__pyx_t_5, (1-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 75, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + } + __Pyx_Raise(__pyx_t_4, 0, 0, 0); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __PYX_ERR(0, 75, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":74 + * text = self.text_ + * limit = len(text) + * if start >= limit: # <<<<<<<<<<<<<< + * raise StopIteration() + * cur_char = text[start] +*/ + } + + /* "fontTools/feaLib/lexer.py":76 + * if start >= limit: + * raise StopIteration() + * cur_char = text[start] # <<<<<<<<<<<<<< + * next_char = text[start + 1] if start + 1 < limit else None + * +*/ + __pyx_t_4 = __Pyx_PyObject_GetItem(__pyx_v_text, __pyx_v_start); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_v_cur_char = __pyx_t_4; + __pyx_t_4 = 0; + + /* "fontTools/feaLib/lexer.py":77 + * raise StopIteration() + * cur_char = text[start] + * next_char = text[start + 1] if start + 1 < limit else None # <<<<<<<<<<<<<< + * + * if cur_char == "\n": +*/ + __pyx_t_1 = __Pyx_PyLong_AddObjC(__pyx_v_start, __pyx_mstate_global->__pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyLong_FromSsize_t(__pyx_v_limit); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_7) { + __pyx_t_3 = __Pyx_PyLong_AddObjC(__pyx_v_start, __pyx_mstate_global->__pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_v_text, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = __pyx_t_2; + __pyx_t_2 = 0; + } else { + __Pyx_INCREF(Py_None); + __pyx_t_4 = Py_None; + } + __pyx_v_next_char = __pyx_t_4; + __pyx_t_4 = 0; + + /* "fontTools/feaLib/lexer.py":79 + * next_char = text[start + 1] if start + 1 < limit else None + * + * if cur_char == "\n": # <<<<<<<<<<<<<< + * self.pos_ += 1 + * self.line_ += 1 +*/ + __pyx_t_7 = (__Pyx_PyUnicode_Equals(__pyx_v_cur_char, __pyx_mstate_global->__pyx_kp_u_, Py_EQ)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 79, __pyx_L1_error) + if (__pyx_t_7) { + + /* "fontTools/feaLib/lexer.py":80 + * + * if cur_char == "\n": + * self.pos_ += 1 # <<<<<<<<<<<<<< + * self.line_ += 1 + * self.line_start_ = self.pos_ +*/ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_2 = __Pyx_PyLong_AddObjC(__pyx_t_4, __pyx_mstate_global->__pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos, __pyx_t_2) < (0)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":81 + * if cur_char == "\n": + * self.pos_ += 1 + * self.line_ += 1 # <<<<<<<<<<<<<< + * self.line_start_ = self.pos_ + * return (Lexer.NEWLINE, None, location) +*/ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_line); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 81, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyLong_AddObjC(__pyx_t_2, __pyx_mstate_global->__pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 81, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_line, __pyx_t_4) < (0)) __PYX_ERR(0, 81, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/feaLib/lexer.py":82 + * self.pos_ += 1 + * self.line_ += 1 + * self.line_start_ = self.pos_ # <<<<<<<<<<<<<< + * return (Lexer.NEWLINE, None, location) + * if cur_char == "\r": +*/ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 82, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_line_start, __pyx_t_4) < (0)) __PYX_ERR(0, 82, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/feaLib/lexer.py":83 + * self.line_ += 1 + * self.line_start_ = self.pos_ + * return (Lexer.NEWLINE, None, location) # <<<<<<<<<<<<<< + * if cur_char == "\r": + * self.pos_ += 2 if next_char == "\n" else 1 +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 83, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_NEWLINE); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 83, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 83, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2) != (0)) __PYX_ERR(0, 83, __pyx_L1_error); + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, Py_None) != (0)) __PYX_ERR(0, 83, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 83, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":79 + * next_char = text[start + 1] if start + 1 < limit else None + * + * if cur_char == "\n": # <<<<<<<<<<<<<< + * self.pos_ += 1 + * self.line_ += 1 +*/ + } + + /* "fontTools/feaLib/lexer.py":84 + * self.line_start_ = self.pos_ + * return (Lexer.NEWLINE, None, location) + * if cur_char == "\r": # <<<<<<<<<<<<<< + * self.pos_ += 2 if next_char == "\n" else 1 + * self.line_ += 1 +*/ + __pyx_t_7 = (__Pyx_PyUnicode_Equals(__pyx_v_cur_char, __pyx_mstate_global->__pyx_kp_u__2, Py_EQ)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 84, __pyx_L1_error) + if (__pyx_t_7) { + + /* "fontTools/feaLib/lexer.py":85 + * return (Lexer.NEWLINE, None, location) + * if cur_char == "\r": + * self.pos_ += 2 if next_char == "\n" else 1 # <<<<<<<<<<<<<< + * self.line_ += 1 + * self.line_start_ = self.pos_ +*/ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 85, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = (__Pyx_PyUnicode_Equals(__pyx_v_next_char, __pyx_mstate_global->__pyx_kp_u_, Py_EQ)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 85, __pyx_L1_error) + if (__pyx_t_7) { + __Pyx_INCREF(__pyx_mstate_global->__pyx_int_2); + __pyx_t_2 = __pyx_mstate_global->__pyx_int_2; + } else { + __Pyx_INCREF(__pyx_mstate_global->__pyx_int_1); + __pyx_t_2 = __pyx_mstate_global->__pyx_int_1; + } + __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 85, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos, __pyx_t_3) < (0)) __PYX_ERR(0, 85, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/feaLib/lexer.py":86 + * if cur_char == "\r": + * self.pos_ += 2 if next_char == "\n" else 1 + * self.line_ += 1 # <<<<<<<<<<<<<< + * self.line_start_ = self.pos_ + * return (Lexer.NEWLINE, None, location) +*/ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_line); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 86, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyLong_AddObjC(__pyx_t_3, __pyx_mstate_global->__pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 86, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_line, __pyx_t_2) < (0)) __PYX_ERR(0, 86, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":87 + * self.pos_ += 2 if next_char == "\n" else 1 + * self.line_ += 1 + * self.line_start_ = self.pos_ # <<<<<<<<<<<<<< + * return (Lexer.NEWLINE, None, location) + * if cur_char == "#": +*/ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 87, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_line_start, __pyx_t_2) < (0)) __PYX_ERR(0, 87, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":88 + * self.line_ += 1 + * self.line_start_ = self.pos_ + * return (Lexer.NEWLINE, None, location) # <<<<<<<<<<<<<< + * if cur_char == "#": + * self.scan_until_(Lexer.CHAR_NEWLINE_) +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 88, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_NEWLINE); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 88, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 88, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3) != (0)) __PYX_ERR(0, 88, __pyx_L1_error); + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, Py_None) != (0)) __PYX_ERR(0, 88, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 88, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":84 + * self.line_start_ = self.pos_ + * return (Lexer.NEWLINE, None, location) + * if cur_char == "\r": # <<<<<<<<<<<<<< + * self.pos_ += 2 if next_char == "\n" else 1 + * self.line_ += 1 +*/ + } + + /* "fontTools/feaLib/lexer.py":89 + * self.line_start_ = self.pos_ + * return (Lexer.NEWLINE, None, location) + * if cur_char == "#": # <<<<<<<<<<<<<< + * self.scan_until_(Lexer.CHAR_NEWLINE_) + * return (Lexer.COMMENT, text[start : self.pos_], location) +*/ + __pyx_t_7 = (__Pyx_PyUnicode_Equals(__pyx_v_cur_char, __pyx_mstate_global->__pyx_kp_u__3, Py_EQ)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 89, __pyx_L1_error) + if (__pyx_t_7) { + + /* "fontTools/feaLib/lexer.py":90 + * return (Lexer.NEWLINE, None, location) + * if cur_char == "#": + * self.scan_until_(Lexer.CHAR_NEWLINE_) # <<<<<<<<<<<<<< + * return (Lexer.COMMENT, text[start : self.pos_], location) + * +*/ + __pyx_t_3 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_3); + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 90, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_CHAR_NEWLINE); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 90, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_t_1}; + __pyx_t_2 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_until, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 90, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":91 + * if cur_char == "#": + * self.scan_until_(Lexer.CHAR_NEWLINE_) + * return (Lexer.COMMENT, text[start : self.pos_], location) # <<<<<<<<<<<<<< + * + * if self.mode_ is Lexer.MODE_FILENAME_: +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 91, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_COMMENT); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 91, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 91, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetSlice(__pyx_v_text, 0, 0, &__pyx_v_start, &__pyx_t_2, NULL, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 91, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 91, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 91, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3) != (0)) __PYX_ERR(0, 91, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 91, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":89 + * self.line_start_ = self.pos_ + * return (Lexer.NEWLINE, None, location) + * if cur_char == "#": # <<<<<<<<<<<<<< + * self.scan_until_(Lexer.CHAR_NEWLINE_) + * return (Lexer.COMMENT, text[start : self.pos_], location) +*/ + } + + /* "fontTools/feaLib/lexer.py":93 + * return (Lexer.COMMENT, text[start : self.pos_], location) + * + * if self.mode_ is Lexer.MODE_FILENAME_: # <<<<<<<<<<<<<< + * if cur_char != "(": + * raise FeatureLibError("Expected '(' before file name", location) +*/ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_mode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 93, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 93, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_MODE_FILENAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 93, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = (__pyx_t_2 == __pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_7) { + + /* "fontTools/feaLib/lexer.py":94 + * + * if self.mode_ is Lexer.MODE_FILENAME_: + * if cur_char != "(": # <<<<<<<<<<<<<< + * raise FeatureLibError("Expected '(' before file name", location) + * self.scan_until_(")") +*/ + __pyx_t_7 = (__Pyx_PyUnicode_Equals(__pyx_v_cur_char, __pyx_mstate_global->__pyx_kp_u__4, Py_NE)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 94, __pyx_L1_error) + if (unlikely(__pyx_t_7)) { + + /* "fontTools/feaLib/lexer.py":95 + * if self.mode_ is Lexer.MODE_FILENAME_: + * if cur_char != "(": + * raise FeatureLibError("Expected '(' before file name", location) # <<<<<<<<<<<<<< + * self.scan_until_(")") + * cur_char = text[self.pos_] if self.pos_ < limit else None +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_FeatureLibError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 95, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_Expected_before_file_name, __pyx_v_location}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 95, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(0, 95, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":94 + * + * if self.mode_ is Lexer.MODE_FILENAME_: + * if cur_char != "(": # <<<<<<<<<<<<<< + * raise FeatureLibError("Expected '(' before file name", location) + * self.scan_until_(")") +*/ + } + + /* "fontTools/feaLib/lexer.py":96 + * if cur_char != "(": + * raise FeatureLibError("Expected '(' before file name", location) + * self.scan_until_(")") # <<<<<<<<<<<<<< + * cur_char = text[self.pos_] if self.pos_ < limit else None + * if cur_char != ")": +*/ + __pyx_t_3 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_3); + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_mstate_global->__pyx_kp_u__5}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_until, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 96, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/feaLib/lexer.py":97 + * raise FeatureLibError("Expected '(' before file name", location) + * self.scan_until_(")") + * cur_char = text[self.pos_] if self.pos_ < limit else None # <<<<<<<<<<<<<< + * if cur_char != ")": + * raise FeatureLibError("Expected ')' after file name", location) +*/ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 97, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyLong_FromSsize_t(__pyx_v_limit); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 97, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 97, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 97, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_7) { + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 97, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_v_text, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 97, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_1 = __pyx_t_2; + __pyx_t_2 = 0; + } else { + __Pyx_INCREF(Py_None); + __pyx_t_1 = Py_None; + } + __Pyx_DECREF_SET(__pyx_v_cur_char, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/feaLib/lexer.py":98 + * self.scan_until_(")") + * cur_char = text[self.pos_] if self.pos_ < limit else None + * if cur_char != ")": # <<<<<<<<<<<<<< + * raise FeatureLibError("Expected ')' after file name", location) + * self.pos_ += 1 +*/ + __pyx_t_7 = (__Pyx_PyUnicode_Equals(__pyx_v_cur_char, __pyx_mstate_global->__pyx_kp_u__5, Py_NE)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 98, __pyx_L1_error) + if (unlikely(__pyx_t_7)) { + + /* "fontTools/feaLib/lexer.py":99 + * cur_char = text[self.pos_] if self.pos_ < limit else None + * if cur_char != ")": + * raise FeatureLibError("Expected ')' after file name", location) # <<<<<<<<<<<<<< + * self.pos_ += 1 + * self.mode_ = Lexer.MODE_NORMAL_ +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_FeatureLibError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_4); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_4, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_Expected_after_file_name, __pyx_v_location}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_4, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(0, 99, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":98 + * self.scan_until_(")") + * cur_char = text[self.pos_] if self.pos_ < limit else None + * if cur_char != ")": # <<<<<<<<<<<<<< + * raise FeatureLibError("Expected ')' after file name", location) + * self.pos_ += 1 +*/ + } + + /* "fontTools/feaLib/lexer.py":100 + * if cur_char != ")": + * raise FeatureLibError("Expected ')' after file name", location) + * self.pos_ += 1 # <<<<<<<<<<<<<< + * self.mode_ = Lexer.MODE_NORMAL_ + * return (Lexer.FILENAME, text[start + 1 : self.pos_ - 1], location) +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 100, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PyLong_AddObjC(__pyx_t_1, __pyx_mstate_global->__pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 100, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos, __pyx_t_4) < (0)) __PYX_ERR(0, 100, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/feaLib/lexer.py":101 + * raise FeatureLibError("Expected ')' after file name", location) + * self.pos_ += 1 + * self.mode_ = Lexer.MODE_NORMAL_ # <<<<<<<<<<<<<< + * return (Lexer.FILENAME, text[start + 1 : self.pos_ - 1], location) + * +*/ + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 101, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_MODE_NORMAL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 101, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_mode, __pyx_t_1) < (0)) __PYX_ERR(0, 101, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/feaLib/lexer.py":102 + * self.pos_ += 1 + * self.mode_ = Lexer.MODE_NORMAL_ + * return (Lexer.FILENAME, text[start + 1 : self.pos_ - 1], location) # <<<<<<<<<<<<<< + * + * if cur_char == "\\" and next_char in Lexer.CHAR_DIGIT_: +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 102, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_FILENAME); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 102, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyLong_AddObjC(__pyx_v_start, __pyx_mstate_global->__pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 102, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 102, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyLong_SubtractObjC(__pyx_t_2, __pyx_mstate_global->__pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 102, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_GetSlice(__pyx_v_text, 0, 0, &__pyx_t_1, &__pyx_t_3, NULL, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 102, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 102, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4) != (0)) __PYX_ERR(0, 102, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2) != (0)) __PYX_ERR(0, 102, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 102, __pyx_L1_error); + __pyx_t_4 = 0; + __pyx_t_2 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":93 + * return (Lexer.COMMENT, text[start : self.pos_], location) + * + * if self.mode_ is Lexer.MODE_FILENAME_: # <<<<<<<<<<<<<< + * if cur_char != "(": + * raise FeatureLibError("Expected '(' before file name", location) +*/ + } + + /* "fontTools/feaLib/lexer.py":104 + * return (Lexer.FILENAME, text[start + 1 : self.pos_ - 1], location) + * + * if cur_char == "\\" and next_char in Lexer.CHAR_DIGIT_: # <<<<<<<<<<<<<< + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_DIGIT_) +*/ + __pyx_t_8 = (__Pyx_PyUnicode_Equals(__pyx_v_cur_char, __pyx_mstate_global->__pyx_kp_u__6, Py_EQ)); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 104, __pyx_L1_error) + if (__pyx_t_8) { + } else { + __pyx_t_7 = __pyx_t_8; + goto __pyx_L11_bool_binop_done; + } + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_CHAR_DIGIT); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_8 = (__Pyx_PySequence_ContainsTF(__pyx_v_next_char, __pyx_t_2, Py_EQ)); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_7 = __pyx_t_8; + __pyx_L11_bool_binop_done:; + if (__pyx_t_7) { + + /* "fontTools/feaLib/lexer.py":105 + * + * if cur_char == "\\" and next_char in Lexer.CHAR_DIGIT_: + * self.pos_ += 1 # <<<<<<<<<<<<<< + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.CID, int(text[start + 1 : self.pos_], 10), location) +*/ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 105, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyLong_AddObjC(__pyx_t_2, __pyx_mstate_global->__pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 105, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos, __pyx_t_3) < (0)) __PYX_ERR(0, 105, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/feaLib/lexer.py":106 + * if cur_char == "\\" and next_char in Lexer.CHAR_DIGIT_: + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_DIGIT_) # <<<<<<<<<<<<<< + * return (Lexer.CID, int(text[start + 1 : self.pos_], 10), location) + * if cur_char == "@": +*/ + __pyx_t_2 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 106, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_CHAR_DIGIT); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 106, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_t_1}; + __pyx_t_3 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_over, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 106, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/feaLib/lexer.py":107 + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.CID, int(text[start + 1 : self.pos_], 10), location) # <<<<<<<<<<<<<< + * if cur_char == "@": + * self.pos_ += 1 +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 107, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_CID); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 107, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_2 = NULL; + __pyx_t_4 = __Pyx_PyLong_AddObjC(__pyx_v_start, __pyx_mstate_global->__pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 107, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 107, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = __Pyx_PyObject_GetSlice(__pyx_v_text, 0, 0, &__pyx_t_4, &__pyx_t_9, NULL, 0, 0, 1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 107, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_t_10, __pyx_mstate_global->__pyx_int_10}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)(&PyLong_Type), __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 107, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 107, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 107, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_3) != (0)) __PYX_ERR(0, 107, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 107, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_r = __pyx_t_10; + __pyx_t_10 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":104 + * return (Lexer.FILENAME, text[start + 1 : self.pos_ - 1], location) + * + * if cur_char == "\\" and next_char in Lexer.CHAR_DIGIT_: # <<<<<<<<<<<<<< + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_DIGIT_) +*/ + } + + /* "fontTools/feaLib/lexer.py":108 + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.CID, int(text[start + 1 : self.pos_], 10), location) + * if cur_char == "@": # <<<<<<<<<<<<<< + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) +*/ + __pyx_t_7 = (__Pyx_PyUnicode_Equals(__pyx_v_cur_char, __pyx_mstate_global->__pyx_kp_u__7, Py_EQ)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 108, __pyx_L1_error) + if (__pyx_t_7) { + + /* "fontTools/feaLib/lexer.py":109 + * return (Lexer.CID, int(text[start + 1 : self.pos_], 10), location) + * if cur_char == "@": + * self.pos_ += 1 # <<<<<<<<<<<<<< + * self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) + * glyphclass = text[start + 1 : self.pos_] +*/ + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 109, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_3 = __Pyx_PyLong_AddObjC(__pyx_t_10, __pyx_mstate_global->__pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 109, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos, __pyx_t_3) < (0)) __PYX_ERR(0, 109, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/feaLib/lexer.py":110 + * if cur_char == "@": + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) # <<<<<<<<<<<<<< + * glyphclass = text[start + 1 : self.pos_] + * if len(glyphclass) < 1: +*/ + __pyx_t_10 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_10); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 110, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_CHAR_NAME_CONTINUATION); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 110, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_10, __pyx_t_2}; + __pyx_t_3 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_over, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 110, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/feaLib/lexer.py":111 + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) + * glyphclass = text[start + 1 : self.pos_] # <<<<<<<<<<<<<< + * if len(glyphclass) < 1: + * raise FeatureLibError("Expected glyph class name", location) +*/ + __pyx_t_3 = __Pyx_PyLong_AddObjC(__pyx_v_start, __pyx_mstate_global->__pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 111, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 111, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_10 = __Pyx_PyObject_GetSlice(__pyx_v_text, 0, 0, &__pyx_t_3, &__pyx_t_2, NULL, 0, 0, 1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 111, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_glyphclass = __pyx_t_10; + __pyx_t_10 = 0; + + /* "fontTools/feaLib/lexer.py":112 + * self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) + * glyphclass = text[start + 1 : self.pos_] + * if len(glyphclass) < 1: # <<<<<<<<<<<<<< + * raise FeatureLibError("Expected glyph class name", location) + * if not Lexer.RE_GLYPHCLASS.match(glyphclass): +*/ + __pyx_t_6 = PyObject_Length(__pyx_v_glyphclass); if (unlikely(__pyx_t_6 == ((Py_ssize_t)-1))) __PYX_ERR(0, 112, __pyx_L1_error) + __pyx_t_7 = (__pyx_t_6 < 1); + if (unlikely(__pyx_t_7)) { + + /* "fontTools/feaLib/lexer.py":113 + * glyphclass = text[start + 1 : self.pos_] + * if len(glyphclass) < 1: + * raise FeatureLibError("Expected glyph class name", location) # <<<<<<<<<<<<<< + * if not Lexer.RE_GLYPHCLASS.match(glyphclass): + * raise FeatureLibError( +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_FeatureLibError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_Expected_glyph_class_name, __pyx_v_location}; + __pyx_t_10 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + } + __Pyx_Raise(__pyx_t_10, 0, 0, 0); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __PYX_ERR(0, 113, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":112 + * self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) + * glyphclass = text[start + 1 : self.pos_] + * if len(glyphclass) < 1: # <<<<<<<<<<<<<< + * raise FeatureLibError("Expected glyph class name", location) + * if not Lexer.RE_GLYPHCLASS.match(glyphclass): +*/ + } + + /* "fontTools/feaLib/lexer.py":114 + * if len(glyphclass) < 1: + * raise FeatureLibError("Expected glyph class name", location) + * if not Lexer.RE_GLYPHCLASS.match(glyphclass): # <<<<<<<<<<<<<< + * raise FeatureLibError( + * "Glyph class names must consist of letters, digits, " +*/ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_RE_GLYPHCLASS); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_3 = __pyx_t_1; + __Pyx_INCREF(__pyx_t_3); + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_glyphclass}; + __pyx_t_10 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_match, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + } + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_8 = (!__pyx_t_7); + if (unlikely(__pyx_t_8)) { + + /* "fontTools/feaLib/lexer.py":115 + * raise FeatureLibError("Expected glyph class name", location) + * if not Lexer.RE_GLYPHCLASS.match(glyphclass): + * raise FeatureLibError( # <<<<<<<<<<<<<< + * "Glyph class names must consist of letters, digits, " + * "underscore, period or hyphen", +*/ + __pyx_t_1 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_FeatureLibError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/feaLib/lexer.py":118 + * "Glyph class names must consist of letters, digits, " + * "underscore, period or hyphen", + * location, # <<<<<<<<<<<<<< + * ) + * return (Lexer.GLYPHCLASS, glyphclass, location) +*/ + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_1); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_1, __pyx_mstate_global->__pyx_kp_u_Glyph_class_names_must_consist_o, __pyx_v_location}; + __pyx_t_10 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + } + __Pyx_Raise(__pyx_t_10, 0, 0, 0); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __PYX_ERR(0, 115, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":114 + * if len(glyphclass) < 1: + * raise FeatureLibError("Expected glyph class name", location) + * if not Lexer.RE_GLYPHCLASS.match(glyphclass): # <<<<<<<<<<<<<< + * raise FeatureLibError( + * "Glyph class names must consist of letters, digits, " +*/ + } + + /* "fontTools/feaLib/lexer.py":120 + * location, + * ) + * return (Lexer.GLYPHCLASS, glyphclass, location) # <<<<<<<<<<<<<< + * if cur_char in Lexer.CHAR_NAME_START_: + * self.pos_ += 1 +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 120, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_GLYPHCLASS); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 120, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 120, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_3) != (0)) __PYX_ERR(0, 120, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_glyphclass); + __Pyx_GIVEREF(__pyx_v_glyphclass); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_v_glyphclass) != (0)) __PYX_ERR(0, 120, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 120, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_r = __pyx_t_10; + __pyx_t_10 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":108 + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.CID, int(text[start + 1 : self.pos_], 10), location) + * if cur_char == "@": # <<<<<<<<<<<<<< + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) +*/ + } + + /* "fontTools/feaLib/lexer.py":121 + * ) + * return (Lexer.GLYPHCLASS, glyphclass, location) + * if cur_char in Lexer.CHAR_NAME_START_: # <<<<<<<<<<<<<< + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) +*/ + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_CHAR_NAME_START); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_8 = (__Pyx_PySequence_ContainsTF(__pyx_v_cur_char, __pyx_t_3, Py_EQ)); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_8) { + + /* "fontTools/feaLib/lexer.py":122 + * return (Lexer.GLYPHCLASS, glyphclass, location) + * if cur_char in Lexer.CHAR_NAME_START_: + * self.pos_ += 1 # <<<<<<<<<<<<<< + * self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) + * token = text[start : self.pos_] +*/ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 122, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_10 = __Pyx_PyLong_AddObjC(__pyx_t_3, __pyx_mstate_global->__pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 122, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos, __pyx_t_10) < (0)) __PYX_ERR(0, 122, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + + /* "fontTools/feaLib/lexer.py":123 + * if cur_char in Lexer.CHAR_NAME_START_: + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) # <<<<<<<<<<<<<< + * token = text[start : self.pos_] + * if token == "include": +*/ + __pyx_t_3 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_3); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 123, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_CHAR_NAME_CONTINUATION); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 123, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_t_2}; + __pyx_t_10 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_over, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 123, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + } + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + + /* "fontTools/feaLib/lexer.py":124 + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) + * token = text[start : self.pos_] # <<<<<<<<<<<<<< + * if token == "include": + * self.mode_ = Lexer.MODE_FILENAME_ +*/ + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 124, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_2 = __Pyx_PyObject_GetSlice(__pyx_v_text, 0, 0, &__pyx_v_start, &__pyx_t_10, NULL, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 124, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_v_token = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":125 + * self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) + * token = text[start : self.pos_] + * if token == "include": # <<<<<<<<<<<<<< + * self.mode_ = Lexer.MODE_FILENAME_ + * return (Lexer.NAME, token, location) +*/ + __pyx_t_8 = (__Pyx_PyUnicode_Equals(__pyx_v_token, __pyx_mstate_global->__pyx_n_u_include, Py_EQ)); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 125, __pyx_L1_error) + if (__pyx_t_8) { + + /* "fontTools/feaLib/lexer.py":126 + * token = text[start : self.pos_] + * if token == "include": + * self.mode_ = Lexer.MODE_FILENAME_ # <<<<<<<<<<<<<< + * return (Lexer.NAME, token, location) + * if cur_char == "0" and next_char in "xX": +*/ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_MODE_FILENAME); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_mode, __pyx_t_10) < (0)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + + /* "fontTools/feaLib/lexer.py":125 + * self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) + * token = text[start : self.pos_] + * if token == "include": # <<<<<<<<<<<<<< + * self.mode_ = Lexer.MODE_FILENAME_ + * return (Lexer.NAME, token, location) +*/ + } + + /* "fontTools/feaLib/lexer.py":127 + * if token == "include": + * self.mode_ = Lexer.MODE_FILENAME_ + * return (Lexer.NAME, token, location) # <<<<<<<<<<<<<< + * if cur_char == "0" and next_char in "xX": + * self.pos_ += 2 +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 127, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_NAME); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 127, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 127, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_2) != (0)) __PYX_ERR(0, 127, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_token); + __Pyx_GIVEREF(__pyx_v_token); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_v_token) != (0)) __PYX_ERR(0, 127, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 127, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_r = __pyx_t_10; + __pyx_t_10 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":121 + * ) + * return (Lexer.GLYPHCLASS, glyphclass, location) + * if cur_char in Lexer.CHAR_NAME_START_: # <<<<<<<<<<<<<< + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) +*/ + } + + /* "fontTools/feaLib/lexer.py":128 + * self.mode_ = Lexer.MODE_FILENAME_ + * return (Lexer.NAME, token, location) + * if cur_char == "0" and next_char in "xX": # <<<<<<<<<<<<<< + * self.pos_ += 2 + * self.scan_over_(Lexer.CHAR_HEXDIGIT_) +*/ + __pyx_t_7 = (__Pyx_PyUnicode_Equals(__pyx_v_cur_char, __pyx_mstate_global->__pyx_kp_u_0, Py_EQ)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 128, __pyx_L1_error) + if (__pyx_t_7) { + } else { + __pyx_t_8 = __pyx_t_7; + goto __pyx_L19_bool_binop_done; + } + __pyx_t_7 = (__Pyx_PyUnicode_ContainsTF(__pyx_v_next_char, __pyx_mstate_global->__pyx_n_u_xX, Py_EQ)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 128, __pyx_L1_error) + __pyx_t_8 = __pyx_t_7; + __pyx_L19_bool_binop_done:; + if (__pyx_t_8) { + + /* "fontTools/feaLib/lexer.py":129 + * return (Lexer.NAME, token, location) + * if cur_char == "0" and next_char in "xX": + * self.pos_ += 2 # <<<<<<<<<<<<<< + * self.scan_over_(Lexer.CHAR_HEXDIGIT_) + * return (Lexer.HEXADECIMAL, int(text[start : self.pos_], 16), location) +*/ + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 129, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_2 = __Pyx_PyLong_AddObjC(__pyx_t_10, __pyx_mstate_global->__pyx_int_2, 2, 1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 129, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos, __pyx_t_2) < (0)) __PYX_ERR(0, 129, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":130 + * if cur_char == "0" and next_char in "xX": + * self.pos_ += 2 + * self.scan_over_(Lexer.CHAR_HEXDIGIT_) # <<<<<<<<<<<<<< + * return (Lexer.HEXADECIMAL, int(text[start : self.pos_], 16), location) + * if cur_char == "0" and next_char in Lexer.CHAR_DIGIT_: +*/ + __pyx_t_10 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_10); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 130, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_CHAR_HEXDIGIT); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 130, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_10, __pyx_t_1}; + __pyx_t_2 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_over, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 130, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":131 + * self.pos_ += 2 + * self.scan_over_(Lexer.CHAR_HEXDIGIT_) + * return (Lexer.HEXADECIMAL, int(text[start : self.pos_], 16), location) # <<<<<<<<<<<<<< + * if cur_char == "0" and next_char in Lexer.CHAR_DIGIT_: + * self.scan_over_(Lexer.CHAR_DIGIT_) +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_HEXADECIMAL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_10 = NULL; + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_9 = __Pyx_PyObject_GetSlice(__pyx_v_text, 0, 0, &__pyx_v_start, &__pyx_t_3, NULL, 0, 0, 1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_10, __pyx_t_9, __pyx_mstate_global->__pyx_int_16}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)(&PyLong_Type), __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 131, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_2) != (0)) __PYX_ERR(0, 131, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 131, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_r = __pyx_t_9; + __pyx_t_9 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":128 + * self.mode_ = Lexer.MODE_FILENAME_ + * return (Lexer.NAME, token, location) + * if cur_char == "0" and next_char in "xX": # <<<<<<<<<<<<<< + * self.pos_ += 2 + * self.scan_over_(Lexer.CHAR_HEXDIGIT_) +*/ + } + + /* "fontTools/feaLib/lexer.py":132 + * self.scan_over_(Lexer.CHAR_HEXDIGIT_) + * return (Lexer.HEXADECIMAL, int(text[start : self.pos_], 16), location) + * if cur_char == "0" and next_char in Lexer.CHAR_DIGIT_: # <<<<<<<<<<<<<< + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.OCTAL, int(text[start : self.pos_], 8), location) +*/ + __pyx_t_7 = (__Pyx_PyUnicode_Equals(__pyx_v_cur_char, __pyx_mstate_global->__pyx_kp_u_0, Py_EQ)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 132, __pyx_L1_error) + if (__pyx_t_7) { + } else { + __pyx_t_8 = __pyx_t_7; + goto __pyx_L22_bool_binop_done; + } + __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 132, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_mstate_global->__pyx_n_u_CHAR_DIGIT); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 132, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_7 = (__Pyx_PySequence_ContainsTF(__pyx_v_next_char, __pyx_t_2, Py_EQ)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 132, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_8 = __pyx_t_7; + __pyx_L22_bool_binop_done:; + if (__pyx_t_8) { + + /* "fontTools/feaLib/lexer.py":133 + * return (Lexer.HEXADECIMAL, int(text[start : self.pos_], 16), location) + * if cur_char == "0" and next_char in Lexer.CHAR_DIGIT_: + * self.scan_over_(Lexer.CHAR_DIGIT_) # <<<<<<<<<<<<<< + * return (Lexer.OCTAL, int(text[start : self.pos_], 8), location) + * if cur_char in Lexer.CHAR_DIGIT_: +*/ + __pyx_t_9 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_9); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 133, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_CHAR_DIGIT); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 133, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_9, __pyx_t_10}; + __pyx_t_2 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_over, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 133, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":134 + * if cur_char == "0" and next_char in Lexer.CHAR_DIGIT_: + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.OCTAL, int(text[start : self.pos_], 8), location) # <<<<<<<<<<<<<< + * if cur_char in Lexer.CHAR_DIGIT_: + * self.scan_over_(Lexer.CHAR_DIGIT_) +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 134, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_OCTAL); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 134, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_9 = NULL; + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 134, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_GetSlice(__pyx_v_text, 0, 0, &__pyx_v_start, &__pyx_t_1, NULL, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 134, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_9, __pyx_t_3, __pyx_mstate_global->__pyx_int_8}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)(&PyLong_Type), __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 134, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 134, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_10); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_10) != (0)) __PYX_ERR(0, 134, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2) != (0)) __PYX_ERR(0, 134, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 134, __pyx_L1_error); + __pyx_t_10 = 0; + __pyx_t_2 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":132 + * self.scan_over_(Lexer.CHAR_HEXDIGIT_) + * return (Lexer.HEXADECIMAL, int(text[start : self.pos_], 16), location) + * if cur_char == "0" and next_char in Lexer.CHAR_DIGIT_: # <<<<<<<<<<<<<< + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.OCTAL, int(text[start : self.pos_], 8), location) +*/ + } + + /* "fontTools/feaLib/lexer.py":135 + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.OCTAL, int(text[start : self.pos_], 8), location) + * if cur_char in Lexer.CHAR_DIGIT_: # <<<<<<<<<<<<<< + * self.scan_over_(Lexer.CHAR_DIGIT_) + * if self.pos_ >= limit or text[self.pos_] != ".": +*/ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 135, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_CHAR_DIGIT); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 135, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_8 = (__Pyx_PySequence_ContainsTF(__pyx_v_cur_char, __pyx_t_2, Py_EQ)); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 135, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__pyx_t_8) { + + /* "fontTools/feaLib/lexer.py":136 + * return (Lexer.OCTAL, int(text[start : self.pos_], 8), location) + * if cur_char in Lexer.CHAR_DIGIT_: + * self.scan_over_(Lexer.CHAR_DIGIT_) # <<<<<<<<<<<<<< + * if self.pos_ >= limit or text[self.pos_] != ".": + * return (Lexer.NUMBER, int(text[start : self.pos_], 10), location) +*/ + __pyx_t_3 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_3); + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_CHAR_DIGIT); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_t_9}; + __pyx_t_2 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_over, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":137 + * if cur_char in Lexer.CHAR_DIGIT_: + * self.scan_over_(Lexer.CHAR_DIGIT_) + * if self.pos_ >= limit or text[self.pos_] != ".": # <<<<<<<<<<<<<< + * return (Lexer.NUMBER, int(text[start : self.pos_], 10), location) + * self.scan_over_(".") +*/ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 137, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_9 = PyLong_FromSsize_t(__pyx_v_limit); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 137, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_3 = PyObject_RichCompare(__pyx_t_2, __pyx_t_9, Py_GE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 137, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 137, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (!__pyx_t_7) { + } else { + __pyx_t_8 = __pyx_t_7; + goto __pyx_L26_bool_binop_done; + } + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 137, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_9 = __Pyx_PyObject_GetItem(__pyx_v_text, __pyx_t_3); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 137, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = (__Pyx_PyUnicode_Equals(__pyx_t_9, __pyx_mstate_global->__pyx_kp_u__8, Py_NE)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 137, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_8 = __pyx_t_7; + __pyx_L26_bool_binop_done:; + if (__pyx_t_8) { + + /* "fontTools/feaLib/lexer.py":138 + * self.scan_over_(Lexer.CHAR_DIGIT_) + * if self.pos_ >= limit or text[self.pos_] != ".": + * return (Lexer.NUMBER, int(text[start : self.pos_], 10), location) # <<<<<<<<<<<<<< + * self.scan_over_(".") + * self.scan_over_(Lexer.CHAR_DIGIT_) +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 138, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_mstate_global->__pyx_n_u_NUMBER); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 138, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_2 = NULL; + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 138, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_1 = __Pyx_PyObject_GetSlice(__pyx_v_text, 0, 0, &__pyx_v_start, &__pyx_t_10, NULL, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 138, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_t_1, __pyx_mstate_global->__pyx_int_10}; + __pyx_t_9 = __Pyx_PyObject_FastCall((PyObject*)(&PyLong_Type), __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 138, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + } + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 138, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3) != (0)) __PYX_ERR(0, 138, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_9); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_9) != (0)) __PYX_ERR(0, 138, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 138, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_t_9 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":137 + * if cur_char in Lexer.CHAR_DIGIT_: + * self.scan_over_(Lexer.CHAR_DIGIT_) + * if self.pos_ >= limit or text[self.pos_] != ".": # <<<<<<<<<<<<<< + * return (Lexer.NUMBER, int(text[start : self.pos_], 10), location) + * self.scan_over_(".") +*/ + } + + /* "fontTools/feaLib/lexer.py":139 + * if self.pos_ >= limit or text[self.pos_] != ".": + * return (Lexer.NUMBER, int(text[start : self.pos_], 10), location) + * self.scan_over_(".") # <<<<<<<<<<<<<< + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.FLOAT, float(text[start : self.pos_]), location) +*/ + __pyx_t_9 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_9); + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_9, __pyx_mstate_global->__pyx_kp_u__8}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_over, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 139, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/feaLib/lexer.py":140 + * return (Lexer.NUMBER, int(text[start : self.pos_], 10), location) + * self.scan_over_(".") + * self.scan_over_(Lexer.CHAR_DIGIT_) # <<<<<<<<<<<<<< + * return (Lexer.FLOAT, float(text[start : self.pos_]), location) + * if cur_char == "-" and next_char in Lexer.CHAR_DIGIT_: +*/ + __pyx_t_9 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_9); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 140, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_CHAR_DIGIT); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 140, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_9, __pyx_t_2}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_over, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 140, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/feaLib/lexer.py":141 + * self.scan_over_(".") + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.FLOAT, float(text[start : self.pos_]), location) # <<<<<<<<<<<<<< + * if cur_char == "-" and next_char in Lexer.CHAR_DIGIT_: + * self.pos_ += 1 +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 141, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_FLOAT); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 141, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 141, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_9 = __Pyx_PyObject_GetSlice(__pyx_v_text, 0, 0, &__pyx_v_start, &__pyx_t_1, NULL, 0, 0, 1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 141, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyNumber_Float(__pyx_t_9); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 141, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 141, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_2) != (0)) __PYX_ERR(0, 141, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_1) != (0)) __PYX_ERR(0, 141, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 141, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_1 = 0; + __pyx_r = __pyx_t_9; + __pyx_t_9 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":135 + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.OCTAL, int(text[start : self.pos_], 8), location) + * if cur_char in Lexer.CHAR_DIGIT_: # <<<<<<<<<<<<<< + * self.scan_over_(Lexer.CHAR_DIGIT_) + * if self.pos_ >= limit or text[self.pos_] != ".": +*/ + } + + /* "fontTools/feaLib/lexer.py":142 + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.FLOAT, float(text[start : self.pos_]), location) + * if cur_char == "-" and next_char in Lexer.CHAR_DIGIT_: # <<<<<<<<<<<<<< + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_DIGIT_) +*/ + __pyx_t_7 = (__Pyx_PyUnicode_Equals(__pyx_v_cur_char, __pyx_mstate_global->__pyx_kp_u__9, Py_EQ)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 142, __pyx_L1_error) + if (__pyx_t_7) { + } else { + __pyx_t_8 = __pyx_t_7; + goto __pyx_L29_bool_binop_done; + } + __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_mstate_global->__pyx_n_u_CHAR_DIGIT); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_7 = (__Pyx_PySequence_ContainsTF(__pyx_v_next_char, __pyx_t_1, Py_EQ)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_8 = __pyx_t_7; + __pyx_L29_bool_binop_done:; + if (__pyx_t_8) { + + /* "fontTools/feaLib/lexer.py":143 + * return (Lexer.FLOAT, float(text[start : self.pos_]), location) + * if cur_char == "-" and next_char in Lexer.CHAR_DIGIT_: + * self.pos_ += 1 # <<<<<<<<<<<<<< + * self.scan_over_(Lexer.CHAR_DIGIT_) + * if self.pos_ >= limit or text[self.pos_] != ".": +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 143, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_9 = __Pyx_PyLong_AddObjC(__pyx_t_1, __pyx_mstate_global->__pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 143, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos, __pyx_t_9) < (0)) __PYX_ERR(0, 143, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "fontTools/feaLib/lexer.py":144 + * if cur_char == "-" and next_char in Lexer.CHAR_DIGIT_: + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_DIGIT_) # <<<<<<<<<<<<<< + * if self.pos_ >= limit or text[self.pos_] != ".": + * return (Lexer.NUMBER, int(text[start : self.pos_], 10), location) +*/ + __pyx_t_1 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_1); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 144, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_CHAR_DIGIT); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 144, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_t_3}; + __pyx_t_9 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_over, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 144, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + } + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "fontTools/feaLib/lexer.py":145 + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_DIGIT_) + * if self.pos_ >= limit or text[self.pos_] != ".": # <<<<<<<<<<<<<< + * return (Lexer.NUMBER, int(text[start : self.pos_], 10), location) + * self.scan_over_(".") +*/ + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 145, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_3 = PyLong_FromSsize_t(__pyx_v_limit); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 145, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyObject_RichCompare(__pyx_t_9, __pyx_t_3, Py_GE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 145, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 145, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (!__pyx_t_7) { + } else { + __pyx_t_8 = __pyx_t_7; + goto __pyx_L32_bool_binop_done; + } + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 145, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_text, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 145, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = (__Pyx_PyUnicode_Equals(__pyx_t_3, __pyx_mstate_global->__pyx_kp_u__8, Py_NE)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 145, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_8 = __pyx_t_7; + __pyx_L32_bool_binop_done:; + if (__pyx_t_8) { + + /* "fontTools/feaLib/lexer.py":146 + * self.scan_over_(Lexer.CHAR_DIGIT_) + * if self.pos_ >= limit or text[self.pos_] != ".": + * return (Lexer.NUMBER, int(text[start : self.pos_], 10), location) # <<<<<<<<<<<<<< + * self.scan_over_(".") + * self.scan_over_(Lexer.CHAR_DIGIT_) +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 146, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_NUMBER); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 146, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_9 = NULL; + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 146, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_10 = __Pyx_PyObject_GetSlice(__pyx_v_text, 0, 0, &__pyx_v_start, &__pyx_t_2, NULL, 0, 0, 1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 146, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_9, __pyx_t_10, __pyx_mstate_global->__pyx_int_10}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)(&PyLong_Type), __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 146, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 146, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 146, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_3) != (0)) __PYX_ERR(0, 146, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 146, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_r = __pyx_t_10; + __pyx_t_10 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":145 + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_DIGIT_) + * if self.pos_ >= limit or text[self.pos_] != ".": # <<<<<<<<<<<<<< + * return (Lexer.NUMBER, int(text[start : self.pos_], 10), location) + * self.scan_over_(".") +*/ + } + + /* "fontTools/feaLib/lexer.py":147 + * if self.pos_ >= limit or text[self.pos_] != ".": + * return (Lexer.NUMBER, int(text[start : self.pos_], 10), location) + * self.scan_over_(".") # <<<<<<<<<<<<<< + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.FLOAT, float(text[start : self.pos_]), location) +*/ + __pyx_t_3 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_3); + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_mstate_global->__pyx_kp_u__8}; + __pyx_t_10 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_over, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + } + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + + /* "fontTools/feaLib/lexer.py":148 + * return (Lexer.NUMBER, int(text[start : self.pos_], 10), location) + * self.scan_over_(".") + * self.scan_over_(Lexer.CHAR_DIGIT_) # <<<<<<<<<<<<<< + * return (Lexer.FLOAT, float(text[start : self.pos_]), location) + * if cur_char in Lexer.CHAR_SYMBOL_: +*/ + __pyx_t_3 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_3); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_CHAR_DIGIT); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_t_9}; + __pyx_t_10 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_over, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + } + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + + /* "fontTools/feaLib/lexer.py":149 + * self.scan_over_(".") + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.FLOAT, float(text[start : self.pos_]), location) # <<<<<<<<<<<<<< + * if cur_char in Lexer.CHAR_SYMBOL_: + * self.pos_ += 1 +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_FLOAT); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_3 = __Pyx_PyObject_GetSlice(__pyx_v_text, 0, 0, &__pyx_v_start, &__pyx_t_10, NULL, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_10 = __Pyx_PyNumber_Float(__pyx_t_3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_9); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_9) != (0)) __PYX_ERR(0, 149, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_10); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_10) != (0)) __PYX_ERR(0, 149, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 149, __pyx_L1_error); + __pyx_t_9 = 0; + __pyx_t_10 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":142 + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.FLOAT, float(text[start : self.pos_]), location) + * if cur_char == "-" and next_char in Lexer.CHAR_DIGIT_: # <<<<<<<<<<<<<< + * self.pos_ += 1 + * self.scan_over_(Lexer.CHAR_DIGIT_) +*/ + } + + /* "fontTools/feaLib/lexer.py":150 + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.FLOAT, float(text[start : self.pos_]), location) + * if cur_char in Lexer.CHAR_SYMBOL_: # <<<<<<<<<<<<<< + * self.pos_ += 1 + * return (Lexer.SYMBOL, cur_char, location) +*/ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 150, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_CHAR_SYMBOL); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 150, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_8 = (__Pyx_PySequence_ContainsTF(__pyx_v_cur_char, __pyx_t_10, Py_EQ)); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 150, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (__pyx_t_8) { + + /* "fontTools/feaLib/lexer.py":151 + * return (Lexer.FLOAT, float(text[start : self.pos_]), location) + * if cur_char in Lexer.CHAR_SYMBOL_: + * self.pos_ += 1 # <<<<<<<<<<<<<< + * return (Lexer.SYMBOL, cur_char, location) + * if cur_char == '"': +*/ + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 151, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_3 = __Pyx_PyLong_AddObjC(__pyx_t_10, __pyx_mstate_global->__pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 151, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos, __pyx_t_3) < (0)) __PYX_ERR(0, 151, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/feaLib/lexer.py":152 + * if cur_char in Lexer.CHAR_SYMBOL_: + * self.pos_ += 1 + * return (Lexer.SYMBOL, cur_char, location) # <<<<<<<<<<<<<< + * if cur_char == '"': + * self.pos_ += 1 +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 152, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_SYMBOL); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 152, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 152, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_10); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_10) != (0)) __PYX_ERR(0, 152, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_cur_char); + __Pyx_GIVEREF(__pyx_v_cur_char); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_cur_char) != (0)) __PYX_ERR(0, 152, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 152, __pyx_L1_error); + __pyx_t_10 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":150 + * self.scan_over_(Lexer.CHAR_DIGIT_) + * return (Lexer.FLOAT, float(text[start : self.pos_]), location) + * if cur_char in Lexer.CHAR_SYMBOL_: # <<<<<<<<<<<<<< + * self.pos_ += 1 + * return (Lexer.SYMBOL, cur_char, location) +*/ + } + + /* "fontTools/feaLib/lexer.py":153 + * self.pos_ += 1 + * return (Lexer.SYMBOL, cur_char, location) + * if cur_char == '"': # <<<<<<<<<<<<<< + * self.pos_ += 1 + * self.scan_until_('"') +*/ + __pyx_t_8 = (__Pyx_PyUnicode_Equals(__pyx_v_cur_char, __pyx_mstate_global->__pyx_kp_u__10, Py_EQ)); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 153, __pyx_L1_error) + if (__pyx_t_8) { + + /* "fontTools/feaLib/lexer.py":154 + * return (Lexer.SYMBOL, cur_char, location) + * if cur_char == '"': + * self.pos_ += 1 # <<<<<<<<<<<<<< + * self.scan_until_('"') + * if self.pos_ < self.text_length_ and self.text_[self.pos_] == '"': +*/ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 154, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_10 = __Pyx_PyLong_AddObjC(__pyx_t_3, __pyx_mstate_global->__pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 154, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos, __pyx_t_10) < (0)) __PYX_ERR(0, 154, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + + /* "fontTools/feaLib/lexer.py":155 + * if cur_char == '"': + * self.pos_ += 1 + * self.scan_until_('"') # <<<<<<<<<<<<<< + * if self.pos_ < self.text_length_ and self.text_[self.pos_] == '"': + * self.pos_ += 1 +*/ + __pyx_t_3 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_3); + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_mstate_global->__pyx_kp_u__10}; + __pyx_t_10 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_until, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 155, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + } + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + + /* "fontTools/feaLib/lexer.py":156 + * self.pos_ += 1 + * self.scan_until_('"') + * if self.pos_ < self.text_length_ and self.text_[self.pos_] == '"': # <<<<<<<<<<<<<< + * self.pos_ += 1 + * # strip newlines embedded within a string +*/ + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 156, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_text_length); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 156, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_9 = PyObject_RichCompare(__pyx_t_10, __pyx_t_3, Py_LT); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 156, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 156, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (__pyx_t_7) { + } else { + __pyx_t_8 = __pyx_t_7; + goto __pyx_L37_bool_binop_done; + } + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_text_2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 156, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 156, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_10 = __Pyx_PyObject_GetItem(__pyx_t_9, __pyx_t_3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 156, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = (__Pyx_PyUnicode_Equals(__pyx_t_10, __pyx_mstate_global->__pyx_kp_u__10, Py_EQ)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 156, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_8 = __pyx_t_7; + __pyx_L37_bool_binop_done:; + if (likely(__pyx_t_8)) { + + /* "fontTools/feaLib/lexer.py":157 + * self.scan_until_('"') + * if self.pos_ < self.text_length_ and self.text_[self.pos_] == '"': + * self.pos_ += 1 # <<<<<<<<<<<<<< + * # strip newlines embedded within a string + * string = re.sub("[\r\n]", "", text[start + 1 : self.pos_ - 1]) +*/ + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 157, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_3 = __Pyx_PyLong_AddObjC(__pyx_t_10, __pyx_mstate_global->__pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 157, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos, __pyx_t_3) < (0)) __PYX_ERR(0, 157, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/feaLib/lexer.py":159 + * self.pos_ += 1 + * # strip newlines embedded within a string + * string = re.sub("[\r\n]", "", text[start + 1 : self.pos_ - 1]) # <<<<<<<<<<<<<< + * return (Lexer.STRING, string, location) + * else: +*/ + __pyx_t_10 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_mstate_global->__pyx_n_u_re); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_mstate_global->__pyx_n_u_sub); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_9 = __Pyx_PyLong_AddObjC(__pyx_v_start, __pyx_mstate_global->__pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyLong_SubtractObjC(__pyx_t_2, __pyx_mstate_global->__pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_GetSlice(__pyx_v_text, 0, 0, &__pyx_t_9, &__pyx_t_4, NULL, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_10); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_10, __pyx_mstate_global->__pyx_kp_u__11, __pyx_mstate_global->__pyx_kp_u__12, __pyx_t_2}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_5, (4-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __pyx_v_string = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/feaLib/lexer.py":160 + * # strip newlines embedded within a string + * string = re.sub("[\r\n]", "", text[start + 1 : self.pos_ - 1]) + * return (Lexer.STRING, string, location) # <<<<<<<<<<<<<< + * else: + * raise FeatureLibError("Expected '\"' to terminate string", location) +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 160, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_STRING); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 160, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 160, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 160, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_string); + __Pyx_GIVEREF(__pyx_v_string); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_string) != (0)) __PYX_ERR(0, 160, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 160, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":156 + * self.pos_ += 1 + * self.scan_until_('"') + * if self.pos_ < self.text_length_ and self.text_[self.pos_] == '"': # <<<<<<<<<<<<<< + * self.pos_ += 1 + * # strip newlines embedded within a string +*/ + } + + /* "fontTools/feaLib/lexer.py":162 + * return (Lexer.STRING, string, location) + * else: + * raise FeatureLibError("Expected '\"' to terminate string", location) # <<<<<<<<<<<<<< + * raise FeatureLibError("Unexpected character: %r" % cur_char, location) + * +*/ + /*else*/ { + __pyx_t_1 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_FeatureLibError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 162, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_1); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_1, __pyx_mstate_global->__pyx_kp_u_Expected_to_terminate_string, __pyx_v_location}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 162, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 162, __pyx_L1_error) + } + + /* "fontTools/feaLib/lexer.py":153 + * self.pos_ += 1 + * return (Lexer.SYMBOL, cur_char, location) + * if cur_char == '"': # <<<<<<<<<<<<<< + * self.pos_ += 1 + * self.scan_until_('"') +*/ + } + + /* "fontTools/feaLib/lexer.py":163 + * else: + * raise FeatureLibError("Expected '\"' to terminate string", location) + * raise FeatureLibError("Unexpected character: %r" % cur_char, location) # <<<<<<<<<<<<<< + * + * def scan_over_(self, valid): +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_FeatureLibError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 163, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_10 = __Pyx_PyUnicode_FormatSafe(__pyx_mstate_global->__pyx_kp_u_Unexpected_character_r, __pyx_v_cur_char); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 163, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_t_10, __pyx_v_location}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 163, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 163, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":68 + * return FeatureLibLocation(self.filename_ or "", self.line_, column) + * + * def next_(self): # <<<<<<<<<<<<<< + * self.scan_over_(Lexer.CHAR_WHITESPACE_) + * location = self.location_() +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.next_", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_location); + __Pyx_XDECREF(__pyx_v_start); + __Pyx_XDECREF(__pyx_v_text); + __Pyx_XDECREF(__pyx_v_cur_char); + __Pyx_XDECREF(__pyx_v_next_char); + __Pyx_XDECREF(__pyx_v_glyphclass); + __Pyx_XDECREF(__pyx_v_token); + __Pyx_XDECREF(__pyx_v_string); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/feaLib/lexer.py":165 + * raise FeatureLibError("Unexpected character: %r" % cur_char, location) + * + * def scan_over_(self, valid): # <<<<<<<<<<<<<< + * p = self.pos_ + * while p < self.text_length_ and self.text_[p] in valid: +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_13scan_over_(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_6feaLib_5lexer_5Lexer_12scan_over_, "Lexer.scan_over_(self, valid)"); +static PyMethodDef __pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_13scan_over_ = {"scan_over_", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_13scan_over_, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_6feaLib_5lexer_5Lexer_12scan_over_}; +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_13scan_over_(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_valid = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("scan_over_ (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_valid,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 165, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 165, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 165, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "scan_over_", 0) < (0)) __PYX_ERR(0, 165, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("scan_over_", 1, 2, 2, i); __PYX_ERR(0, 165, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 165, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 165, __pyx_L3_error) + } + __pyx_v_self = values[0]; + __pyx_v_valid = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("scan_over_", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 165, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.scan_over_", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_12scan_over_(__pyx_self, __pyx_v_self, __pyx_v_valid); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_12scan_over_(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_valid) { + PyObject *__pyx_v_p = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("scan_over_", 0); + + /* "fontTools/feaLib/lexer.py":166 + * + * def scan_over_(self, valid): + * p = self.pos_ # <<<<<<<<<<<<<< + * while p < self.text_length_ and self.text_[p] in valid: + * p += 1 +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 166, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_p = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/feaLib/lexer.py":167 + * def scan_over_(self, valid): + * p = self.pos_ + * while p < self.text_length_ and self.text_[p] in valid: # <<<<<<<<<<<<<< + * p += 1 + * self.pos_ = p +*/ + while (1) { + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_text_length); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 167, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_p, __pyx_t_1, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 167, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 167, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_4) { + } else { + __pyx_t_2 = __pyx_t_4; + goto __pyx_L5_bool_binop_done; + } + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_text_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 167, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_v_p); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 167, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = (__Pyx_PySequence_ContainsTF(__pyx_t_1, __pyx_v_valid, Py_EQ)); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 167, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_2 = __pyx_t_4; + __pyx_L5_bool_binop_done:; + if (!__pyx_t_2) break; + + /* "fontTools/feaLib/lexer.py":168 + * p = self.pos_ + * while p < self.text_length_ and self.text_[p] in valid: + * p += 1 # <<<<<<<<<<<<<< + * self.pos_ = p + * +*/ + __pyx_t_1 = __Pyx_PyLong_AddObjC(__pyx_v_p, __pyx_mstate_global->__pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 168, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF_SET(__pyx_v_p, __pyx_t_1); + __pyx_t_1 = 0; + } + + /* "fontTools/feaLib/lexer.py":169 + * while p < self.text_length_ and self.text_[p] in valid: + * p += 1 + * self.pos_ = p # <<<<<<<<<<<<<< + * + * def scan_until_(self, stop_at): +*/ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos, __pyx_v_p) < (0)) __PYX_ERR(0, 169, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":165 + * raise FeatureLibError("Unexpected character: %r" % cur_char, location) + * + * def scan_over_(self, valid): # <<<<<<<<<<<<<< + * p = self.pos_ + * while p < self.text_length_ and self.text_[p] in valid: +*/ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.scan_over_", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_p); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/feaLib/lexer.py":171 + * self.pos_ = p + * + * def scan_until_(self, stop_at): # <<<<<<<<<<<<<< + * p = self.pos_ + * while p < self.text_length_ and self.text_[p] not in stop_at: +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_15scan_until_(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_6feaLib_5lexer_5Lexer_14scan_until_, "Lexer.scan_until_(self, stop_at)"); +static PyMethodDef __pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_15scan_until_ = {"scan_until_", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_15scan_until_, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_6feaLib_5lexer_5Lexer_14scan_until_}; +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_15scan_until_(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_stop_at = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("scan_until_ (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_stop_at,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 171, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 171, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 171, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "scan_until_", 0) < (0)) __PYX_ERR(0, 171, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("scan_until_", 1, 2, 2, i); __PYX_ERR(0, 171, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 171, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 171, __pyx_L3_error) + } + __pyx_v_self = values[0]; + __pyx_v_stop_at = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("scan_until_", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 171, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.scan_until_", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_14scan_until_(__pyx_self, __pyx_v_self, __pyx_v_stop_at); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_14scan_until_(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_stop_at) { + PyObject *__pyx_v_p = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("scan_until_", 0); + + /* "fontTools/feaLib/lexer.py":172 + * + * def scan_until_(self, stop_at): + * p = self.pos_ # <<<<<<<<<<<<<< + * while p < self.text_length_ and self.text_[p] not in stop_at: + * p += 1 +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 172, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_p = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/feaLib/lexer.py":173 + * def scan_until_(self, stop_at): + * p = self.pos_ + * while p < self.text_length_ and self.text_[p] not in stop_at: # <<<<<<<<<<<<<< + * p += 1 + * self.pos_ = p +*/ + while (1) { + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_text_length); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 173, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_p, __pyx_t_1, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 173, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 173, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_4) { + } else { + __pyx_t_2 = __pyx_t_4; + goto __pyx_L5_bool_binop_done; + } + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_text_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 173, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_v_p); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 173, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = (__Pyx_PySequence_ContainsTF(__pyx_t_1, __pyx_v_stop_at, Py_NE)); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 173, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_2 = __pyx_t_4; + __pyx_L5_bool_binop_done:; + if (!__pyx_t_2) break; + + /* "fontTools/feaLib/lexer.py":174 + * p = self.pos_ + * while p < self.text_length_ and self.text_[p] not in stop_at: + * p += 1 # <<<<<<<<<<<<<< + * self.pos_ = p + * +*/ + __pyx_t_1 = __Pyx_PyLong_AddObjC(__pyx_v_p, __pyx_mstate_global->__pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 174, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF_SET(__pyx_v_p, __pyx_t_1); + __pyx_t_1 = 0; + } + + /* "fontTools/feaLib/lexer.py":175 + * while p < self.text_length_ and self.text_[p] not in stop_at: + * p += 1 + * self.pos_ = p # <<<<<<<<<<<<<< + * + * def scan_anonymous_block(self, tag): +*/ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos, __pyx_v_p) < (0)) __PYX_ERR(0, 175, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":171 + * self.pos_ = p + * + * def scan_until_(self, stop_at): # <<<<<<<<<<<<<< + * p = self.pos_ + * while p < self.text_length_ and self.text_[p] not in stop_at: +*/ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.scan_until_", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_p); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/feaLib/lexer.py":177 + * self.pos_ = p + * + * def scan_anonymous_block(self, tag): # <<<<<<<<<<<<<< + * location = self.location_() + * tag = tag.strip() +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_17scan_anonymous_block(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_6feaLib_5lexer_5Lexer_16scan_anonymous_block, "Lexer.scan_anonymous_block(self, tag)"); +static PyMethodDef __pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_17scan_anonymous_block = {"scan_anonymous_block", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_17scan_anonymous_block, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_6feaLib_5lexer_5Lexer_16scan_anonymous_block}; +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_5Lexer_17scan_anonymous_block(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_tag = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("scan_anonymous_block (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_tag,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 177, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 177, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 177, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "scan_anonymous_block", 0) < (0)) __PYX_ERR(0, 177, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("scan_anonymous_block", 1, 2, 2, i); __PYX_ERR(0, 177, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 177, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 177, __pyx_L3_error) + } + __pyx_v_self = values[0]; + __pyx_v_tag = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("scan_anonymous_block", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 177, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.scan_anonymous_block", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_16scan_anonymous_block(__pyx_self, __pyx_v_self, __pyx_v_tag); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_5Lexer_16scan_anonymous_block(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_tag) { + PyObject *__pyx_v_location = NULL; + PyObject *__pyx_v_regexp = NULL; + PyObject *__pyx_v_split = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + size_t __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + Py_ssize_t __pyx_t_8; + int __pyx_t_9; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("scan_anonymous_block", 0); + __Pyx_INCREF(__pyx_v_tag); + + /* "fontTools/feaLib/lexer.py":178 + * + * def scan_anonymous_block(self, tag): + * location = self.location_() # <<<<<<<<<<<<<< + * tag = tag.strip() + * self.scan_until_(Lexer.CHAR_NEWLINE_) +*/ + __pyx_t_2 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_location, __pyx_callargs+__pyx_t_3, (1-__pyx_t_3) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 178, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_v_location = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/feaLib/lexer.py":179 + * def scan_anonymous_block(self, tag): + * location = self.location_() + * tag = tag.strip() # <<<<<<<<<<<<<< + * self.scan_until_(Lexer.CHAR_NEWLINE_) + * self.scan_over_(Lexer.CHAR_NEWLINE_) +*/ + __pyx_t_2 = __pyx_v_tag; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_strip, __pyx_callargs+__pyx_t_3, (1-__pyx_t_3) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 179, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __Pyx_DECREF_SET(__pyx_v_tag, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/feaLib/lexer.py":180 + * location = self.location_() + * tag = tag.strip() + * self.scan_until_(Lexer.CHAR_NEWLINE_) # <<<<<<<<<<<<<< + * self.scan_over_(Lexer.CHAR_NEWLINE_) + * regexp = r"}\s*" + tag + r"\s*;" +*/ + __pyx_t_2 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 180, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_CHAR_NEWLINE); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 180, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_3 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_t_5}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_until, __pyx_callargs+__pyx_t_3, (2-__pyx_t_3) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 180, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/feaLib/lexer.py":181 + * tag = tag.strip() + * self.scan_until_(Lexer.CHAR_NEWLINE_) + * self.scan_over_(Lexer.CHAR_NEWLINE_) # <<<<<<<<<<<<<< + * regexp = r"}\s*" + tag + r"\s*;" + * split = re.split(regexp, self.text_[self.pos_ :], maxsplit=1) +*/ + __pyx_t_5 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_5); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 181, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_CHAR_NEWLINE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 181, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_3 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_t_4}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_over, __pyx_callargs+__pyx_t_3, (2-__pyx_t_3) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 181, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/feaLib/lexer.py":182 + * self.scan_until_(Lexer.CHAR_NEWLINE_) + * self.scan_over_(Lexer.CHAR_NEWLINE_) + * regexp = r"}\s*" + tag + r"\s*;" # <<<<<<<<<<<<<< + * split = re.split(regexp, self.text_[self.pos_ :], maxsplit=1) + * if len(split) != 2: +*/ + __pyx_t_1 = PyNumber_Add(__pyx_mstate_global->__pyx_kp_u_s, __pyx_v_tag); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = PyNumber_Add(__pyx_t_1, __pyx_mstate_global->__pyx_kp_u_s_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_regexp = __pyx_t_4; + __pyx_t_4 = 0; + + /* "fontTools/feaLib/lexer.py":183 + * self.scan_over_(Lexer.CHAR_NEWLINE_) + * regexp = r"}\s*" + tag + r"\s*;" + * split = re.split(regexp, self.text_[self.pos_ :], maxsplit=1) # <<<<<<<<<<<<<< + * if len(split) != 2: + * raise FeatureLibError( +*/ + __pyx_t_1 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_re); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_split); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_text_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __Pyx_PyObject_GetSlice(__pyx_t_5, 0, 0, &__pyx_t_6, NULL, NULL, 0, 0, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_3 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_1); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_3 = 0; + } + #endif + { + PyObject *__pyx_callargs[3 + ((CYTHON_VECTORCALL) ? 1 : 0)] = {__pyx_t_1, __pyx_v_regexp, __pyx_t_7}; + __pyx_t_6 = __Pyx_MakeVectorcallBuilderKwds(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_maxsplit, __pyx_mstate_global->__pyx_int_1, __pyx_t_6, __pyx_callargs+3, 0) < (0)) __PYX_ERR(0, 183, __pyx_L1_error) + __pyx_t_4 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_3, (3-__pyx_t_3) | (__pyx_t_3*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_6); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + } + __pyx_v_split = __pyx_t_4; + __pyx_t_4 = 0; + + /* "fontTools/feaLib/lexer.py":184 + * regexp = r"}\s*" + tag + r"\s*;" + * split = re.split(regexp, self.text_[self.pos_ :], maxsplit=1) + * if len(split) != 2: # <<<<<<<<<<<<<< + * raise FeatureLibError( + * "Expected '} %s;' to terminate anonymous block" % tag, location +*/ + __pyx_t_8 = PyObject_Length(__pyx_v_split); if (unlikely(__pyx_t_8 == ((Py_ssize_t)-1))) __PYX_ERR(0, 184, __pyx_L1_error) + __pyx_t_9 = (__pyx_t_8 != 2); + if (unlikely(__pyx_t_9)) { + + /* "fontTools/feaLib/lexer.py":185 + * split = re.split(regexp, self.text_[self.pos_ :], maxsplit=1) + * if len(split) != 2: + * raise FeatureLibError( # <<<<<<<<<<<<<< + * "Expected '} %s;' to terminate anonymous block" % tag, location + * ) +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_FeatureLibError); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 185, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + + /* "fontTools/feaLib/lexer.py":186 + * if len(split) != 2: + * raise FeatureLibError( + * "Expected '} %s;' to terminate anonymous block" % tag, location # <<<<<<<<<<<<<< + * ) + * self.pos_ += len(split[0]) +*/ + __pyx_t_7 = __Pyx_PyUnicode_FormatSafe(__pyx_mstate_global->__pyx_kp_u_Expected_s_to_terminate_anonymou, __pyx_v_tag); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 186, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_3 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_6); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_6, __pyx__function); + __pyx_t_3 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_t_7, __pyx_v_location}; + __pyx_t_4 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_6, __pyx_callargs+__pyx_t_3, (3-__pyx_t_3) | (__pyx_t_3*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 185, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + } + __Pyx_Raise(__pyx_t_4, 0, 0, 0); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __PYX_ERR(0, 185, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":184 + * regexp = r"}\s*" + tag + r"\s*;" + * split = re.split(regexp, self.text_[self.pos_ :], maxsplit=1) + * if len(split) != 2: # <<<<<<<<<<<<<< + * raise FeatureLibError( + * "Expected '} %s;' to terminate anonymous block" % tag, location +*/ + } + + /* "fontTools/feaLib/lexer.py":188 + * "Expected '} %s;' to terminate anonymous block" % tag, location + * ) + * self.pos_ += len(split[0]) # <<<<<<<<<<<<<< + * return (Lexer.ANONYMOUS_BLOCK, split[0], location) + * +*/ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 188, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_6 = __Pyx_GetItemInt(__pyx_v_split, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 188, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_8 = PyObject_Length(__pyx_t_6); if (unlikely(__pyx_t_8 == ((Py_ssize_t)-1))) __PYX_ERR(0, 188, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyLong_FromSsize_t(__pyx_t_8); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 188, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 188, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_pos, __pyx_t_7) < (0)) __PYX_ERR(0, 188, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "fontTools/feaLib/lexer.py":189 + * ) + * self.pos_ += len(split[0]) + * return (Lexer.ANONYMOUS_BLOCK, split[0], location) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 189, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_ANONYMOUS_BLOCK); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 189, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_split, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 189, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 189, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6) != (0)) __PYX_ERR(0, 189, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_7); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_7) != (0)) __PYX_ERR(0, 189, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 189, __pyx_L1_error); + __pyx_t_6 = 0; + __pyx_t_7 = 0; + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":177 + * self.pos_ = p + * + * def scan_anonymous_block(self, tag): # <<<<<<<<<<<<<< + * location = self.location_() + * tag = tag.strip() +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("fontTools.feaLib.lexer.Lexer.scan_anonymous_block", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_location); + __Pyx_XDECREF(__pyx_v_regexp); + __Pyx_XDECREF(__pyx_v_split); + __Pyx_XDECREF(__pyx_v_tag); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/feaLib/lexer.py":207 + * """ + * + * def __init__(self, featurefile, *, includeDir=None): # <<<<<<<<<<<<<< + * """Initializes an IncludingLexer. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_1__init__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_6feaLib_5lexer_14IncludingLexer___init__, "IncludingLexer.__init__(self, featurefile, *, includeDir=None)\n\nInitializes an IncludingLexer.\n\nBehavior:\n If includeDir is passed, it will be used to determine the top-level\n include directory to use for all encountered include statements. If it is\n not passed, ``os.path.dirname(featurefile)`` will be considered the\n include directory."); +static PyMethodDef __pyx_mdef_9fontTools_6feaLib_5lexer_14IncludingLexer_1__init__ = {"__init__", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_1__init__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_6feaLib_5lexer_14IncludingLexer___init__}; +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_1__init__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_featurefile = 0; + PyObject *__pyx_v_includeDir = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_featurefile,&__pyx_mstate_global->__pyx_n_u_includeDir,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 207, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 207, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 207, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "__init__", 0) < (0)) __PYX_ERR(0, 207, __pyx_L3_error) + if (!values[2]) values[2] = __Pyx_NewRef(((PyObject *)Py_None)); + for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, i); __PYX_ERR(0, 207, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 207, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 207, __pyx_L3_error) + if (!values[2]) values[2] = __Pyx_NewRef(((PyObject *)Py_None)); + } + __pyx_v_self = values[0]; + __pyx_v_featurefile = values[1]; + __pyx_v_includeDir = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 207, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.feaLib.lexer.IncludingLexer.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer___init__(__pyx_self, __pyx_v_self, __pyx_v_featurefile, __pyx_v_includeDir); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_featurefile, PyObject *__pyx_v_includeDir) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + size_t __pyx_t_3; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__init__", 0); + + /* "fontTools/feaLib/lexer.py":217 + * """ + * + * self.lexers_ = [self.make_lexer_(featurefile)] # <<<<<<<<<<<<<< + * self.featurefilepath = self.lexers_[0].filename_ + * self.includeDir = includeDir +*/ + __pyx_t_2 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_v_featurefile}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_make_lexer, __pyx_callargs+__pyx_t_3, (2-__pyx_t_3) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 217, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 217, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 217, __pyx_L1_error); + __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_lexers, __pyx_t_2) < (0)) __PYX_ERR(0, 217, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":218 + * + * self.lexers_ = [self.make_lexer_(featurefile)] + * self.featurefilepath = self.lexers_[0].filename_ # <<<<<<<<<<<<<< + * self.includeDir = includeDir + * +*/ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_lexers); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_filename_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_featurefilepath, __pyx_t_2) < (0)) __PYX_ERR(0, 218, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":219 + * self.lexers_ = [self.make_lexer_(featurefile)] + * self.featurefilepath = self.lexers_[0].filename_ + * self.includeDir = includeDir # <<<<<<<<<<<<<< + * + * def __iter__(self): +*/ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_includeDir, __pyx_v_includeDir) < (0)) __PYX_ERR(0, 219, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":207 + * """ + * + * def __init__(self, featurefile, *, includeDir=None): # <<<<<<<<<<<<<< + * """Initializes an IncludingLexer. + * +*/ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("fontTools.feaLib.lexer.IncludingLexer.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/feaLib/lexer.py":221 + * self.includeDir = includeDir + * + * def __iter__(self): # <<<<<<<<<<<<<< + * return self + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_3__iter__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_6feaLib_5lexer_14IncludingLexer_2__iter__, "IncludingLexer.__iter__(self)"); +static PyMethodDef __pyx_mdef_9fontTools_6feaLib_5lexer_14IncludingLexer_3__iter__ = {"__iter__", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_3__iter__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_6feaLib_5lexer_14IncludingLexer_2__iter__}; +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_3__iter__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 221, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 221, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "__iter__", 0) < (0)) __PYX_ERR(0, 221, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("__iter__", 1, 1, 1, i); __PYX_ERR(0, 221, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 221, __pyx_L3_error) + } + __pyx_v_self = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__iter__", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 221, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.feaLib.lexer.IncludingLexer.__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer_2__iter__(__pyx_self, __pyx_v_self); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer_2__iter__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__iter__", 0); + + /* "fontTools/feaLib/lexer.py":222 + * + * def __iter__(self): + * return self # <<<<<<<<<<<<<< + * + * def next(self): # Python 2 +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self); + __pyx_r = __pyx_v_self; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":221 + * self.includeDir = includeDir + * + * def __iter__(self): # <<<<<<<<<<<<<< + * return self + * +*/ + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/feaLib/lexer.py":224 + * return self + * + * def next(self): # Python 2 # <<<<<<<<<<<<<< + * return self.__next__() + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_5next(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_6feaLib_5lexer_14IncludingLexer_4next, "IncludingLexer.next(self)"); +static PyMethodDef __pyx_mdef_9fontTools_6feaLib_5lexer_14IncludingLexer_5next = {"next", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_5next, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_6feaLib_5lexer_14IncludingLexer_4next}; +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_5next(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("next (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 224, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 224, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "next", 0) < (0)) __PYX_ERR(0, 224, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("next", 1, 1, 1, i); __PYX_ERR(0, 224, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 224, __pyx_L3_error) + } + __pyx_v_self = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("next", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 224, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.feaLib.lexer.IncludingLexer.next", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer_4next(__pyx_self, __pyx_v_self); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer_4next(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + size_t __pyx_t_3; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("next", 0); + + /* "fontTools/feaLib/lexer.py":225 + * + * def next(self): # Python 2 + * return self.__next__() # <<<<<<<<<<<<<< + * + * def __next__(self): # Python 3 +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_next, __pyx_callargs+__pyx_t_3, (1-__pyx_t_3) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 225, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":224 + * return self + * + * def next(self): # Python 2 # <<<<<<<<<<<<<< + * return self.__next__() + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("fontTools.feaLib.lexer.IncludingLexer.next", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/feaLib/lexer.py":227 + * return self.__next__() + * + * def __next__(self): # Python 3 # <<<<<<<<<<<<<< + * while self.lexers_: + * lexer = self.lexers_[-1] +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_7__next__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_6feaLib_5lexer_14IncludingLexer_6__next__, "IncludingLexer.__next__(self)"); +static PyMethodDef __pyx_mdef_9fontTools_6feaLib_5lexer_14IncludingLexer_7__next__ = {"__next__", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_7__next__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_6feaLib_5lexer_14IncludingLexer_6__next__}; +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_7__next__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__next__ (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 227, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 227, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "__next__", 0) < (0)) __PYX_ERR(0, 227, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("__next__", 1, 1, 1, i); __PYX_ERR(0, 227, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 227, __pyx_L3_error) + } + __pyx_v_self = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__next__", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 227, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.feaLib.lexer.IncludingLexer.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer_6__next__(__pyx_self, __pyx_v_self); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer_6__next__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_v_lexer = NULL; + PyObject *__pyx_v_token_type = NULL; + PyObject *__pyx_v_token = NULL; + PyObject *__pyx_v_location = NULL; + PyObject *__pyx_v_fname_type = NULL; + PyObject *__pyx_v_fname_token = NULL; + PyObject *__pyx_v_fname_location = NULL; + PyObject *__pyx_v_path = NULL; + PyObject *__pyx_v_curpath = NULL; + PyObject *__pyx_v_err = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *(*__pyx_t_10)(PyObject *); + int __pyx_t_11; + int __pyx_t_12; + size_t __pyx_t_13; + Py_ssize_t __pyx_t_14; + int __pyx_t_15; + PyObject *__pyx_t_16 = NULL; + int __pyx_t_17; + char const *__pyx_t_18; + PyObject *__pyx_t_19 = NULL; + PyObject *__pyx_t_20 = NULL; + PyObject *__pyx_t_21 = NULL; + PyObject *__pyx_t_22 = NULL; + PyObject *__pyx_t_23 = NULL; + PyObject *__pyx_t_24 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__next__", 0); + + /* "fontTools/feaLib/lexer.py":228 + * + * def __next__(self): # Python 3 + * while self.lexers_: # <<<<<<<<<<<<<< + * lexer = self.lexers_[-1] + * try: +*/ + while (1) { + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_lexers); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (!__pyx_t_2) break; + + /* "fontTools/feaLib/lexer.py":229 + * def __next__(self): # Python 3 + * while self.lexers_: + * lexer = self.lexers_[-1] # <<<<<<<<<<<<<< + * try: + * token_type, token, location = next(lexer) +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_lexers); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 229, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, -1L, long, 1, __Pyx_PyLong_From_long, 0, 1, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 229, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_lexer, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/feaLib/lexer.py":230 + * while self.lexers_: + * lexer = self.lexers_[-1] + * try: # <<<<<<<<<<<<<< + * token_type, token, location = next(lexer) + * except StopIteration: +*/ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_6); + /*try:*/ { + + /* "fontTools/feaLib/lexer.py":231 + * lexer = self.lexers_[-1] + * try: + * token_type, token, location = next(lexer) # <<<<<<<<<<<<<< + * except StopIteration: + * self.lexers_.pop() +*/ + __pyx_t_3 = __Pyx_PyIter_Next(__pyx_v_lexer); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 231, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_3); + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 3)) { + if (size > 3) __Pyx_RaiseTooManyValuesError(3); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 231, __pyx_L5_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_7); + __pyx_t_8 = PyTuple_GET_ITEM(sequence, 2); + __Pyx_INCREF(__pyx_t_8); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 231, __pyx_L5_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_7 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 231, __pyx_L5_error) + __Pyx_XGOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_PyList_GetItemRefFast(sequence, 2, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 231, __pyx_L5_error) + __Pyx_XGOTREF(__pyx_t_8); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 231, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_7 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 231, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 231, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_8); + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_9 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 231, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_10 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_9); + index = 0; __pyx_t_1 = __pyx_t_10(__pyx_t_9); if (unlikely(!__pyx_t_1)) goto __pyx_L13_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_7 = __pyx_t_10(__pyx_t_9); if (unlikely(!__pyx_t_7)) goto __pyx_L13_unpacking_failed; + __Pyx_GOTREF(__pyx_t_7); + index = 2; __pyx_t_8 = __pyx_t_10(__pyx_t_9); if (unlikely(!__pyx_t_8)) goto __pyx_L13_unpacking_failed; + __Pyx_GOTREF(__pyx_t_8); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_9), 3) < (0)) __PYX_ERR(0, 231, __pyx_L5_error) + __pyx_t_10 = NULL; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + goto __pyx_L14_unpacking_done; + __pyx_L13_unpacking_failed:; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_10 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 231, __pyx_L5_error) + __pyx_L14_unpacking_done:; + } + __Pyx_XDECREF_SET(__pyx_v_token_type, __pyx_t_1); + __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_token, __pyx_t_7); + __pyx_t_7 = 0; + __Pyx_XDECREF_SET(__pyx_v_location, __pyx_t_8); + __pyx_t_8 = 0; + + /* "fontTools/feaLib/lexer.py":230 + * while self.lexers_: + * lexer = self.lexers_[-1] + * try: # <<<<<<<<<<<<<< + * token_type, token, location = next(lexer) + * except StopIteration: +*/ + } + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + goto __pyx_L12_try_end; + __pyx_L5_error:; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "fontTools/feaLib/lexer.py":232 + * try: + * token_type, token, location = next(lexer) + * except StopIteration: # <<<<<<<<<<<<<< + * self.lexers_.pop() + * continue +*/ + __pyx_t_11 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(((PyTypeObject*)PyExc_StopIteration)))); + if (__pyx_t_11) { + __Pyx_AddTraceback("fontTools.feaLib.lexer.IncludingLexer.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_3, &__pyx_t_8, &__pyx_t_7) < 0) __PYX_ERR(0, 232, __pyx_L7_except_error) + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_8); + __Pyx_XGOTREF(__pyx_t_7); + + /* "fontTools/feaLib/lexer.py":233 + * token_type, token, location = next(lexer) + * except StopIteration: + * self.lexers_.pop() # <<<<<<<<<<<<<< + * continue + * if token_type is Lexer.NAME and token == "include": +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_lexers); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 233, __pyx_L7_except_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_9 = __Pyx_PyObject_Pop(__pyx_t_1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 233, __pyx_L7_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "fontTools/feaLib/lexer.py":234 + * except StopIteration: + * self.lexers_.pop() + * continue # <<<<<<<<<<<<<< + * if token_type is Lexer.NAME and token == "include": + * fname_type, fname_token, fname_location = lexer.next() +*/ + goto __pyx_L15_except_continue; + __pyx_L15_except_continue:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L11_try_continue; + } + goto __pyx_L7_except_error; + + /* "fontTools/feaLib/lexer.py":230 + * while self.lexers_: + * lexer = self.lexers_[-1] + * try: # <<<<<<<<<<<<<< + * token_type, token, location = next(lexer) + * except StopIteration: +*/ + __pyx_L7_except_error:; + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_XGIVEREF(__pyx_t_6); + __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6); + goto __pyx_L1_error; + __pyx_L11_try_continue:; + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_XGIVEREF(__pyx_t_6); + __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6); + goto __pyx_L3_continue; + __pyx_L12_try_end:; + } + + /* "fontTools/feaLib/lexer.py":235 + * self.lexers_.pop() + * continue + * if token_type is Lexer.NAME and token == "include": # <<<<<<<<<<<<<< + * fname_type, fname_token, fname_location = lexer.next() + * if fname_type is not Lexer.FILENAME: +*/ + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 235, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_NAME); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 235, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_12 = (__pyx_v_token_type == __pyx_t_8); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (__pyx_t_12) { + } else { + __pyx_t_2 = __pyx_t_12; + goto __pyx_L18_bool_binop_done; + } + __pyx_t_12 = (__Pyx_PyUnicode_Equals(__pyx_v_token, __pyx_mstate_global->__pyx_n_u_include, Py_EQ)); if (unlikely((__pyx_t_12 < 0))) __PYX_ERR(0, 235, __pyx_L1_error) + __pyx_t_2 = __pyx_t_12; + __pyx_L18_bool_binop_done:; + if (__pyx_t_2) { + + /* "fontTools/feaLib/lexer.py":236 + * continue + * if token_type is Lexer.NAME and token == "include": + * fname_type, fname_token, fname_location = lexer.next() # <<<<<<<<<<<<<< + * if fname_type is not Lexer.FILENAME: + * raise FeatureLibError("Expected file name", fname_location) +*/ + __pyx_t_7 = __pyx_v_lexer; + __Pyx_INCREF(__pyx_t_7); + __pyx_t_13 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_7, NULL}; + __pyx_t_8 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_next_3, __pyx_callargs+__pyx_t_13, (1-__pyx_t_13) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 236, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + } + if ((likely(PyTuple_CheckExact(__pyx_t_8))) || (PyList_CheckExact(__pyx_t_8))) { + PyObject* sequence = __pyx_t_8; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 3)) { + if (size > 3) __Pyx_RaiseTooManyValuesError(3); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 236, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_7 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_7); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_3); + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 2); + __Pyx_INCREF(__pyx_t_9); + } else { + __pyx_t_7 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 236, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_7); + __pyx_t_3 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 236, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_3); + __pyx_t_9 = __Pyx_PyList_GetItemRefFast(sequence, 2, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 236, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_9); + } + #else + __pyx_t_7 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 236, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_3 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 236, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_9 = __Pyx_PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 236, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + #endif + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_1 = PyObject_GetIter(__pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 236, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_10 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); + index = 0; __pyx_t_7 = __pyx_t_10(__pyx_t_1); if (unlikely(!__pyx_t_7)) goto __pyx_L20_unpacking_failed; + __Pyx_GOTREF(__pyx_t_7); + index = 1; __pyx_t_3 = __pyx_t_10(__pyx_t_1); if (unlikely(!__pyx_t_3)) goto __pyx_L20_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 2; __pyx_t_9 = __pyx_t_10(__pyx_t_1); if (unlikely(!__pyx_t_9)) goto __pyx_L20_unpacking_failed; + __Pyx_GOTREF(__pyx_t_9); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_1), 3) < (0)) __PYX_ERR(0, 236, __pyx_L1_error) + __pyx_t_10 = NULL; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + goto __pyx_L21_unpacking_done; + __pyx_L20_unpacking_failed:; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_10 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 236, __pyx_L1_error) + __pyx_L21_unpacking_done:; + } + __Pyx_XDECREF_SET(__pyx_v_fname_type, __pyx_t_7); + __pyx_t_7 = 0; + __Pyx_XDECREF_SET(__pyx_v_fname_token, __pyx_t_3); + __pyx_t_3 = 0; + __Pyx_XDECREF_SET(__pyx_v_fname_location, __pyx_t_9); + __pyx_t_9 = 0; + + /* "fontTools/feaLib/lexer.py":237 + * if token_type is Lexer.NAME and token == "include": + * fname_type, fname_token, fname_location = lexer.next() + * if fname_type is not Lexer.FILENAME: # <<<<<<<<<<<<<< + * raise FeatureLibError("Expected file name", fname_location) + * # semi_type, semi_token, semi_location = lexer.next() +*/ + __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 237, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_FILENAME); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 237, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_2 = (__pyx_v_fname_type != __pyx_t_9); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (unlikely(__pyx_t_2)) { + + /* "fontTools/feaLib/lexer.py":238 + * fname_type, fname_token, fname_location = lexer.next() + * if fname_type is not Lexer.FILENAME: + * raise FeatureLibError("Expected file name", fname_location) # <<<<<<<<<<<<<< + * # semi_type, semi_token, semi_location = lexer.next() + * # if semi_type is not Lexer.SYMBOL or semi_token != ";": +*/ + __pyx_t_8 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_FeatureLibError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_13 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_8); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_13 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_8, __pyx_mstate_global->__pyx_kp_u_Expected_file_name, __pyx_v_fname_location}; + __pyx_t_9 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_13, (3-__pyx_t_13) | (__pyx_t_13*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + } + __Pyx_Raise(__pyx_t_9, 0, 0, 0); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __PYX_ERR(0, 238, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":237 + * if token_type is Lexer.NAME and token == "include": + * fname_type, fname_token, fname_location = lexer.next() + * if fname_type is not Lexer.FILENAME: # <<<<<<<<<<<<<< + * raise FeatureLibError("Expected file name", fname_location) + * # semi_type, semi_token, semi_location = lexer.next() +*/ + } + + /* "fontTools/feaLib/lexer.py":242 + * # if semi_type is not Lexer.SYMBOL or semi_token != ";": + * # raise FeatureLibError("Expected ';'", semi_location) + * if os.path.isabs(fname_token): # <<<<<<<<<<<<<< + * path = fname_token + * else: +*/ + __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_os); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_path); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_3 = __pyx_t_7; + __Pyx_INCREF(__pyx_t_3); + __pyx_t_13 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_fname_token}; + __pyx_t_9 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_isabs, __pyx_callargs+__pyx_t_13, (2-__pyx_t_13) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + } + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 242, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (__pyx_t_2) { + + /* "fontTools/feaLib/lexer.py":243 + * # raise FeatureLibError("Expected ';'", semi_location) + * if os.path.isabs(fname_token): + * path = fname_token # <<<<<<<<<<<<<< + * else: + * if self.includeDir is not None: +*/ + __Pyx_INCREF(__pyx_v_fname_token); + __Pyx_XDECREF_SET(__pyx_v_path, __pyx_v_fname_token); + + /* "fontTools/feaLib/lexer.py":242 + * # if semi_type is not Lexer.SYMBOL or semi_token != ";": + * # raise FeatureLibError("Expected ';'", semi_location) + * if os.path.isabs(fname_token): # <<<<<<<<<<<<<< + * path = fname_token + * else: +*/ + goto __pyx_L23; + } + + /* "fontTools/feaLib/lexer.py":245 + * path = fname_token + * else: + * if self.includeDir is not None: # <<<<<<<<<<<<<< + * curpath = self.includeDir + * elif self.featurefilepath is not None: +*/ + /*else*/ { + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_includeDir); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_2 = (__pyx_t_9 != Py_None); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (__pyx_t_2) { + + /* "fontTools/feaLib/lexer.py":246 + * else: + * if self.includeDir is not None: + * curpath = self.includeDir # <<<<<<<<<<<<<< + * elif self.featurefilepath is not None: + * curpath = os.path.dirname(self.featurefilepath) +*/ + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_includeDir); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 246, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_XDECREF_SET(__pyx_v_curpath, __pyx_t_9); + __pyx_t_9 = 0; + + /* "fontTools/feaLib/lexer.py":245 + * path = fname_token + * else: + * if self.includeDir is not None: # <<<<<<<<<<<<<< + * curpath = self.includeDir + * elif self.featurefilepath is not None: +*/ + goto __pyx_L24; + } + + /* "fontTools/feaLib/lexer.py":247 + * if self.includeDir is not None: + * curpath = self.includeDir + * elif self.featurefilepath is not None: # <<<<<<<<<<<<<< + * curpath = os.path.dirname(self.featurefilepath) + * else: +*/ + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_featurefilepath); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 247, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_2 = (__pyx_t_9 != Py_None); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (__pyx_t_2) { + + /* "fontTools/feaLib/lexer.py":248 + * curpath = self.includeDir + * elif self.featurefilepath is not None: + * curpath = os.path.dirname(self.featurefilepath) # <<<<<<<<<<<<<< + * else: + * # if the IncludingLexer was initialized from an in-memory +*/ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_os); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 248, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_path); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 248, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = __pyx_t_8; + __Pyx_INCREF(__pyx_t_7); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_featurefilepath); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 248, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_13 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_7, __pyx_t_3}; + __pyx_t_9 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_dirname, __pyx_callargs+__pyx_t_13, (2-__pyx_t_13) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 248, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + } + __Pyx_XDECREF_SET(__pyx_v_curpath, __pyx_t_9); + __pyx_t_9 = 0; + + /* "fontTools/feaLib/lexer.py":247 + * if self.includeDir is not None: + * curpath = self.includeDir + * elif self.featurefilepath is not None: # <<<<<<<<<<<<<< + * curpath = os.path.dirname(self.featurefilepath) + * else: +*/ + goto __pyx_L24; + } + + /* "fontTools/feaLib/lexer.py":254 + * # its filesystem path, therefore we fall back to using the + * # current working directory to resolve relative includes + * curpath = os.getcwd() # <<<<<<<<<<<<<< + * path = os.path.join(curpath, fname_token) + * if len(self.lexers_) >= 5: +*/ + /*else*/ { + __pyx_t_8 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_os); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 254, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_getcwd); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 254, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_13 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7); + assert(__pyx_t_8); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_7, __pyx__function); + __pyx_t_13 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_8, NULL}; + __pyx_t_9 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_7, __pyx_callargs+__pyx_t_13, (1-__pyx_t_13) | (__pyx_t_13*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 254, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + } + __Pyx_XDECREF_SET(__pyx_v_curpath, __pyx_t_9); + __pyx_t_9 = 0; + } + __pyx_L24:; + + /* "fontTools/feaLib/lexer.py":255 + * # current working directory to resolve relative includes + * curpath = os.getcwd() + * path = os.path.join(curpath, fname_token) # <<<<<<<<<<<<<< + * if len(self.lexers_) >= 5: + * raise FeatureLibError("Too many recursive includes", fname_location) +*/ + __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_os); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 255, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_path); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 255, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_7 = __pyx_t_3; + __Pyx_INCREF(__pyx_t_7); + __pyx_t_13 = 0; + { + PyObject *__pyx_callargs[3] = {__pyx_t_7, __pyx_v_curpath, __pyx_v_fname_token}; + __pyx_t_9 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_join, __pyx_callargs+__pyx_t_13, (3-__pyx_t_13) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 255, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + } + __Pyx_XDECREF_SET(__pyx_v_path, __pyx_t_9); + __pyx_t_9 = 0; + } + __pyx_L23:; + + /* "fontTools/feaLib/lexer.py":256 + * curpath = os.getcwd() + * path = os.path.join(curpath, fname_token) + * if len(self.lexers_) >= 5: # <<<<<<<<<<<<<< + * raise FeatureLibError("Too many recursive includes", fname_location) + * try: +*/ + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_lexers); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 256, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_14 = PyObject_Length(__pyx_t_9); if (unlikely(__pyx_t_14 == ((Py_ssize_t)-1))) __PYX_ERR(0, 256, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_2 = (__pyx_t_14 >= 5); + if (unlikely(__pyx_t_2)) { + + /* "fontTools/feaLib/lexer.py":257 + * path = os.path.join(curpath, fname_token) + * if len(self.lexers_) >= 5: + * raise FeatureLibError("Too many recursive includes", fname_location) # <<<<<<<<<<<<<< + * try: + * self.lexers_.append(self.make_lexer_(path)) +*/ + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_FeatureLibError); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 257, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_13 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_7); + assert(__pyx_t_3); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_7, __pyx__function); + __pyx_t_13 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_mstate_global->__pyx_kp_u_Too_many_recursive_includes, __pyx_v_fname_location}; + __pyx_t_9 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_7, __pyx_callargs+__pyx_t_13, (3-__pyx_t_13) | (__pyx_t_13*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 257, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + } + __Pyx_Raise(__pyx_t_9, 0, 0, 0); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __PYX_ERR(0, 257, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":256 + * curpath = os.getcwd() + * path = os.path.join(curpath, fname_token) + * if len(self.lexers_) >= 5: # <<<<<<<<<<<<<< + * raise FeatureLibError("Too many recursive includes", fname_location) + * try: +*/ + } + + /* "fontTools/feaLib/lexer.py":258 + * if len(self.lexers_) >= 5: + * raise FeatureLibError("Too many recursive includes", fname_location) + * try: # <<<<<<<<<<<<<< + * self.lexers_.append(self.make_lexer_(path)) + * except FileNotFoundError as err: +*/ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_4); + /*try:*/ { + + /* "fontTools/feaLib/lexer.py":259 + * raise FeatureLibError("Too many recursive includes", fname_location) + * try: + * self.lexers_.append(self.make_lexer_(path)) # <<<<<<<<<<<<<< + * except FileNotFoundError as err: + * raise IncludedFeaNotFound(fname_token, fname_location) from err +*/ + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_lexers); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 259, __pyx_L26_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_3 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_3); + __pyx_t_13 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_path}; + __pyx_t_7 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_make_lexer, __pyx_callargs+__pyx_t_13, (2-__pyx_t_13) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 259, __pyx_L26_error) + __Pyx_GOTREF(__pyx_t_7); + } + __pyx_t_15 = __Pyx_PyObject_Append(__pyx_t_9, __pyx_t_7); if (unlikely(__pyx_t_15 == ((int)-1))) __PYX_ERR(0, 259, __pyx_L26_error) + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "fontTools/feaLib/lexer.py":258 + * if len(self.lexers_) >= 5: + * raise FeatureLibError("Too many recursive includes", fname_location) + * try: # <<<<<<<<<<<<<< + * self.lexers_.append(self.make_lexer_(path)) + * except FileNotFoundError as err: +*/ + } + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L33_try_end; + __pyx_L26_error:; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "fontTools/feaLib/lexer.py":260 + * try: + * self.lexers_.append(self.make_lexer_(path)) + * except FileNotFoundError as err: # <<<<<<<<<<<<<< + * raise IncludedFeaNotFound(fname_token, fname_location) from err + * else: +*/ + __pyx_t_11 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(((PyTypeObject*)PyExc_FileNotFoundError)))); + if (__pyx_t_11) { + __Pyx_AddTraceback("fontTools.feaLib.lexer.IncludingLexer.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_9, &__pyx_t_3) < 0) __PYX_ERR(0, 260, __pyx_L28_except_error) + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_9); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_9); + __pyx_v_err = __pyx_t_9; + /*try:*/ { + + /* "fontTools/feaLib/lexer.py":261 + * self.lexers_.append(self.make_lexer_(path)) + * except FileNotFoundError as err: + * raise IncludedFeaNotFound(fname_token, fname_location) from err # <<<<<<<<<<<<<< + * else: + * return (token_type, token, location) +*/ + __pyx_t_1 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_16, __pyx_mstate_global->__pyx_n_u_IncludedFeaNotFound); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 261, __pyx_L39_error) + __Pyx_GOTREF(__pyx_t_16); + __pyx_t_13 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_16))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_16); + assert(__pyx_t_1); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_16); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_16, __pyx__function); + __pyx_t_13 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_1, __pyx_v_fname_token, __pyx_v_fname_location}; + __pyx_t_8 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_16, __pyx_callargs+__pyx_t_13, (3-__pyx_t_13) | (__pyx_t_13*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0; + if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 261, __pyx_L39_error) + __Pyx_GOTREF(__pyx_t_8); + } + __Pyx_Raise(__pyx_t_8, 0, 0, __pyx_v_err); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __PYX_ERR(0, 261, __pyx_L39_error) + } + + /* "fontTools/feaLib/lexer.py":260 + * try: + * self.lexers_.append(self.make_lexer_(path)) + * except FileNotFoundError as err: # <<<<<<<<<<<<<< + * raise IncludedFeaNotFound(fname_token, fname_location) from err + * else: +*/ + /*finally:*/ { + __pyx_L39_error:; + /*exception exit:*/{ + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0; __pyx_t_24 = 0; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_ExceptionSwap(&__pyx_t_22, &__pyx_t_23, &__pyx_t_24); + if ( unlikely(__Pyx_GetException(&__pyx_t_19, &__pyx_t_20, &__pyx_t_21) < 0)) __Pyx_ErrFetch(&__pyx_t_19, &__pyx_t_20, &__pyx_t_21); + __Pyx_XGOTREF(__pyx_t_19); + __Pyx_XGOTREF(__pyx_t_20); + __Pyx_XGOTREF(__pyx_t_21); + __Pyx_XGOTREF(__pyx_t_22); + __Pyx_XGOTREF(__pyx_t_23); + __Pyx_XGOTREF(__pyx_t_24); + __pyx_t_11 = __pyx_lineno; __pyx_t_17 = __pyx_clineno; __pyx_t_18 = __pyx_filename; + { + __Pyx_DECREF(__pyx_v_err); __pyx_v_err = 0; + } + __Pyx_XGIVEREF(__pyx_t_22); + __Pyx_XGIVEREF(__pyx_t_23); + __Pyx_XGIVEREF(__pyx_t_24); + __Pyx_ExceptionReset(__pyx_t_22, __pyx_t_23, __pyx_t_24); + __Pyx_XGIVEREF(__pyx_t_19); + __Pyx_XGIVEREF(__pyx_t_20); + __Pyx_XGIVEREF(__pyx_t_21); + __Pyx_ErrRestore(__pyx_t_19, __pyx_t_20, __pyx_t_21); + __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0; __pyx_t_24 = 0; + __pyx_lineno = __pyx_t_11; __pyx_clineno = __pyx_t_17; __pyx_filename = __pyx_t_18; + goto __pyx_L28_except_error; + } + } + } + goto __pyx_L28_except_error; + + /* "fontTools/feaLib/lexer.py":258 + * if len(self.lexers_) >= 5: + * raise FeatureLibError("Too many recursive includes", fname_location) + * try: # <<<<<<<<<<<<<< + * self.lexers_.append(self.make_lexer_(path)) + * except FileNotFoundError as err: +*/ + __pyx_L28_except_error:; + __Pyx_XGIVEREF(__pyx_t_6); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_6, __pyx_t_5, __pyx_t_4); + goto __pyx_L1_error; + __pyx_L33_try_end:; + } + + /* "fontTools/feaLib/lexer.py":235 + * self.lexers_.pop() + * continue + * if token_type is Lexer.NAME and token == "include": # <<<<<<<<<<<<<< + * fname_type, fname_token, fname_location = lexer.next() + * if fname_type is not Lexer.FILENAME: +*/ + goto __pyx_L17; + } + + /* "fontTools/feaLib/lexer.py":263 + * raise IncludedFeaNotFound(fname_token, fname_location) from err + * else: + * return (token_type, token, location) # <<<<<<<<<<<<<< + * raise StopIteration() + * +*/ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 263, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_token_type); + __Pyx_GIVEREF(__pyx_v_token_type); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_token_type) != (0)) __PYX_ERR(0, 263, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_token); + __Pyx_GIVEREF(__pyx_v_token); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_token) != (0)) __PYX_ERR(0, 263, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_location); + __Pyx_GIVEREF(__pyx_v_location); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_location) != (0)) __PYX_ERR(0, 263, __pyx_L1_error); + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + } + __pyx_L17:; + __pyx_L3_continue:; + } + + /* "fontTools/feaLib/lexer.py":264 + * else: + * return (token_type, token, location) + * raise StopIteration() # <<<<<<<<<<<<<< + * + * @staticmethod +*/ + __pyx_t_9 = NULL; + __pyx_t_13 = 1; + { + PyObject *__pyx_callargs[2] = {__pyx_t_9, NULL}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)(((PyTypeObject*)PyExc_StopIteration)), __pyx_callargs+__pyx_t_13, (1-__pyx_t_13) | (__pyx_t_13*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 264, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 264, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":227 + * return self.__next__() + * + * def __next__(self): # Python 3 # <<<<<<<<<<<<<< + * while self.lexers_: + * lexer = self.lexers_[-1] +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_16); + __Pyx_AddTraceback("fontTools.feaLib.lexer.IncludingLexer.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_lexer); + __Pyx_XDECREF(__pyx_v_token_type); + __Pyx_XDECREF(__pyx_v_token); + __Pyx_XDECREF(__pyx_v_location); + __Pyx_XDECREF(__pyx_v_fname_type); + __Pyx_XDECREF(__pyx_v_fname_token); + __Pyx_XDECREF(__pyx_v_fname_location); + __Pyx_XDECREF(__pyx_v_path); + __Pyx_XDECREF(__pyx_v_curpath); + __Pyx_XDECREF(__pyx_v_err); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/feaLib/lexer.py":266 + * raise StopIteration() + * + * @staticmethod # <<<<<<<<<<<<<< + * def make_lexer_(file_or_path): + * if hasattr(file_or_path, "read"): +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_9make_lexer_(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_6feaLib_5lexer_14IncludingLexer_8make_lexer_, "IncludingLexer.make_lexer_(file_or_path)"); +static PyMethodDef __pyx_mdef_9fontTools_6feaLib_5lexer_14IncludingLexer_9make_lexer_ = {"make_lexer_", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_9make_lexer_, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_6feaLib_5lexer_14IncludingLexer_8make_lexer_}; +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_9make_lexer_(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_file_or_path = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("make_lexer_ (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_file_or_path,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 266, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 266, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "make_lexer_", 0) < (0)) __PYX_ERR(0, 266, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("make_lexer_", 1, 1, 1, i); __PYX_ERR(0, 266, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 266, __pyx_L3_error) + } + __pyx_v_file_or_path = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("make_lexer_", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 266, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.feaLib.lexer.IncludingLexer.make_lexer_", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer_8make_lexer_(__pyx_self, __pyx_v_file_or_path); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer_8make_lexer_(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_file_or_path) { + PyObject *__pyx_v_fileobj = NULL; + int __pyx_v_closing; + PyObject *__pyx_v_filename = NULL; + PyObject *__pyx_v_data = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + size_t __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("make_lexer_", 0); + + /* "fontTools/feaLib/lexer.py":268 + * @staticmethod + * def make_lexer_(file_or_path): + * if hasattr(file_or_path, "read"): # <<<<<<<<<<<<<< + * fileobj, closing = file_or_path, False + * else: +*/ + __pyx_t_1 = __Pyx_HasAttr(__pyx_v_file_or_path, __pyx_mstate_global->__pyx_n_u_read); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 268, __pyx_L1_error) + if (__pyx_t_1) { + + /* "fontTools/feaLib/lexer.py":269 + * def make_lexer_(file_or_path): + * if hasattr(file_or_path, "read"): + * fileobj, closing = file_or_path, False # <<<<<<<<<<<<<< + * else: + * filename, closing = file_or_path, True +*/ + __pyx_t_2 = __pyx_v_file_or_path; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = 0; + __pyx_v_fileobj = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_closing = __pyx_t_1; + + /* "fontTools/feaLib/lexer.py":268 + * @staticmethod + * def make_lexer_(file_or_path): + * if hasattr(file_or_path, "read"): # <<<<<<<<<<<<<< + * fileobj, closing = file_or_path, False + * else: +*/ + goto __pyx_L3; + } + + /* "fontTools/feaLib/lexer.py":271 + * fileobj, closing = file_or_path, False + * else: + * filename, closing = file_or_path, True # <<<<<<<<<<<<<< + * fileobj = open(filename, "r", encoding="utf-8-sig") + * data = fileobj.read() +*/ + /*else*/ { + __pyx_t_2 = __pyx_v_file_or_path; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = 1; + __pyx_v_filename = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_closing = __pyx_t_1; + + /* "fontTools/feaLib/lexer.py":272 + * else: + * filename, closing = file_or_path, True + * fileobj = open(filename, "r", encoding="utf-8-sig") # <<<<<<<<<<<<<< + * data = fileobj.read() + * filename = getattr(fileobj, "name", None) +*/ + __pyx_t_3 = NULL; + __pyx_t_4 = 1; + { + PyObject *__pyx_callargs[3 + ((CYTHON_VECTORCALL) ? 1 : 0)] = {__pyx_t_3, __pyx_v_filename, __pyx_mstate_global->__pyx_n_u_r}; + __pyx_t_5 = __Pyx_MakeVectorcallBuilderKwds(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 272, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_encoding, __pyx_mstate_global->__pyx_kp_u_utf_8_sig, __pyx_t_5, __pyx_callargs+3, 0) < (0)) __PYX_ERR(0, 272, __pyx_L1_error) + __pyx_t_2 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_builtin_open, __pyx_callargs+__pyx_t_4, (3-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_5); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 272, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __pyx_v_fileobj = __pyx_t_2; + __pyx_t_2 = 0; + } + __pyx_L3:; + + /* "fontTools/feaLib/lexer.py":273 + * filename, closing = file_or_path, True + * fileobj = open(filename, "r", encoding="utf-8-sig") + * data = fileobj.read() # <<<<<<<<<<<<<< + * filename = getattr(fileobj, "name", None) + * if closing: +*/ + __pyx_t_5 = __pyx_v_fileobj; + __Pyx_INCREF(__pyx_t_5); + __pyx_t_4 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_5, NULL}; + __pyx_t_2 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_read, __pyx_callargs+__pyx_t_4, (1-__pyx_t_4) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 273, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __pyx_v_data = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":274 + * fileobj = open(filename, "r", encoding="utf-8-sig") + * data = fileobj.read() + * filename = getattr(fileobj, "name", None) # <<<<<<<<<<<<<< + * if closing: + * fileobj.close() +*/ + __pyx_t_2 = __Pyx_GetAttr3(__pyx_v_fileobj, __pyx_mstate_global->__pyx_n_u_name, Py_None); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 274, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_v_filename, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":275 + * data = fileobj.read() + * filename = getattr(fileobj, "name", None) + * if closing: # <<<<<<<<<<<<<< + * fileobj.close() + * return Lexer(data, filename) +*/ + if (__pyx_v_closing) { + + /* "fontTools/feaLib/lexer.py":276 + * filename = getattr(fileobj, "name", None) + * if closing: + * fileobj.close() # <<<<<<<<<<<<<< + * return Lexer(data, filename) + * +*/ + __pyx_t_5 = __pyx_v_fileobj; + __Pyx_INCREF(__pyx_t_5); + __pyx_t_4 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_5, NULL}; + __pyx_t_2 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_close, __pyx_callargs+__pyx_t_4, (1-__pyx_t_4) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 276, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":275 + * data = fileobj.read() + * filename = getattr(fileobj, "name", None) + * if closing: # <<<<<<<<<<<<<< + * fileobj.close() + * return Lexer(data, filename) +*/ + } + + /* "fontTools/feaLib/lexer.py":277 + * if closing: + * fileobj.close() + * return Lexer(data, filename) # <<<<<<<<<<<<<< + * + * def scan_anonymous_block(self, tag): +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_5 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_Lexer); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 277, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_5); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_5, __pyx_v_data, __pyx_v_filename}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_4, (3-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 277, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":266 + * raise StopIteration() + * + * @staticmethod # <<<<<<<<<<<<<< + * def make_lexer_(file_or_path): + * if hasattr(file_or_path, "read"): +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.feaLib.lexer.IncludingLexer.make_lexer_", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_fileobj); + __Pyx_XDECREF(__pyx_v_filename); + __Pyx_XDECREF(__pyx_v_data); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/feaLib/lexer.py":279 + * return Lexer(data, filename) + * + * def scan_anonymous_block(self, tag): # <<<<<<<<<<<<<< + * return self.lexers_[-1].scan_anonymous_block(tag) + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_11scan_anonymous_block(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_6feaLib_5lexer_14IncludingLexer_10scan_anonymous_block, "IncludingLexer.scan_anonymous_block(self, tag)"); +static PyMethodDef __pyx_mdef_9fontTools_6feaLib_5lexer_14IncludingLexer_11scan_anonymous_block = {"scan_anonymous_block", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_11scan_anonymous_block, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_6feaLib_5lexer_14IncludingLexer_10scan_anonymous_block}; +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_14IncludingLexer_11scan_anonymous_block(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_tag = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("scan_anonymous_block (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_tag,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 279, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 279, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 279, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "scan_anonymous_block", 0) < (0)) __PYX_ERR(0, 279, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("scan_anonymous_block", 1, 2, 2, i); __PYX_ERR(0, 279, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 279, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 279, __pyx_L3_error) + } + __pyx_v_self = values[0]; + __pyx_v_tag = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("scan_anonymous_block", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 279, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.feaLib.lexer.IncludingLexer.scan_anonymous_block", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer_10scan_anonymous_block(__pyx_self, __pyx_v_self, __pyx_v_tag); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_14IncludingLexer_10scan_anonymous_block(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_tag) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + size_t __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("scan_anonymous_block", 0); + + /* "fontTools/feaLib/lexer.py":280 + * + * def scan_anonymous_block(self, tag): + * return self.lexers_[-1].scan_anonymous_block(tag) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_lexers); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 280, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_3, -1L, long, 1, __Pyx_PyLong_From_long, 0, 1, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 280, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_2 = __pyx_t_4; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_5 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_v_tag}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_anonymous_block, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 280, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":279 + * return Lexer(data, filename) + * + * def scan_anonymous_block(self, tag): # <<<<<<<<<<<<<< + * return self.lexers_[-1].scan_anonymous_block(tag) + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("fontTools.feaLib.lexer.IncludingLexer.scan_anonymous_block", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/feaLib/lexer.py":286 + * """Lexer that does not follow `include` statements, emits them as-is.""" + * + * def __next__(self): # Python 3 # <<<<<<<<<<<<<< + * return next(self.lexers_[0]) +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_17NonIncludingLexer_1__next__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_6feaLib_5lexer_17NonIncludingLexer___next__, "NonIncludingLexer.__next__(self)"); +static PyMethodDef __pyx_mdef_9fontTools_6feaLib_5lexer_17NonIncludingLexer_1__next__ = {"__next__", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_6feaLib_5lexer_17NonIncludingLexer_1__next__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_6feaLib_5lexer_17NonIncludingLexer___next__}; +static PyObject *__pyx_pw_9fontTools_6feaLib_5lexer_17NonIncludingLexer_1__next__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__next__ (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 286, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 286, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "__next__", 0) < (0)) __PYX_ERR(0, 286, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("__next__", 1, 1, 1, i); __PYX_ERR(0, 286, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 286, __pyx_L3_error) + } + __pyx_v_self = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__next__", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 286, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.feaLib.lexer.NonIncludingLexer.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_6feaLib_5lexer_17NonIncludingLexer___next__(__pyx_self, __pyx_v_self); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_6feaLib_5lexer_17NonIncludingLexer___next__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__next__", 0); + + /* "fontTools/feaLib/lexer.py":287 + * + * def __next__(self): # Python 3 + * return next(self.lexers_[0]) # <<<<<<<<<<<<<< +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_lexers); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 287, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 287, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyIter_Next(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 287, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/feaLib/lexer.py":286 + * """Lexer that does not follow `include` statements, emits them as-is.""" + * + * def __next__(self): # Python 3 # <<<<<<<<<<<<<< + * return next(self.lexers_[0]) +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("fontTools.feaLib.lexer.NonIncludingLexer.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +/* #### Code section: module_exttypes ### */ + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; +/* #### Code section: initfunc_declarations ### */ +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_CreateCodeObjects(__pyx_mstatetype *__pyx_mstate); /*proto*/ +/* #### Code section: init_module ### */ + +static int __Pyx_modinit_global_init_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_import_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_import_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec_lexer(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec_lexer}, + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + {Py_mod_gil, Py_MOD_GIL_USED}, + #endif + #if PY_VERSION_HEX >= 0x030C0000 && CYTHON_USE_MODULE_STATE + {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED}, + #endif + {0, NULL} +}; +#endif + +#ifdef __cplusplus +namespace { + struct PyModuleDef __pyx_moduledef = + #else + static struct PyModuleDef __pyx_moduledef = + #endif + { + PyModuleDef_HEAD_INIT, + "lexer", + 0, /* m_doc */ + #if CYTHON_USE_MODULE_STATE + sizeof(__pyx_mstatetype), /* m_size */ + #else + (CYTHON_PEP489_MULTI_PHASE_INIT) ? 0 : -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + #if CYTHON_USE_MODULE_STATE + __pyx_m_traverse, /* m_traverse */ + __pyx_m_clear, /* m_clear */ + NULL /* m_free */ + #else + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ + #endif + }; + #ifdef __cplusplus +} /* anonymous namespace */ +#endif + +/* PyModInitFuncType */ +#ifndef CYTHON_NO_PYINIT_EXPORT + #define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#else + #ifdef __cplusplus + #define __Pyx_PyMODINIT_FUNC extern "C" PyObject * + #else + #define __Pyx_PyMODINIT_FUNC PyObject * + #endif +#endif + +__Pyx_PyMODINIT_FUNC PyInit_lexer(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit_lexer(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +/* ModuleCreationPEP489 */ +#if CYTHON_COMPILING_IN_LIMITED_API && (__PYX_LIMITED_VERSION_HEX < 0x03090000\ + || ((defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS)) && __PYX_LIMITED_VERSION_HEX < 0x030A0000)) +static PY_INT64_T __Pyx_GetCurrentInterpreterId(void) { + { + PyObject *module = PyImport_ImportModule("_interpreters"); // 3.13+ I think + if (!module) { + PyErr_Clear(); // just try the 3.8-3.12 version + module = PyImport_ImportModule("_xxsubinterpreters"); + if (!module) goto bad; + } + PyObject *current = PyObject_CallMethod(module, "get_current", NULL); + Py_DECREF(module); + if (!current) goto bad; + if (PyTuple_Check(current)) { + PyObject *new_current = PySequence_GetItem(current, 0); + Py_DECREF(current); + current = new_current; + if (!new_current) goto bad; + } + long long as_c_int = PyLong_AsLongLong(current); + Py_DECREF(current); + return as_c_int; + } + bad: + PySys_WriteStderr("__Pyx_GetCurrentInterpreterId failed. Try setting the C define CYTHON_PEP489_MULTI_PHASE_INIT=0\n"); + return -1; +} +#endif +#if !CYTHON_USE_MODULE_STATE +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + static PY_INT64_T main_interpreter_id = -1; +#if CYTHON_COMPILING_IN_GRAAL && defined(GRAALPY_VERSION_NUM) && GRAALPY_VERSION_NUM > 0x19000000 + PY_INT64_T current_id = GraalPyInterpreterState_GetIDFromThreadState(PyThreadState_Get()); +#elif CYTHON_COMPILING_IN_GRAAL + PY_INT64_T current_id = PyInterpreterState_GetIDFromThreadState(PyThreadState_Get()); +#elif CYTHON_COMPILING_IN_LIMITED_API && (__PYX_LIMITED_VERSION_HEX < 0x03090000\ + || ((defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS)) && __PYX_LIMITED_VERSION_HEX < 0x030A0000)) + PY_INT64_T current_id = __Pyx_GetCurrentInterpreterId(); +#elif CYTHON_COMPILING_IN_LIMITED_API + PY_INT64_T current_id = PyInterpreterState_GetID(PyInterpreterState_Get()); +#else + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); +#endif + if (unlikely(current_id == -1)) { + return -1; + } + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return 0; + } else if (unlikely(main_interpreter_id != current_id)) { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +#endif +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) +{ + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + CYTHON_UNUSED_VAR(def); + #if !CYTHON_USE_MODULE_STATE + if (__Pyx_check_single_interpreter()) + return NULL; + #endif + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec_lexer(PyObject *__pyx_pyinit_module) +#endif +{ + int stringtab_initialized = 0; + #if CYTHON_USE_MODULE_STATE + int pystate_addmodule_run = 0; + #endif + __pyx_mstatetype *__pyx_mstate = NULL; + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + Py_ssize_t __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + size_t __pyx_t_12; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module 'lexer' has already been imported. Re-initialisation is not supported."); + return -1; + } + #else + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_t_1 = __pyx_pyinit_module; + Py_INCREF(__pyx_t_1); + #else + __pyx_t_1 = PyModule_Create(&__pyx_moduledef); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #if CYTHON_USE_MODULE_STATE + { + int add_module_result = __Pyx_State_AddModule(__pyx_t_1, &__pyx_moduledef); + __pyx_t_1 = 0; /* transfer ownership from __pyx_t_1 to "lexer" pseudovariable */ + if (unlikely((add_module_result < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + pystate_addmodule_run = 1; + } + #else + __pyx_m = __pyx_t_1; + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + PyUnstable_Module_SetGIL(__pyx_m, Py_MOD_GIL_USED); + #endif + __pyx_mstate = __pyx_mstate_global; + CYTHON_UNUSED_VAR(__pyx_t_1); + __pyx_mstate->__pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_mstate->__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_mstate->__pyx_d); + __pyx_mstate->__pyx_b = __Pyx_PyImport_AddModuleRef(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_mstate->__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_cython_runtime = __Pyx_PyImport_AddModuleRef("cython_runtime"); if (unlikely(!__pyx_mstate->__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_mstate->__pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /* ImportRefnannyAPI */ + #if CYTHON_REFNANNY + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); + if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); + } + #endif + +__Pyx_RefNannySetupContext("PyInit_lexer", 0); + __Pyx_init_runtime_version(); + if (__Pyx_check_binary_version(__PYX_LIMITED_VERSION_HEX, __Pyx_get_runtime_version(), CYTHON_COMPILING_IN_LIMITED_API) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_mstate->__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_mstate->__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_mstate->__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Library function declarations ---*/ + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitConstants(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + stringtab_initialized = 1; + if (__Pyx_InitGlobals() < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (__pyx_module_is_main_fontTools__feaLib__lexer) { + if (PyObject_SetAttr(__pyx_m, __pyx_mstate_global->__pyx_n_u_name_2, __pyx_mstate_global->__pyx_n_u_main) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + } + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "fontTools.feaLib.lexer")) { + if (unlikely((PyDict_SetItemString(modules, "fontTools.feaLib.lexer", __pyx_m) < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (__Pyx_CreateCodeObjects(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(__pyx_mstate); + (void)__Pyx_modinit_variable_export_code(__pyx_mstate); + (void)__Pyx_modinit_function_export_code(__pyx_mstate); + (void)__Pyx_modinit_type_init_code(__pyx_mstate); + (void)__Pyx_modinit_type_import_code(__pyx_mstate); + (void)__Pyx_modinit_variable_import_code(__pyx_mstate); + (void)__Pyx_modinit_function_import_code(__pyx_mstate); + /*--- Execution code ---*/ + + /* "fontTools/feaLib/lexer.py":1 + * from fontTools.feaLib.error import FeatureLibError, IncludedFeaNotFound # <<<<<<<<<<<<<< + * from fontTools.feaLib.location import FeatureLibLocation + * import re +*/ + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_FeatureLibError,__pyx_mstate_global->__pyx_n_u_IncludedFeaNotFound}; + __pyx_t_1 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_fontTools_feaLib_error, __pyx_imported_names, 2, NULL, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + } + __pyx_t_2 = __pyx_t_1; + __Pyx_GOTREF(__pyx_t_2); + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_FeatureLibError,__pyx_mstate_global->__pyx_n_u_IncludedFeaNotFound}; + for (__pyx_t_3=0; __pyx_t_3 < 2; __pyx_t_3++) { + __pyx_t_4 = __Pyx_ImportFrom(__pyx_t_2, __pyx_imported_names[__pyx_t_3]); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_imported_names[__pyx_t_3], __pyx_t_4) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":2 + * from fontTools.feaLib.error import FeatureLibError, IncludedFeaNotFound + * from fontTools.feaLib.location import FeatureLibLocation # <<<<<<<<<<<<<< + * import re + * import os +*/ + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_FeatureLibLocation}; + __pyx_t_1 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_fontTools_feaLib_location, __pyx_imported_names, 1, NULL, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2, __pyx_L1_error) + } + __pyx_t_2 = __pyx_t_1; + __Pyx_GOTREF(__pyx_t_2); + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_FeatureLibLocation}; + __pyx_t_3 = 0; { + __pyx_t_4 = __Pyx_ImportFrom(__pyx_t_2, __pyx_imported_names[__pyx_t_3]); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_imported_names[__pyx_t_3], __pyx_t_4) < (0)) __PYX_ERR(0, 2, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":3 + * from fontTools.feaLib.error import FeatureLibError, IncludedFeaNotFound + * from fontTools.feaLib.location import FeatureLibLocation + * import re # <<<<<<<<<<<<<< + * import os + * +*/ + __pyx_t_1 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_re, 0, 0, NULL, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3, __pyx_L1_error) + __pyx_t_2 = __pyx_t_1; + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_re, __pyx_t_2) < (0)) __PYX_ERR(0, 3, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":4 + * from fontTools.feaLib.location import FeatureLibLocation + * import re + * import os # <<<<<<<<<<<<<< + * + * try: +*/ + __pyx_t_1 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_os, 0, 0, NULL, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error) + __pyx_t_2 = __pyx_t_1; + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_os, __pyx_t_2) < (0)) __PYX_ERR(0, 4, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":6 + * import os + * + * try: # <<<<<<<<<<<<<< + * import cython + * except ImportError: +*/ + { + (void)__pyx_t_1; (void)__pyx_t_5; (void)__pyx_t_6; /* mark used */ + /*try:*/ { + + /* "fontTools/feaLib/lexer.py":7 + * + * try: + * import cython # <<<<<<<<<<<<<< + * except ImportError: + * # if cython not installed, use mock module with no-op decorators and types +*/ + } + } + + /* "fontTools/feaLib/lexer.py":13 + * + * + * class Lexer(object): # <<<<<<<<<<<<<< + * NUMBER = "NUMBER" + * HEXADECIMAL = "HEXADECIMAL" +*/ + __pyx_t_2 = __Pyx_PEP560_update_bases(__pyx_mstate_global->__pyx_tuple[1]); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = __Pyx_Py3MetaclassPrepare(__pyx_t_4, __pyx_t_2, __pyx_mstate_global->__pyx_n_u_Lexer, __pyx_mstate_global->__pyx_n_u_Lexer, (PyObject *) NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, (PyObject *) NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (__pyx_t_2 != __pyx_mstate_global->__pyx_tuple[1]) { + if (unlikely((PyDict_SetItemString(__pyx_t_7, "__orig_bases__", __pyx_mstate_global->__pyx_tuple[1]) < 0))) __PYX_ERR(0, 13, __pyx_L1_error) + } + + /* "fontTools/feaLib/lexer.py":14 + * + * class Lexer(object): + * NUMBER = "NUMBER" # <<<<<<<<<<<<<< + * HEXADECIMAL = "HEXADECIMAL" + * OCTAL = "OCTAL" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_NUMBER, __pyx_mstate_global->__pyx_n_u_NUMBER) < (0)) __PYX_ERR(0, 14, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":15 + * class Lexer(object): + * NUMBER = "NUMBER" + * HEXADECIMAL = "HEXADECIMAL" # <<<<<<<<<<<<<< + * OCTAL = "OCTAL" + * NUMBERS = (NUMBER, HEXADECIMAL, OCTAL) +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_HEXADECIMAL, __pyx_mstate_global->__pyx_n_u_HEXADECIMAL) < (0)) __PYX_ERR(0, 15, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":16 + * NUMBER = "NUMBER" + * HEXADECIMAL = "HEXADECIMAL" + * OCTAL = "OCTAL" # <<<<<<<<<<<<<< + * NUMBERS = (NUMBER, HEXADECIMAL, OCTAL) + * FLOAT = "FLOAT" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_OCTAL, __pyx_mstate_global->__pyx_n_u_OCTAL) < (0)) __PYX_ERR(0, 16, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":17 + * HEXADECIMAL = "HEXADECIMAL" + * OCTAL = "OCTAL" + * NUMBERS = (NUMBER, HEXADECIMAL, OCTAL) # <<<<<<<<<<<<<< + * FLOAT = "FLOAT" + * STRING = "STRING" +*/ + __pyx_t_8 = PyObject_GetItem(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_NUMBER); + if (unlikely(!__pyx_t_8)) { + PyErr_Clear(); + __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_NUMBER); + } + if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = PyObject_GetItem(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_HEXADECIMAL); + if (unlikely(!__pyx_t_9)) { + PyErr_Clear(); + __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_mstate_global->__pyx_n_u_HEXADECIMAL); + } + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = PyObject_GetItem(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_OCTAL); + if (unlikely(!__pyx_t_10)) { + PyErr_Clear(); + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_OCTAL); + } + if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_11 = PyTuple_Pack(3, __pyx_t_8, __pyx_t_9, __pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_NUMBERS, __pyx_t_11) < (0)) __PYX_ERR(0, 17, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "fontTools/feaLib/lexer.py":18 + * OCTAL = "OCTAL" + * NUMBERS = (NUMBER, HEXADECIMAL, OCTAL) + * FLOAT = "FLOAT" # <<<<<<<<<<<<<< + * STRING = "STRING" + * NAME = "NAME" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_FLOAT, __pyx_mstate_global->__pyx_n_u_FLOAT) < (0)) __PYX_ERR(0, 18, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":19 + * NUMBERS = (NUMBER, HEXADECIMAL, OCTAL) + * FLOAT = "FLOAT" + * STRING = "STRING" # <<<<<<<<<<<<<< + * NAME = "NAME" + * FILENAME = "FILENAME" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_STRING, __pyx_mstate_global->__pyx_n_u_STRING) < (0)) __PYX_ERR(0, 19, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":20 + * FLOAT = "FLOAT" + * STRING = "STRING" + * NAME = "NAME" # <<<<<<<<<<<<<< + * FILENAME = "FILENAME" + * GLYPHCLASS = "GLYPHCLASS" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_NAME, __pyx_mstate_global->__pyx_n_u_NAME) < (0)) __PYX_ERR(0, 20, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":21 + * STRING = "STRING" + * NAME = "NAME" + * FILENAME = "FILENAME" # <<<<<<<<<<<<<< + * GLYPHCLASS = "GLYPHCLASS" + * CID = "CID" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_FILENAME, __pyx_mstate_global->__pyx_n_u_FILENAME) < (0)) __PYX_ERR(0, 21, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":22 + * NAME = "NAME" + * FILENAME = "FILENAME" + * GLYPHCLASS = "GLYPHCLASS" # <<<<<<<<<<<<<< + * CID = "CID" + * SYMBOL = "SYMBOL" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_GLYPHCLASS, __pyx_mstate_global->__pyx_n_u_GLYPHCLASS) < (0)) __PYX_ERR(0, 22, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":23 + * FILENAME = "FILENAME" + * GLYPHCLASS = "GLYPHCLASS" + * CID = "CID" # <<<<<<<<<<<<<< + * SYMBOL = "SYMBOL" + * COMMENT = "COMMENT" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_CID, __pyx_mstate_global->__pyx_n_u_CID) < (0)) __PYX_ERR(0, 23, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":24 + * GLYPHCLASS = "GLYPHCLASS" + * CID = "CID" + * SYMBOL = "SYMBOL" # <<<<<<<<<<<<<< + * COMMENT = "COMMENT" + * NEWLINE = "NEWLINE" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_SYMBOL, __pyx_mstate_global->__pyx_n_u_SYMBOL) < (0)) __PYX_ERR(0, 24, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":25 + * CID = "CID" + * SYMBOL = "SYMBOL" + * COMMENT = "COMMENT" # <<<<<<<<<<<<<< + * NEWLINE = "NEWLINE" + * ANONYMOUS_BLOCK = "ANONYMOUS_BLOCK" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_COMMENT, __pyx_mstate_global->__pyx_n_u_COMMENT) < (0)) __PYX_ERR(0, 25, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":26 + * SYMBOL = "SYMBOL" + * COMMENT = "COMMENT" + * NEWLINE = "NEWLINE" # <<<<<<<<<<<<<< + * ANONYMOUS_BLOCK = "ANONYMOUS_BLOCK" + * +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_NEWLINE, __pyx_mstate_global->__pyx_n_u_NEWLINE) < (0)) __PYX_ERR(0, 26, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":27 + * COMMENT = "COMMENT" + * NEWLINE = "NEWLINE" + * ANONYMOUS_BLOCK = "ANONYMOUS_BLOCK" # <<<<<<<<<<<<<< + * + * CHAR_WHITESPACE_ = " \t" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_ANONYMOUS_BLOCK, __pyx_mstate_global->__pyx_n_u_ANONYMOUS_BLOCK) < (0)) __PYX_ERR(0, 27, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":29 + * ANONYMOUS_BLOCK = "ANONYMOUS_BLOCK" + * + * CHAR_WHITESPACE_ = " \t" # <<<<<<<<<<<<<< + * CHAR_NEWLINE_ = "\r\n" + * CHAR_SYMBOL_ = ",;:-+'{}[]<>()=" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_CHAR_WHITESPACE, __pyx_mstate_global->__pyx_kp_u__13) < (0)) __PYX_ERR(0, 29, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":30 + * + * CHAR_WHITESPACE_ = " \t" + * CHAR_NEWLINE_ = "\r\n" # <<<<<<<<<<<<<< + * CHAR_SYMBOL_ = ",;:-+'{}[]<>()=" + * CHAR_DIGIT_ = "0123456789" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_CHAR_NEWLINE, __pyx_mstate_global->__pyx_kp_u__14) < (0)) __PYX_ERR(0, 30, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":31 + * CHAR_WHITESPACE_ = " \t" + * CHAR_NEWLINE_ = "\r\n" + * CHAR_SYMBOL_ = ",;:-+'{}[]<>()=" # <<<<<<<<<<<<<< + * CHAR_DIGIT_ = "0123456789" + * CHAR_HEXDIGIT_ = "0123456789ABCDEFabcdef" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_CHAR_SYMBOL, __pyx_mstate_global->__pyx_kp_u__15) < (0)) __PYX_ERR(0, 31, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":32 + * CHAR_NEWLINE_ = "\r\n" + * CHAR_SYMBOL_ = ",;:-+'{}[]<>()=" + * CHAR_DIGIT_ = "0123456789" # <<<<<<<<<<<<<< + * CHAR_HEXDIGIT_ = "0123456789ABCDEFabcdef" + * CHAR_LETTER_ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_CHAR_DIGIT, __pyx_mstate_global->__pyx_kp_u_0123456789) < (0)) __PYX_ERR(0, 32, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":33 + * CHAR_SYMBOL_ = ",;:-+'{}[]<>()=" + * CHAR_DIGIT_ = "0123456789" + * CHAR_HEXDIGIT_ = "0123456789ABCDEFabcdef" # <<<<<<<<<<<<<< + * CHAR_LETTER_ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + * CHAR_NAME_START_ = CHAR_LETTER_ + "_+*:.^~!\\" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_CHAR_HEXDIGIT, __pyx_mstate_global->__pyx_kp_u_0123456789ABCDEFabcdef) < (0)) __PYX_ERR(0, 33, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":34 + * CHAR_DIGIT_ = "0123456789" + * CHAR_HEXDIGIT_ = "0123456789ABCDEFabcdef" + * CHAR_LETTER_ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" # <<<<<<<<<<<<<< + * CHAR_NAME_START_ = CHAR_LETTER_ + "_+*:.^~!\\" + * CHAR_NAME_CONTINUATION_ = CHAR_LETTER_ + CHAR_DIGIT_ + "_.+*:^~!/-" +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_CHAR_LETTER, __pyx_mstate_global->__pyx_n_u_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef) < (0)) __PYX_ERR(0, 34, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":35 + * CHAR_HEXDIGIT_ = "0123456789ABCDEFabcdef" + * CHAR_LETTER_ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + * CHAR_NAME_START_ = CHAR_LETTER_ + "_+*:.^~!\\" # <<<<<<<<<<<<<< + * CHAR_NAME_CONTINUATION_ = CHAR_LETTER_ + CHAR_DIGIT_ + "_.+*:^~!/-" + * +*/ + __pyx_t_11 = PyObject_GetItem(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_CHAR_LETTER); + if (unlikely(!__pyx_t_11)) { + PyErr_Clear(); + __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_mstate_global->__pyx_n_u_CHAR_LETTER); + } + if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_10 = PyNumber_Add(__pyx_t_11, __pyx_mstate_global->__pyx_kp_u__16); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_CHAR_NAME_START, __pyx_t_10) < (0)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + + /* "fontTools/feaLib/lexer.py":36 + * CHAR_LETTER_ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + * CHAR_NAME_START_ = CHAR_LETTER_ + "_+*:.^~!\\" + * CHAR_NAME_CONTINUATION_ = CHAR_LETTER_ + CHAR_DIGIT_ + "_.+*:^~!/-" # <<<<<<<<<<<<<< + * + * RE_GLYPHCLASS = re.compile(r"^[A-Za-z_0-9.\-]+$") +*/ + __pyx_t_10 = PyObject_GetItem(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_CHAR_LETTER); + if (unlikely(!__pyx_t_10)) { + PyErr_Clear(); + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_CHAR_LETTER); + } + if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 36, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_11 = PyObject_GetItem(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_CHAR_DIGIT); + if (unlikely(!__pyx_t_11)) { + PyErr_Clear(); + __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_mstate_global->__pyx_n_u_CHAR_DIGIT); + } + if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 36, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_9 = PyNumber_Add(__pyx_t_10, __pyx_t_11); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 36, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __pyx_t_11 = PyNumber_Add(__pyx_t_9, __pyx_mstate_global->__pyx_kp_u__17); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 36, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_CHAR_NAME_CONTINUATION, __pyx_t_11) < (0)) __PYX_ERR(0, 36, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "fontTools/feaLib/lexer.py":38 + * CHAR_NAME_CONTINUATION_ = CHAR_LETTER_ + CHAR_DIGIT_ + "_.+*:^~!/-" + * + * RE_GLYPHCLASS = re.compile(r"^[A-Za-z_0-9.\-]+$") # <<<<<<<<<<<<<< + * + * MODE_NORMAL_ = "NORMAL" +*/ + __pyx_t_9 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_re); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 38, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_compile); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 38, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_12 = 1; + { + PyObject *__pyx_callargs[2] = {__pyx_t_9, __pyx_mstate_global->__pyx_kp_u_A_Za_z_0_9}; + __pyx_t_11 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_8, __pyx_callargs+__pyx_t_12, (2-__pyx_t_12) | (__pyx_t_12*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 38, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + } + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_RE_GLYPHCLASS, __pyx_t_11) < (0)) __PYX_ERR(0, 38, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "fontTools/feaLib/lexer.py":40 + * RE_GLYPHCLASS = re.compile(r"^[A-Za-z_0-9.\-]+$") + * + * MODE_NORMAL_ = "NORMAL" # <<<<<<<<<<<<<< + * MODE_FILENAME_ = "FILENAME" + * +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_MODE_NORMAL, __pyx_mstate_global->__pyx_n_u_NORMAL) < (0)) __PYX_ERR(0, 40, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":41 + * + * MODE_NORMAL_ = "NORMAL" + * MODE_FILENAME_ = "FILENAME" # <<<<<<<<<<<<<< + * + * def __init__(self, text, filename): +*/ + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_MODE_FILENAME, __pyx_mstate_global->__pyx_n_u_FILENAME) < (0)) __PYX_ERR(0, 41, __pyx_L1_error) + + /* "fontTools/feaLib/lexer.py":43 + * MODE_FILENAME_ = "FILENAME" + * + * def __init__(self, text, filename): # <<<<<<<<<<<<<< + * self.filename_ = filename + * self.line_ = 1 +*/ + __pyx_t_11 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_1__init__, 0, __pyx_mstate_global->__pyx_n_u_Lexer___init, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[0])); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 43, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_11); + #endif + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_init, __pyx_t_11) < (0)) __PYX_ERR(0, 43, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "fontTools/feaLib/lexer.py":52 + * self.mode_ = Lexer.MODE_NORMAL_ + * + * def __iter__(self): # <<<<<<<<<<<<<< + * return self + * +*/ + __pyx_t_11 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_3__iter__, 0, __pyx_mstate_global->__pyx_n_u_Lexer___iter, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[1])); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 52, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_11); + #endif + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_iter, __pyx_t_11) < (0)) __PYX_ERR(0, 52, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "fontTools/feaLib/lexer.py":55 + * return self + * + * def next(self): # Python 2 # <<<<<<<<<<<<<< + * return self.__next__() + * +*/ + __pyx_t_11 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_5next, 0, __pyx_mstate_global->__pyx_n_u_Lexer_next, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[2])); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 55, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_11); + #endif + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_next_3, __pyx_t_11) < (0)) __PYX_ERR(0, 55, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "fontTools/feaLib/lexer.py":58 + * return self.__next__() + * + * def __next__(self): # Python 3 # <<<<<<<<<<<<<< + * while True: + * token_type, token, location = self.next_() +*/ + __pyx_t_11 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_7__next__, 0, __pyx_mstate_global->__pyx_n_u_Lexer___next, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[3])); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 58, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_11); + #endif + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_next, __pyx_t_11) < (0)) __PYX_ERR(0, 58, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "fontTools/feaLib/lexer.py":64 + * return (token_type, token, location) + * + * def location_(self): # <<<<<<<<<<<<<< + * column = self.pos_ - self.line_start_ + 1 + * return FeatureLibLocation(self.filename_ or "", self.line_, column) +*/ + __pyx_t_11 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_9location_, 0, __pyx_mstate_global->__pyx_n_u_Lexer_location, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[4])); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 64, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_11); + #endif + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_location, __pyx_t_11) < (0)) __PYX_ERR(0, 64, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "fontTools/feaLib/lexer.py":68 + * return FeatureLibLocation(self.filename_ or "", self.line_, column) + * + * def next_(self): # <<<<<<<<<<<<<< + * self.scan_over_(Lexer.CHAR_WHITESPACE_) + * location = self.location_() +*/ + __pyx_t_11 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_11next_, 0, __pyx_mstate_global->__pyx_n_u_Lexer_next_2, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[5])); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 68, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_11); + #endif + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_next_2, __pyx_t_11) < (0)) __PYX_ERR(0, 68, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "fontTools/feaLib/lexer.py":165 + * raise FeatureLibError("Unexpected character: %r" % cur_char, location) + * + * def scan_over_(self, valid): # <<<<<<<<<<<<<< + * p = self.pos_ + * while p < self.text_length_ and self.text_[p] in valid: +*/ + __pyx_t_11 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_13scan_over_, 0, __pyx_mstate_global->__pyx_n_u_Lexer_scan_over, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[6])); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 165, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_11); + #endif + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_scan_over, __pyx_t_11) < (0)) __PYX_ERR(0, 165, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "fontTools/feaLib/lexer.py":171 + * self.pos_ = p + * + * def scan_until_(self, stop_at): # <<<<<<<<<<<<<< + * p = self.pos_ + * while p < self.text_length_ and self.text_[p] not in stop_at: +*/ + __pyx_t_11 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_15scan_until_, 0, __pyx_mstate_global->__pyx_n_u_Lexer_scan_until, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[7])); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 171, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_11); + #endif + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_scan_until, __pyx_t_11) < (0)) __PYX_ERR(0, 171, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "fontTools/feaLib/lexer.py":177 + * self.pos_ = p + * + * def scan_anonymous_block(self, tag): # <<<<<<<<<<<<<< + * location = self.location_() + * tag = tag.strip() +*/ + __pyx_t_11 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_6feaLib_5lexer_5Lexer_17scan_anonymous_block, 0, __pyx_mstate_global->__pyx_n_u_Lexer_scan_anonymous_block, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[8])); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 177, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_11); + #endif + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_scan_anonymous_block, __pyx_t_11) < (0)) __PYX_ERR(0, 177, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "fontTools/feaLib/lexer.py":13 + * + * + * class Lexer(object): # <<<<<<<<<<<<<< + * NUMBER = "NUMBER" + * HEXADECIMAL = "HEXADECIMAL" +*/ + __pyx_t_11 = __Pyx_Py3ClassCreate(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_Lexer, __pyx_t_2, __pyx_t_7, NULL, 0, 0); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_11); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_Lexer, __pyx_t_11) < (0)) __PYX_ERR(0, 13, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":192 + * + * + * class IncludingLexer(object): # <<<<<<<<<<<<<< + * """A Lexer that follows include statements. + * +*/ + __pyx_t_2 = __Pyx_PEP560_update_bases(__pyx_mstate_global->__pyx_tuple[3]); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 192, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 192, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = __Pyx_Py3MetaclassPrepare(__pyx_t_4, __pyx_t_2, __pyx_mstate_global->__pyx_n_u_IncludingLexer, __pyx_mstate_global->__pyx_n_u_IncludingLexer, (PyObject *) NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_kp_u_A_Lexer_that_follows_include_sta); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 192, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (__pyx_t_2 != __pyx_mstate_global->__pyx_tuple[3]) { + if (unlikely((PyDict_SetItemString(__pyx_t_7, "__orig_bases__", __pyx_mstate_global->__pyx_tuple[3]) < 0))) __PYX_ERR(0, 192, __pyx_L1_error) + } + + /* "fontTools/feaLib/lexer.py":207 + * """ + * + * def __init__(self, featurefile, *, includeDir=None): # <<<<<<<<<<<<<< + * """Initializes an IncludingLexer. + * +*/ + __pyx_t_11 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 207, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + if (PyDict_SetItem(__pyx_t_11, __pyx_mstate_global->__pyx_n_u_includeDir, Py_None) < (0)) __PYX_ERR(0, 207, __pyx_L1_error) + __pyx_t_8 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_6feaLib_5lexer_14IncludingLexer_1__init__, 0, __pyx_mstate_global->__pyx_n_u_IncludingLexer___init, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[9])); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 207, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_8); + #endif + __Pyx_CyFunction_SetDefaultsKwDict(__pyx_t_8, __pyx_t_11); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_init, __pyx_t_8) < (0)) __PYX_ERR(0, 207, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "fontTools/feaLib/lexer.py":221 + * self.includeDir = includeDir + * + * def __iter__(self): # <<<<<<<<<<<<<< + * return self + * +*/ + __pyx_t_8 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_6feaLib_5lexer_14IncludingLexer_3__iter__, 0, __pyx_mstate_global->__pyx_n_u_IncludingLexer___iter, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[10])); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 221, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_8); + #endif + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_iter, __pyx_t_8) < (0)) __PYX_ERR(0, 221, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "fontTools/feaLib/lexer.py":224 + * return self + * + * def next(self): # Python 2 # <<<<<<<<<<<<<< + * return self.__next__() + * +*/ + __pyx_t_8 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_6feaLib_5lexer_14IncludingLexer_5next, 0, __pyx_mstate_global->__pyx_n_u_IncludingLexer_next, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[11])); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 224, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_8); + #endif + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_next_3, __pyx_t_8) < (0)) __PYX_ERR(0, 224, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "fontTools/feaLib/lexer.py":227 + * return self.__next__() + * + * def __next__(self): # Python 3 # <<<<<<<<<<<<<< + * while self.lexers_: + * lexer = self.lexers_[-1] +*/ + __pyx_t_8 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_6feaLib_5lexer_14IncludingLexer_7__next__, 0, __pyx_mstate_global->__pyx_n_u_IncludingLexer___next, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[12])); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 227, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_8); + #endif + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_next, __pyx_t_8) < (0)) __PYX_ERR(0, 227, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "fontTools/feaLib/lexer.py":266 + * raise StopIteration() + * + * @staticmethod # <<<<<<<<<<<<<< + * def make_lexer_(file_or_path): + * if hasattr(file_or_path, "read"): +*/ + __pyx_t_11 = NULL; + __pyx_t_9 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_6feaLib_5lexer_14IncludingLexer_9make_lexer_, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_mstate_global->__pyx_n_u_IncludingLexer_make_lexer, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[13])); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 266, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_9); + #endif + __pyx_t_12 = 1; + { + PyObject *__pyx_callargs[2] = {__pyx_t_11, __pyx_t_9}; + __pyx_t_8 = __Pyx_PyObject_FastCall((PyObject*)__pyx_builtin_staticmethod, __pyx_callargs+__pyx_t_12, (2-__pyx_t_12) | (__pyx_t_12*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 266, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + } + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_make_lexer, __pyx_t_8) < (0)) __PYX_ERR(0, 266, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "fontTools/feaLib/lexer.py":279 + * return Lexer(data, filename) + * + * def scan_anonymous_block(self, tag): # <<<<<<<<<<<<<< + * return self.lexers_[-1].scan_anonymous_block(tag) + * +*/ + __pyx_t_8 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_6feaLib_5lexer_14IncludingLexer_11scan_anonymous_block, 0, __pyx_mstate_global->__pyx_n_u_IncludingLexer_scan_anonymous_bl, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[14])); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 279, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_8); + #endif + if (__Pyx_SetNameInClass(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_scan_anonymous_block, __pyx_t_8) < (0)) __PYX_ERR(0, 279, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "fontTools/feaLib/lexer.py":192 + * + * + * class IncludingLexer(object): # <<<<<<<<<<<<<< + * """A Lexer that follows include statements. + * +*/ + __pyx_t_8 = __Pyx_Py3ClassCreate(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_IncludingLexer, __pyx_t_2, __pyx_t_7, NULL, 0, 0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 192, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_8); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_IncludingLexer, __pyx_t_8) < (0)) __PYX_ERR(0, 192, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":283 + * + * + * class NonIncludingLexer(IncludingLexer): # <<<<<<<<<<<<<< + * """Lexer that does not follow `include` statements, emits them as-is.""" + * +*/ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_IncludingLexer); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 283, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = PyTuple_Pack(1, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 283, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PEP560_update_bases(__pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 283, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_7 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 283, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_Py3MetaclassPrepare(__pyx_t_7, __pyx_t_2, __pyx_mstate_global->__pyx_n_u_NonIncludingLexer, __pyx_mstate_global->__pyx_n_u_NonIncludingLexer, (PyObject *) NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_kp_u_Lexer_that_does_not_follow_inclu); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 283, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + if (__pyx_t_2 != __pyx_t_4) { + if (unlikely((PyDict_SetItemString(__pyx_t_8, "__orig_bases__", __pyx_t_4) < 0))) __PYX_ERR(0, 283, __pyx_L1_error) + } + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/feaLib/lexer.py":286 + * """Lexer that does not follow `include` statements, emits them as-is.""" + * + * def __next__(self): # Python 3 # <<<<<<<<<<<<<< + * return next(self.lexers_[0]) +*/ + __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_6feaLib_5lexer_17NonIncludingLexer_1__next__, 0, __pyx_mstate_global->__pyx_n_u_NonIncludingLexer___next, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_feaLib_lexer, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[15])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 286, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_4); + #endif + if (__Pyx_SetNameInClass(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_next, __pyx_t_4) < (0)) __PYX_ERR(0, 286, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/feaLib/lexer.py":283 + * + * + * class NonIncludingLexer(IncludingLexer): # <<<<<<<<<<<<<< + * """Lexer that does not follow `include` statements, emits them as-is.""" + * +*/ + __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_NonIncludingLexer, __pyx_t_2, __pyx_t_8, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 283, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_4); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_NonIncludingLexer, __pyx_t_4) < (0)) __PYX_ERR(0, 283, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/feaLib/lexer.py":1 + * from fontTools.feaLib.error import FeatureLibError, IncludedFeaNotFound # <<<<<<<<<<<<<< + * from fontTools.feaLib.location import FeatureLibLocation + * import re +*/ + __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_test, __pyx_t_2) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + if (__pyx_m) { + if (__pyx_mstate->__pyx_d && stringtab_initialized) { + __Pyx_AddTraceback("init fontTools.feaLib.lexer", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + #if !CYTHON_USE_MODULE_STATE + Py_CLEAR(__pyx_m); + #else + Py_DECREF(__pyx_m); + if (pystate_addmodule_run) { + PyObject *tp, *value, *tb; + PyErr_Fetch(&tp, &value, &tb); + PyState_RemoveModule(&__pyx_moduledef); + PyErr_Restore(tp, value, tb); + } + #endif + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init fontTools.feaLib.lexer"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #else + return __pyx_m; + #endif +} +/* #### Code section: pystring_table ### */ +/* #### Code section: cached_builtins ### */ + +static int __Pyx_InitCachedBuiltins(__pyx_mstatetype *__pyx_mstate) { + CYTHON_UNUSED_VAR(__pyx_mstate); + __pyx_builtin_object = __Pyx_GetBuiltinName(__pyx_mstate->__pyx_n_u_object); if (!__pyx_builtin_object) __PYX_ERR(0, 13, __pyx_L1_error) + __pyx_builtin_staticmethod = __Pyx_GetBuiltinName(__pyx_mstate->__pyx_n_u_staticmethod); if (!__pyx_builtin_staticmethod) __PYX_ERR(0, 266, __pyx_L1_error) + __pyx_builtin_open = __Pyx_GetBuiltinName(__pyx_mstate->__pyx_n_u_open); if (!__pyx_builtin_open) __PYX_ERR(0, 272, __pyx_L1_error) + + /* Cached unbound methods */ + __pyx_mstate->__pyx_umethod_PyDict_Type_items.type = (PyObject*)&PyDict_Type; + __pyx_mstate->__pyx_umethod_PyDict_Type_items.method_name = &__pyx_mstate->__pyx_n_u_items; + __pyx_mstate->__pyx_umethod_PyDict_Type_pop.type = (PyObject*)&PyDict_Type; + __pyx_mstate->__pyx_umethod_PyDict_Type_pop.method_name = &__pyx_mstate->__pyx_n_u_pop; + __pyx_mstate->__pyx_umethod_PyDict_Type_values.type = (PyObject*)&PyDict_Type; + __pyx_mstate->__pyx_umethod_PyDict_Type_values.method_name = &__pyx_mstate->__pyx_n_u_values; + __pyx_mstate->__pyx_umethod_PyList_Type_pop.type = (PyObject*)&PyList_Type; + __pyx_mstate->__pyx_umethod_PyList_Type_pop.method_name = &__pyx_mstate->__pyx_n_u_pop; + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: cached_constants ### */ + +static int __Pyx_InitCachedConstants(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "fontTools/feaLib/lexer.py":13 + * + * + * class Lexer(object): # <<<<<<<<<<<<<< + * NUMBER = "NUMBER" + * HEXADECIMAL = "HEXADECIMAL" +*/ + __pyx_mstate_global->__pyx_tuple[0] = PyTuple_Pack(1, __pyx_builtin_object); if (unlikely(!__pyx_mstate_global->__pyx_tuple[0])) __PYX_ERR(0, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[0]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[0]); + __pyx_mstate_global->__pyx_tuple[1] = PyTuple_Pack(1, __pyx_builtin_object); if (unlikely(!__pyx_mstate_global->__pyx_tuple[1])) __PYX_ERR(0, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[1]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[1]); + + /* "fontTools/feaLib/lexer.py":192 + * + * + * class IncludingLexer(object): # <<<<<<<<<<<<<< + * """A Lexer that follows include statements. + * +*/ + __pyx_mstate_global->__pyx_tuple[2] = PyTuple_Pack(1, __pyx_builtin_object); if (unlikely(!__pyx_mstate_global->__pyx_tuple[2])) __PYX_ERR(0, 192, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[2]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[2]); + __pyx_mstate_global->__pyx_tuple[3] = PyTuple_Pack(1, __pyx_builtin_object); if (unlikely(!__pyx_mstate_global->__pyx_tuple[3])) __PYX_ERR(0, 192, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[3]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[3]); + #if CYTHON_IMMORTAL_CONSTANTS + { + PyObject **table = __pyx_mstate->__pyx_tuple; + for (Py_ssize_t i=0; i<4; ++i) { + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL); + #else + Py_SET_REFCNT(table[i], _Py_IMMORTAL_INITIAL_REFCNT); + #endif + } + } + #endif + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} +/* #### Code section: init_constants ### */ + +static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) { + CYTHON_UNUSED_VAR(__pyx_mstate); + { + const struct { const unsigned int length: 11; } index[] = {{1},{1},{10},{22},{415},{18},{28},{29},{18},{25},{45},{32},{79},{66},{29},{27},{24},{1},{4},{0},{2},{2},{15},{9},{10},{1},{1},{1},{1},{1},{1},{1},{1},{1},{10},{4},{4},{9},{52},{15},{11},{14},{12},{23},{16},{13},{12},{16},{3},{7},{8},{5},{15},{18},{10},{11},{19},{14},{23},{23},{23},{26},{19},{35},{5},{14},{14},{14},{15},{10},{11},{26},{16},{17},{14},{12},{4},{7},{6},{6},{7},{17},{26},{5},{20},{13},{6},{6},{6},{18},{17},{18},{5},{7},{6},{7},{8},{7},{4},{7},{7},{8},{3},{11},{15},{12},{8},{9},{7},{14},{11},{10},{22},{22},{25},{8},{6},{10},{7},{10},{8},{13},{5},{5},{8},{4},{5},{7},{5},{5},{11},{9},{8},{8},{11},{5},{8},{13},{5},{10},{15},{4},{8},{8},{5},{4},{9},{6},{4},{2},{1},{4},{3},{4},{11},{12},{1},{2},{4},{6},{20},{10},{11},{4},{12},{10},{5},{5},{12},{7},{6},{5},{3},{3},{8},{4},{5},{12},{5},{10},{5},{6},{2},{140},{91},{46},{46},{1121},{58},{41},{283},{38},{7},{17},{20},{11},{45}}; + #if (CYTHON_COMPRESS_STRINGS) == 2 /* compression: bz2 (2542 bytes) */ +const char* const cstring = "BZh91AY&SY\256SP\342\000\000S\177\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\373@@@@@@@@@@@@@\000@\000`\010\371\276\332\353\335\336\3331\321\333\327z5 \241vd\363\320\017\257}\tD$LJ<\320\247\250\007\215O$\323)\3711\220\"\236\232\236\223\364&\247\261LjM\351C\305?R\036\202oR~\2204\217\nyM\212z&\324\022\210\023&\204\302\032&\022x\240\364CQ0!\246\203L\321\003L\000\230F\001\003!\241\210\364OP\006 \323S\024\332Ji\030\324\003\322\036\240\000\r\003M\000\000\000\000\000\0004\000\000\r4\3654d\032dB \t<\244\375&\023\024\363A\023\010\r\014\200\304\030\001\030#F\214&\230\214\230\2320\200\315G\244\025SL\206\0040\312a4\014\010\364&\t\204\304\006F\002a4\304a\030\000&#\000\230\000L\022\232\204\024\332A\r=OA\251\240d\r=L\206i4h\003@\000\003C\023#M\014\021\264#\322\000\006\232e)wm\023\262\t\304A\372\030\242\344\277b\343\343\006\223\212\261\246\217*-A\377\252\252\005\004*\t\273\254\006\310\307L\202A\010\tD$ \001\322\252R\352\366\351\020;\013\316\016\333\325\233\377l`\336\337p\337\337-Fd\266\244\001\250\206\\\020\0212\252*\246q\350\210\364\3140\334fv\235o\001\242\237+\340\204\t\222A(\352\341\211\310d&pA\206j2]\250`\271\204\014@\315Z5\213\rT\210\r\245\233 %-\027@JCI\213\232\310#\336B\252&\224+'\022SJo\262\225Q9\251\230\2114\234\346RY\327\2720B\002\330QD\024p\371;\330\234U\031 Q\232B\216\202*\276y\274@\222\024*\301\226,\346\265^\306@\272\242\006\"\004\217v\370js2N\316<\245\377j\3517\226\361\320\231\304E\325TXi\212\\\260>5e\223~c\344\355\365\326\273\022\010iL\327\030\022\304\262\036\010\372\0265V-\314\241h\275t\245\340@|\315\200q\202=\335\r=\263\r\263\251\t\270\335\031\331\275\277\020=j\216-(\247\314\230\341\3008\253\252;\241\274\341E/\337\345\372\376M)\302\306}\316\326oc\312~\030\276\352\307`\3061\036\026<\356\366\207]\342B\344\253\365\240\354l\336l\301\305\023\237\277\004\255\207\266\2636\331\205\272\367\353\201\214\211G\221\346OI\203\305\326\204\013\nd\326\264g\335s\236F\\\3128\031\301sx\367\337p\243\204Z\373\261\344!Cg=%.F\350)tM#Z\220\022e>\255\236\301\014\207\262I""\241\022o\366\207\277+td8\243\272\304 G\276\036\376!Stq\201\233\033\027A\370q\257\260_\216\353\330\336\010\316z\\Z\363\355{1\364\276ZM[Q\215gU\003\336a\374v-A\255)\026\257\327|I\300\344\311\004!\004\020\272}\304|r\310\341\242ts\275\304u\244\003N\307`i\301\366 \326U~\023\265\010\311-<\035\"\2310L\230&\030&{L\313\244f\265\304\3249\306qp\205\035\2661~\337\374\277\343T\274\022\364\013\3576\353\273C9E\365\235\336~JI'K\372n=Z\264q\215\251\035 u\217\236=\276\347\004\306V\2348O\224\335\224n\363~\221\366\036+\371.4)\311\251\270\006\007w\257'\316\364\344h\342\235\007?]sq\300\353\270\033\2703\260\033$\222A\300V\232H\361\233\222u\006\266\035-\014;Q\250?\221\262\033r\3303\257\211N|\356\025f\3060\214\234\345\223\3456\217\313\306\352\272\332\211\024Tj6\234\366*;U5`d\360\246x}\216\315\330\351^\310;\210\324k\373-\203\\\260m\017\357\3735\232\316\346\326(\035IG\016X@m\352\346u\267`_y\2566\353\327R\253\253W\025\371\035\345\341\315}\211\201\222\275\242\231\355\360\260\"!\020\211\204\341\261p\360Odv\023=\370e\3769J\371;2\257\255\364\\\235\366\331\250\3531{X]\350\237\032s\351U\331\347\014x\226VI\020A\255\275\204\233K\034u\347J2\2253K\300M\024 \2217oi\224\350\306\034\256X6E\"Bj\342\025\347*\221\231\260\016\335\246\235hJ4\005#\251\022\n\220\002\020sGP&X9\000\274\010\200o\241\006Evf\213\035\316\276\273\261\367Y9\370\223b\302,\3010\372~\225\255\021\032\211\003\"C=\246\002\322Bw\241\370\036\221b\314\221\245\00534\2015p\324%\362\363i\336_\025\007!r\223\207\362\335\201I\232~\031@\270\025\250\336K\t\020\317-\210\212\3216\033%9\232+\246)\005\200\310j_\036\212\004\t\256\345\215to\205\010\224\252V\265\333\211\230\312\360\257S\002\365i~d\034\246\271\253*\203?~\014@\241\231/c\032\305\272\353\256\304\321yqv\336R\363\r\305\t\366c\255[D\262\320\217\223\316\2200Q'L=\014\300T\222\021\236\006\215\002@\265\313\271\245\233bv\r\326k\226\0063#*\22671\326E\241;f\234\212\302WTkkZ\310\265\325\217r\321\305\020+c\002\246\"RU\230\032\032\t\351^lU\027\263^1dUe%r\331\306\031\211f,,A\032\3045d\223\265\271\357>\210\250""\3447O\025\370\345\235\224\006\311pq,\273\242C\3671X\260\237\035Z\270\361\225\314B\n@\217\007\313d\nd\234\332\214\3354Tb\364(\214SZ\367\317gIj\276]\216\236\344Lp\217\227\265\325U\227]\004Q.T#\220\323\247\200\320\344\370\252m\tIeh\017VI7\344l\021\026\322\005\264\375yW7\353J\346\350&CK\336\365Ncm\035N[\3031\2257\267f\313\341H\364\032\035f\210\252\204\324\315\233{\216\246~IM\363\301\233\013\216hR=3\004LJ\002\346\210\0244\257G\220\271\262\023\251p\271\232\246\"@V\324\3633\354\311\003\264\026\303F\226\267Zo9\226@\262\266\310\204\350L\n\355\033&^\213\031P[\266\203k\020X\017\33585^\207\215\202M.\324\302\330\320\202*\203$\024\272\267#\025\t\214\007\2647\022b\241\033\210p\352\340\200\372\263\342\310Y\276i\234\254#\323ZN\300\250E\316\200\233C\235\t&\366\321~|c'E\255\"5o$W\177uf\0012\262&\334P\300\306\372\031E\233'\320\210\316\323\245'!]\006H5[\253\\I\317N\310\351\276\360\3467\206\365kE\007\244K\341\266F\305\244\314\003\226dn\2279w\340\300D\205\0339\230\031\350\t^\311v\224A\242H\231\021L\265*\016#+<\022\002\343\274\3117\311dllyL`\327h\033\305_\264Z\316\013b\313pc\022\325\3136V\2246l\330b\275\013\213\351bh\356\344\353\273\252+\276&\354\"\344-\266\212\341\024]okz'{\243N\355|\275(\341\205\005\312\301\254m\350\340^6\261H \314\212Z@\325\202A\223\202(\315D\016\253\246\2722%\200#\207\004\232D1\006\264.\t\004\314\344\n\255\3144\352\n\325\222^\035\256Q\311\312O]\213\0105*2\201\300L\311\230\372\306\356\021\260@\344]\014\251\270\273-\205\031]\210\214\030\033|\226\016\276\360\272\334\266\347B\326\310\375\232i\223\254_\001\310\353y\344\210'\020U\027:\210\235^&\315\266\353IhF\233\362\020\222\\>\264r\377\257\363\222S\352xc:\267\265G\0363\\\263\362\267'\215\3266\033\322\200p z\324K\236\3218\001/|\254CL\246x\020\0021qf,\233\217\364'\270\261\220\177|\240\344\231!Q2\313\372N\325\2130\032R$\001\330l\005\243\271\206\256\326\241\254\226p\230\305\362\243?t8U$\261\200\361n\324\242\354\307R\030\234\200\360\251\353\336\354t\001\222\274\260\234\214\351\036xgm\024T\r\277\316\\\273\206p\356B\317\2434\232""\250\026\373\217\236\376(l\242^\"\321b\257e\037\244\220\035T\332\321\nC\251\254\035\337\370\244T\250+9\332\256L\300\321\374YB\205*\354\362f\032'+\223\253\314\317nvnkL\3665nQ\225\350\332Z`l+n\302\317A\277\225j\325\023\202E\321\235\307\025_#\347#7\246\370\251\333#S\026\234\360}w\360\007\374\215zi\257\302q\376\014o<\311g\235\226\371\251\014\241F\324\333S\230P|,\222\322q\335'\320E\202~^\264\343]\232\352\324v]j\323\306\220W\177V\267\035.k\003\013\010\301t\340\351\334c)M\037W\366\374puX\204\233\352kS\341\202\211\373\026'?:\264\303r\277\362\257M\256/\361\226\331\276\177\362`ma\3142%\213\225\221\333\310\324MBG\204\\\253\245Z\244\214d\355g\350W\305\277\354`a\200\005\027X`4\252\022q4\314\000\202\020\002\010$\207\310~<@\037xfa \351@\304'2\201\325\024\373I\207y'\332-\307\334\332\322\253UC\305\236x|\327\244\345\204\257\032*h*\264`\345z\236\233\320\325\213\n\023\301y\202\301'H\316$\222\211R\217\024\004\274\322\242y\227\005\321\225\0048\004\024`\342N\322\231bH\006Bj\013\352V\010\235\270f\2019(V\303w\204\242TyJ\261\000\253\035\004\344)R%\377\213\271\"\234(HW)\250q\000"; + PyObject *data = __Pyx_DecompressString(cstring, 2542, 2); + if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error) + const char* const bytes = __Pyx_PyBytes_AsString(data); + #if !CYTHON_ASSUME_SAFE_MACROS + if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) } + #endif + #elif (CYTHON_COMPRESS_STRINGS) != 0 /* compression: zlib (2392 bytes) */ +const char* const cstring = "x\332\275\026K[\023\311vP\274\002\023\225H@t\306\231\216\240\210\222h\024Q\300\353\330$\001r\r\t!\301\267\323\323twHK\247;\351\252F\320O?\227,{Y\313^\366\262\227Yf\3112\313,\371\t\376\204{\252:\017^\363\315]\335|I\325\251S\347\375\252\014\334\277\037{\360p\372\321\314\343'\263]\210_\210'\222\213\342\206$+E\236K+;\212\311\341\222\210\271\242\241i\306'\304\251\272\244Y\262\302!,b\245\254\350\030E\007\0068\370\024J\n\227\255(za\267\242pEE\304\226\t\273\252\001iE\221\324\242*\211X5t\237\021\371BeK\341\260\301\330K*\302\206\tD\032g*\"2t4\005\200\006<\333\n\247\226+\206\211\021\207J\206\245\311\334\206\002W\310\320\266\025\031\354\001Q*b2\014SV\3149\337\234X\224K\025\341\n\324\033\226)\201)\206\2169\025q\353\213Y\200\315\262\210\247\350\265\336\325\202\rF\017\004\023\276<\3700.Y5\025\t\254\333e\330\007\321\023,\330\250D4e[\321:\341\241\2163\352\207'\251+\242\251P[\016\2232\332W\ng\350\332.\207\254\n\365\227\213q\267\267U\261M\230P\315IN\324e0\200Q\377\371\216\217\274\025#\237\205\373\221\331\350\373\310\207\273\343\311\035\2104\206\240LLNpb\021C\356X\002t\261\254t\357nO@\000!\002\312)\227'1\233\332n\245\304I\232\210\32019_\271\233h~\2029\245\230eU\207\264\202y\206\276[6,\304mh\206\264\325%\276q\214\020aS\3257\227\216\tG\\\331B\230\223 \373P\016\234Q\3444\005\003\023\324\202\254n\252\030vK\207\034#\t\314\237\342*\212\251\0322\244\235+\201\034E?T\256\262\001\302t\243]\267\334_\255 \376u\250p\2478\245\0142iN\312\234\210\"*\212\246\325\215{4\345\005\303\320\320=\250b\212\320\250\330he\027\220\\Y\324w!\241\222e\"V\230\276T\264\256+mW\245\222h\212\000\231s\334M\363\306\273\013\003\037\270\376\013\003S\363s\221\273\023_\276\276\373\360\364\331\355\311\177\013w\357\314E\377\374\026~/D\001\002\340^\344\217\013c\267'\337?\217F\236\266\232\007=\373\372\036\335\201\357\274\205\213\221'\021\244n\372\335\271\264\234\372\317\213\364J&\273\232[\313\027\326_\276z\375\346\255\337\261\233%\365\343\226V\326\215J\325D\330\332\376\264\263\373\231\317d3oV\262\353ya!\235\215\277\210/\363kB\"""\265\224*\010\014\\N\276>tJ'\013\205\344\232\017g\370\225\244\020\317f\n\251\314:_He3\207\320\371\002\277\326b\311$_\245S\231\244\177\310\277YY\310\246}\370\325r\252\220\314\257\362q\270K%\342\331\225\225d\246\260\230J'\251\204\305t\226/,\372\216B\214\223\246i\230\335c\332\360\207\305R\372\315\352r<\315\347\363`&\237H\306S+|:\345\307\\\006\362\214\201\027\r\250\010\037\005\005\305*\340\350)*\010\252\256bA8\211\206$\235\202\206T\236\244.\213[\212\300\n\341\370\r%?\206B\222\250\013\235V\020X+\260\233\243\006\035\265\343\250z\377\244\265\342 tUu!\341\037\224\3717\3066\010?t\266t\254j\302J6\221\024\332\271\360O\231\354\032\004\227\245\267\225R\037\223Y_YH\256\371k>c\350G}=\201\350x\220\215\027@\234\260\272\273\003\277\204*a!\003\3705\245\270\226\024\272y\315\027\326R\231%\277l\304\n<\037\262\210vuI5\242\320\342\206\205U]A\202\300&\204\260\251`\010U\231\036\001\rA\0240t\232\262!J[\222f \205.`\206dhVY\227\214r\005\206\0314\252@;\022\366\212\210K\262\210E\230\346t\326\010\202lH\202\240\000%5^1\315V\337\321\031x\010\244lt\027\014Sh\303\224\277\275\013\02406>\026\331\241\2351\377\204\215-\245\r\302\263\330\231,Q\177\262D\025Z\366'\260\254\314Nb\333\265 \024-\035\014\207hH\237d6\236YxZ\243\250\373X\264\313LP\221\320\t\246\212\304\rD\243\210\332u\367\321Pu\246\221-H\320T\030\212,\300l\201qi\342\216[]@(\213*[;}\001/\252T*\213;\250\242Q\265e\005\213~\336\204\262!C\270\351fi\024\020\312\246\001\201\207'\200&\327O\206\277\266\213\207\255ta\000M D\230\276\301P!\006\252\320 \005\347:\364\003""\334]j\\\n;Ag\334\331\362\206\274L}\274^\332\027)\341\305=\331\016\373\325\331\347\234\241\225x\2419\370+Yr\346\231\345\261\346P\210\272\265\014-\010ag)\371B\306\240fo\261\3118\006s\006\310W\032\223s\265\2335\253\3167\007\207\354y\262\t\323:\334\014]#\367\334`\343\316\363z\317\217\276\237\202!\373\001\230w\313\351\201\234\204~!\261\203\020\235\031O\235O\320{\2437\3004\261y\365z\343z\024r\234\243\210\033N\322\035\365\202P\245\342\217\300OW\307\000\261\344\306(\353\003\320\177\023z\275\037\252\006\364=\264E\0204\347\344\335\236\216\316\024t\003\230\033\032\005\267\240\253\300\330t\255\007\006\376\340\225\306\225)Hp\350Z\343Z\304\315\271\345\306\374jc\025r6J\002L()=_+*:.^~!\\_.+*:^~!/-?\r#()\\@.-}\\s*\\s*;utf-8-sigABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzANONYMOUS_BLOCKCHAR_DIGIT_CHAR_HEXDIGIT_CHAR_LETTER_CHAR_NAME_CONTINUATION_CHAR_NAME_START_CHAR_NEWLINE_CHAR_SYMBOL_CHAR_WHITESPACE_CIDCOMMENTFILENAMEFLOATFeatureLibErrorFeatureLibLocationGLYPHCLASSHEXADECIMALIncludedFeaNotFoundIncludingLexerIncludingLexer.__init__IncludingLexer.__iter__IncludingLexer.__next__IncludingLexer.make_lexer_IncludingLexer.nextIncludingLexer.scan_anonymous_blockLexerLexer.__init__Lexer.__iter__Lexer.__next__Lexer.location_Lexer.nextLexer.next_Lexer.scan_anonymous_blockLexer.scan_over_Lexer.scan_until_MODE_FILENAME_MODE_NORMAL_NAMENEWLINENORMALNUMBERNUMBERSNonIncludingLexerNonIncludingLexer.__next__OCTAL__Pyx_PyDict_NextRefRE_GLYPHCLASSSTRINGSYMBOLappendasyncio.coroutines__class_getitem__cline_in_tracebackcloseclosingcolumncompilecur_charcurpathdatadirname__doc__encodingerrfeaturefilefeaturefilepathfile_or_pathfilenamefilename_fileobjfname_locationfname_tokenfname_typefontTools.feaLib.errorfontTools.feaLib.lexerfontTools.feaLib.locati""on__func__getcwdglyphclassincludeincludeDir__init___is_coroutineisabsitems__iter__joinlexerlexers_limitline_line_start_location_location__main__make_lexer_matchmaxsplit__metaclass__mode___module____mro_entries__name__name____next__next_nextnext_charobjectopenosppathpoppos___prepare____qualname__rrereadregexpscan_anonymous_blockscan_over_scan_until_self__set_name__setdefaultsplitstartstaticmethodstop_atstringstripsubtag__test__texttext_text_length_tokentoken_typevalidvaluesxX\200A\330\010\023\2204\220z\240\021\330\010\016\210c\220\026\220q\330\010\014\210L\230\001\230\025\230a\330\010\014\210K\220q\230\005\230Q\330\010\021\220\030\230\022\2304\230r\240\021\330\010\020\220\002\220&\230\001\230\030\240\024\240V\2501\250D\260\n\270)\3001\330\010\013\2103\210a\210w\220c\230\021\330\014\022\220/\240\021\330\020@\300\002\300%\300q\340\010\014\210I\220S\230\001\230\025\230a\230q\330\010\020\220\005\320\025'\240u\250A\250T\260\021\200A\340\010\013\2107\220!\220>\240\021\330\014\025\220Z\230~\250Q\340\014\026\220j\240\016\250a\330\014\026\220d\230!\230:\240U\250)\2601\330\010\017\210w\220e\2301\330\010\023\2207\230!\2309\240H\250A\330\010\013\2101\330\014\023\2206\230\021\330\010\017\210u\220A\220V\2301\200A\330\010\014\210D\220\001\330\010\016\210b\220\002\220$\220n\240D\250\004\250F\260!\2603\260c\270\021\330\014\021\220\021\330\010\014\210H\220A\200A\330\010\014\210D\220\001\330\010\016\210b\220\002\220$\220n\240D\250\004\250F\260!\2603\260g\270Q\330\014\021\220\021\330\010\014\210H\220A\200A\330\010\014\210K\220q\230\005\230Q\330\010\023\2204\220z\240\021\330\010\020\220\004\220A\330\010\017\210t\2201\330\010\020\220\003\2201\220A\330\010\013\2106\220\023\220A\330\014\022\220-\230q\330\010\023\2204\220q\230\001\330\010\024\220D\230\001\230\026\230r\240\026\240v\250R\250r\260\022\260;\270a\340\010\013\2109\220C\220q\330\014\020\220\t\230\021\330\014\020\220\n\230!\330\014\020\220\017\230t\2401\330\014\024\220E\230\032\2406\250\021\330\010\013\2109\220C\220q\330\014\020""\220\t\230\025\230j\250\003\250:\260Q\330\014\020\220\n\230!\330\014\020\220\017\230t\2401\330\014\024\220E\230\032\2406\250\021\330\010\013\2109\220C\220q\330\014\020\220\014\230A\230U\240!\330\014\024\220E\230\032\2404\240q\250\010\260\004\260H\270A\340\010\013\2104\210w\220c\230\025\230a\330\014\017\210y\230\003\2301\330\020\026\220o\240Q\320&G\300q\330\014\020\220\014\230A\230Q\330\014\027\220t\2301\230D\240\n\250$\250f\260B\260k\300\021\330\014\017\210y\230\003\2301\330\020\026\220o\240Q\320&F\300a\330\014\020\220\t\230\021\330\014\020\220\t\230\025\230a\330\014\024\220E\230\033\240D\250\001\250\026\250r\260\024\260T\270\026\270r\300\024\300Q\340\010\013\2109\220C\220u\230D\240\n\250#\250U\260!\330\014\020\220\t\230\021\330\014\020\220\013\2301\230E\240\021\330\014\024\220E\230\026\230s\240!\2404\240q\250\006\250b\260\004\260D\270\010\300\005\300Q\330\010\013\2109\220C\220q\330\014\020\220\t\230\021\330\014\020\220\013\2301\230E\240\021\330\014\031\230\024\230Q\230f\240B\240d\250$\250a\330\014\017\210s\220!\220<\230r\240\021\330\020\026\220o\240Q\320&C\3001\330\014\017\210t\2205\230\016\240f\250A\250Q\330\020\026\220o\240Q\330\024\025\340\024\025\340\014\024\220E\230\035\240l\260!\330\010\013\2109\220C\220u\230A\330\014\020\220\t\230\021\330\014\020\220\013\2301\230E\240\021\330\014\024\220D\230\001\230\030\240\024\240Q\330\014\017\210v\220S\230\001\330\020\024\220I\230U\240!\330\014\024\220E\230\027\240\007\240q\330\010\013\2109\220C\220t\2304\230z\250\023\250A\330\014\020\220\t\230\021\330\014\020\220\013\2301\230E\240\021\330\014\024\220E\230\036\240s\250!\2504\250q\260\010\270\004\270H\300E\310\021\330\010\013\2109\220C\220t\2304\230z\250\023\250E\260\021\330\014\020\220\013\2301\230E\240\021\330\014\024\220E\230\030\240\023\240A\240T\250\021\250(\260$\260h\270d\300!\330\010\013\2109\220C\220u\230A\330\014\020\220\013\2301\230E\240\021\330\014\017\210t\2206\230\023\230F\240#\240T\250\021\250$\250g\260S\270\001\330\020\030\230\005\230Y\240c\250\021\250$\250a""\250x\260t\2708\3005\310\001\330\014\020\220\013\2301\230A\330\014\020\220\013\2301\230E\240\021\330\014\024\220E\230\030\240\025\240a\240t\2501\250H\260D\270\t\300\021\330\010\013\2109\220C\220t\2304\230z\250\023\250E\260\021\330\014\020\220\t\230\021\330\014\020\220\013\2301\230E\240\021\330\014\017\210t\2206\230\023\230F\240#\240T\250\021\250$\250g\260S\270\001\330\020\030\230\005\230Y\240c\250\021\250$\250a\250x\260t\2708\3005\310\001\330\014\020\220\013\2301\230A\330\014\020\220\013\2301\230E\240\021\330\014\024\220E\230\030\240\025\240a\240t\2501\250H\260D\270\t\300\021\330\010\013\2109\220C\220u\230A\330\014\020\220\t\230\021\330\014\024\220E\230\031\240*\250A\330\010\013\2109\220C\220q\330\014\020\220\t\230\021\330\014\020\220\014\230A\230Q\330\014\017\210t\2206\230\022\2304\230~\250T\260\024\260V\2701\270D\300\007\300s\310!\330\020\024\220I\230Q\340\020\031\230\022\2304\230q\240\n\250$\250d\260!\2606\270\022\2704\270t\3006\310\022\3101\330\020\030\230\005\230Y\240h\250a\340\020\026\220o\240Q\320&K\3101\330\010\016\210o\230Q\320\0369\270\022\270:\300Q\200A\330\010\014\210M\230\021\330\010\014\210I\220Q\330\010\014\210H\220A\330\010\014\210O\2301\330\010\014\210I\220Q\330\010\014\320\014\034\230C\230q\240\001\330\010\014\210I\220U\230!\200A\330\010\021\220\024\220V\2302\230T\240\035\250b\260\001\330\010\017\320\017!\240\021\240$\240k\260\023\260N\300$\300h\310a\200A\330\010\016\210d\220!\330\014\024\220D\230\010\240\002\240!\330\014\r\330\020\034\230G\240;\250d\260!\2601\330\023\024\330\020\024\220H\230D\240\001\330\020\021\330\014\017\210{\230#\230U\240&\250\004\250F\260#\260Q\330\020\034\230M\320):\270%\270u\300A\330\020\023\220;\230g\240U\250!\330\024\032\230/\250\021\320*@\300\001\360\010\000\021\024\2202\220U\230&\240\001\240\021\330\024\033\2301\340\024\027\220t\230<\240w\250a\330\030\"\240$\240a\330\031\035\320\035.\250g\260Q\330\030\"\240\"\240E\250\030\260\021\260$\260a\360\014\000\031#\240\"\240G\2501\330\024\033\2302\230U\240%\240q\250\t\260\021""\330\020\023\2203\220a\220t\230:\240S\250\001\330\024\032\230/\250\021\320*I\310\021\330\020\021\330\024\030\230\010\240\007\240q\250\004\250L\270\001\270\021\330\020\027\320\027,\250A\330\024\032\320\032-\250Q\250m\320;P\320PQ\340\020\030\230\014\240G\2501\330\010\016\210m\2301\200A\330\010\t\330\014\030\230\007\230{\250$\250f\260A\330\014\017\210{\230#\230U\240!\330\020\030\230\014\240G\2501\200A\330\010\017\210q\200A\330\010\017\210t\2201\220D\230\010\240\001\240\021\200A\330\010\017\210t\2208\2302\230R\320\0374\260A\260Q\200A\330\010\017\210t\2209\230A\320\004'\240q\360\024\000\t\r\210K\220q\230\004\230L\250\001\250\021\330\010\014\320\014\037\230t\2408\2501\250B\250a\330\010\014\210N\230!"; + PyObject *data = NULL; + CYTHON_UNUSED_VAR(__Pyx_DecompressString); + #endif + PyObject **stringtab = __pyx_mstate->__pyx_string_tab; + Py_ssize_t pos = 0; + for (int i = 0; i < 183; i++) { + Py_ssize_t bytes_length = index[i].length; + PyObject *string = PyUnicode_DecodeUTF8(bytes + pos, bytes_length, NULL); + if (likely(string) && i >= 38) PyUnicode_InternInPlace(&string); + if (unlikely(!string)) { + Py_XDECREF(data); + __PYX_ERR(0, 1, __pyx_L1_error) + } + stringtab[i] = string; + pos += bytes_length; + } + for (int i = 183; i < 197; i++) { + Py_ssize_t bytes_length = index[i].length; + PyObject *string = PyBytes_FromStringAndSize(bytes + pos, bytes_length); + stringtab[i] = string; + pos += bytes_length; + if (unlikely(!string)) { + Py_XDECREF(data); + __PYX_ERR(0, 1, __pyx_L1_error) + } + } + Py_XDECREF(data); + for (Py_ssize_t i = 0; i < 197; i++) { + if (unlikely(PyObject_Hash(stringtab[i]) == -1)) { + __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #if CYTHON_IMMORTAL_CONSTANTS + { + PyObject **table = stringtab + 183; + for (Py_ssize_t i=0; i<14; ++i) { + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL); + #else + Py_SET_REFCNT(table[i], _Py_IMMORTAL_INITIAL_REFCNT); + #endif + } + } + #endif + } + { + PyObject **numbertab = __pyx_mstate->__pyx_number_tab + 0; + int8_t const cint_constants_1[] = {0,1,2,8,10,16}; + for (int i = 0; i < 6; i++) { + numbertab[i] = PyLong_FromLong(cint_constants_1[i - 0]); + if (unlikely(!numbertab[i])) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #if CYTHON_IMMORTAL_CONSTANTS + { + PyObject **table = __pyx_mstate->__pyx_number_tab; + for (Py_ssize_t i=0; i<6; ++i) { + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL); + #else + Py_SET_REFCNT(table[i], _Py_IMMORTAL_INITIAL_REFCNT); + #endif + } + } + #endif + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: init_codeobjects ### */ +typedef struct { + unsigned int argcount : 2; + unsigned int num_posonly_args : 1; + unsigned int num_kwonly_args : 1; + unsigned int nlocals : 4; + unsigned int flags : 10; + unsigned int first_line : 9; +} __Pyx_PyCode_New_function_description; +/* NewCodeObj.proto */ +static PyObject* __Pyx_PyCode_New( + const __Pyx_PyCode_New_function_description descr, + PyObject * const *varnames, + PyObject *filename, + PyObject *funcname, + PyObject *line_table, + PyObject *tuple_dedup_map +); + + +static int __Pyx_CreateCodeObjects(__pyx_mstatetype *__pyx_mstate) { + PyObject* tuple_dedup_map = PyDict_New(); + if (unlikely(!tuple_dedup_map)) return -1; + { + const __Pyx_PyCode_New_function_description descr = {3, 0, 0, 3, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 43}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_text, __pyx_mstate->__pyx_n_u_filename}; + __pyx_mstate_global->__pyx_codeobj_tab[0] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_feaLib_lexer_py, __pyx_mstate->__pyx_n_u_init, __pyx_mstate->__pyx_kp_b_iso88591_A_M_IQ_HA_O1_IQ_Cq_IU, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[0])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 1, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 52}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self}; + __pyx_mstate_global->__pyx_codeobj_tab[1] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_feaLib_lexer_py, __pyx_mstate->__pyx_n_u_iter, __pyx_mstate->__pyx_kp_b_iso88591_A_q, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[1])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 1, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 55}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self}; + __pyx_mstate_global->__pyx_codeobj_tab[2] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_feaLib_lexer_py, __pyx_mstate->__pyx_n_u_next_3, __pyx_mstate->__pyx_kp_b_iso88591_A_t9A, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[2])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 4, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 58}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_token_type, __pyx_mstate->__pyx_n_u_token, __pyx_mstate->__pyx_n_u_location_2}; + __pyx_mstate_global->__pyx_codeobj_tab[3] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_feaLib_lexer_py, __pyx_mstate->__pyx_n_u_next, __pyx_mstate->__pyx_kp_b_iso88591_A_fA_U_G1, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[3])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 2, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 64}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_column}; + __pyx_mstate_global->__pyx_codeobj_tab[4] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_feaLib_lexer_py, __pyx_mstate->__pyx_n_u_location, __pyx_mstate->__pyx_kp_b_iso88591_A_V2T_b_k_N_ha, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[4])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 10, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 68}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_location_2, __pyx_mstate->__pyx_n_u_start, __pyx_mstate->__pyx_n_u_text, __pyx_mstate->__pyx_n_u_limit, __pyx_mstate->__pyx_n_u_cur_char, __pyx_mstate->__pyx_n_u_next_char, __pyx_mstate->__pyx_n_u_glyphclass, __pyx_mstate->__pyx_n_u_token, __pyx_mstate->__pyx_n_u_string}; + __pyx_mstate_global->__pyx_codeobj_tab[5] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_feaLib_lexer_py, __pyx_mstate->__pyx_n_u_next_2, __pyx_mstate->__pyx_kp_b_iso88591_A_Kq_Q_4z_A_t1_1A_6_A_q_4q_D_r_v, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[5])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 3, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 165}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_valid, __pyx_mstate->__pyx_n_u_p}; + __pyx_mstate_global->__pyx_codeobj_tab[6] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_feaLib_lexer_py, __pyx_mstate->__pyx_n_u_scan_over, __pyx_mstate->__pyx_kp_b_iso88591_A_D_b_nD_F_3c_HA, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[6])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 3, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 171}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_stop_at, __pyx_mstate->__pyx_n_u_p}; + __pyx_mstate_global->__pyx_codeobj_tab[7] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_feaLib_lexer_py, __pyx_mstate->__pyx_n_u_scan_until, __pyx_mstate->__pyx_kp_b_iso88591_A_D_b_nD_F_3gQ_HA, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[7])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 5, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 177}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_tag, __pyx_mstate->__pyx_n_u_location_2, __pyx_mstate->__pyx_n_u_regexp, __pyx_mstate->__pyx_n_u_split}; + __pyx_mstate_global->__pyx_codeobj_tab[8] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_feaLib_lexer_py, __pyx_mstate->__pyx_n_u_scan_anonymous_block, __pyx_mstate->__pyx_kp_b_iso88591_A_4z_c_q_L_a_Kq_Q_4r_V1D_1_3awc, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[8])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {2, 0, 1, 3, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 207}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_featurefile, __pyx_mstate->__pyx_n_u_includeDir}; + __pyx_mstate_global->__pyx_codeobj_tab[9] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_feaLib_lexer_py, __pyx_mstate->__pyx_n_u_init, __pyx_mstate->__pyx_kp_b_iso88591_q_Kq_L_t81Ba_N, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[9])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 1, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 221}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self}; + __pyx_mstate_global->__pyx_codeobj_tab[10] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_feaLib_lexer_py, __pyx_mstate->__pyx_n_u_iter, __pyx_mstate->__pyx_kp_b_iso88591_A_q, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[10])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 1, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 224}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self}; + __pyx_mstate_global->__pyx_codeobj_tab[11] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_feaLib_lexer_py, __pyx_mstate->__pyx_n_u_next_3, __pyx_mstate->__pyx_kp_b_iso88591_A_t9A, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[11])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 11, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 227}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_lexer, __pyx_mstate->__pyx_n_u_token_type, __pyx_mstate->__pyx_n_u_token, __pyx_mstate->__pyx_n_u_location_2, __pyx_mstate->__pyx_n_u_fname_type, __pyx_mstate->__pyx_n_u_fname_token, __pyx_mstate->__pyx_n_u_fname_location, __pyx_mstate->__pyx_n_u_path, __pyx_mstate->__pyx_n_u_curpath, __pyx_mstate->__pyx_n_u_err}; + __pyx_mstate_global->__pyx_codeobj_tab[12] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_feaLib_lexer_py, __pyx_mstate->__pyx_n_u_next, __pyx_mstate->__pyx_kp_b_iso88591_A_d_D_G_d_1_HD_U_F_Q_M_uA_gU_2U, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[12])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 5, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 266}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_file_or_path, __pyx_mstate->__pyx_n_u_fileobj, __pyx_mstate->__pyx_n_u_closing, __pyx_mstate->__pyx_n_u_filename, __pyx_mstate->__pyx_n_u_data}; + __pyx_mstate_global->__pyx_codeobj_tab[13] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_feaLib_lexer_py, __pyx_mstate->__pyx_n_u_make_lexer, __pyx_mstate->__pyx_kp_b_iso88591_A_7_Z_Q_j_a_d_U_1_we1_7_9HA_1_6, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[13])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 2, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 279}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_tag}; + __pyx_mstate_global->__pyx_codeobj_tab[14] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_feaLib_lexer_py, __pyx_mstate->__pyx_n_u_scan_anonymous_block, __pyx_mstate->__pyx_kp_b_iso88591_A_t82R_4AQ, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[14])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 1, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 286}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self}; + __pyx_mstate_global->__pyx_codeobj_tab[15] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_feaLib_lexer_py, __pyx_mstate->__pyx_n_u_next, __pyx_mstate->__pyx_kp_b_iso88591_A_t1D, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[15])) goto bad; + } + Py_DECREF(tuple_dedup_map); + return 0; + bad: + Py_DECREF(tuple_dedup_map); + return -1; +} +/* #### Code section: init_globals ### */ + +static int __Pyx_InitGlobals(void) { + /* PythonCompatibility.init */ + if (likely(__Pyx_init_co_variables() == 0)); else + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* CommonTypesMetaclass.init */ + if (likely(__pyx_CommonTypesMetaclass_init(__pyx_m) == 0)); else + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* CachedMethodType.init */ + #if CYTHON_COMPILING_IN_LIMITED_API + { + PyObject *typesModule=NULL; + typesModule = PyImport_ImportModule("types"); + if (typesModule) { + __pyx_mstate_global->__Pyx_CachedMethodType = PyObject_GetAttrString(typesModule, "MethodType"); + Py_DECREF(typesModule); + } + } // error handling follows + #endif + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* CythonFunctionShared.init */ + if (likely(__pyx_CyFunction_init(__pyx_m) == 0)); else + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: cleanup_globals ### */ +/* #### Code section: cleanup_module ### */ +/* #### Code section: main_method ### */ +/* #### Code section: utility_code_pragmas ### */ +#ifdef _MSC_VER +#pragma warning( push ) +/* Warning 4127: conditional expression is constant + * Cython uses constant conditional expressions to allow in inline functions to be optimized at + * compile-time, so this warning is not useful + */ +#pragma warning( disable : 4127 ) +#endif + + + +/* #### Code section: utility_code_def ### */ + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* PyErrExceptionMatches (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); + for (i=0; i= 0x030C00A6 + PyObject *current_exception = tstate->current_exception; + if (unlikely(!current_exception)) return 0; + exc_type = (PyObject*) Py_TYPE(current_exception); + if (exc_type == err) return 1; +#else + exc_type = tstate->curexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; +#endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(exc_type); + #endif + if (unlikely(PyTuple_Check(err))) { + result = __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + } else { + result = __Pyx_PyErr_GivenExceptionMatches(exc_type, err); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(exc_type); + #endif + return result; +} +#endif + +/* PyErrFetchRestore (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject *tmp_value; + assert(type == NULL || (value != NULL && type == (PyObject*) Py_TYPE(value))); + if (value) { + #if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(((PyBaseExceptionObject*) value)->traceback != tb)) + #endif + PyException_SetTraceback(value, tb); + } + tmp_value = tstate->current_exception; + tstate->current_exception = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#endif +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject* exc_value; + exc_value = tstate->current_exception; + tstate->current_exception = 0; + *value = exc_value; + *type = NULL; + *tb = NULL; + if (exc_value) { + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + #if CYTHON_COMPILING_IN_CPYTHON + *tb = ((PyBaseExceptionObject*) exc_value)->traceback; + Py_XINCREF(*tb); + #else + *tb = PyException_GetTraceback(exc_value); + #endif + } +#else + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#endif +} +#endif + +/* PyObjectGetAttrStr (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* PyObjectGetAttrStrNoError (used by GetBuiltinName) */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d0000 +static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + __Pyx_PyErr_Clear(); +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { + PyObject *result; +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + (void) PyObject_GetOptionalAttr(obj, attr_name, &result); + return result; +#else +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { + return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); + } +#endif + result = __Pyx_PyObject_GetAttrStr(obj, attr_name); + if (unlikely(!result)) { + __Pyx_PyObject_GetAttrStr_ClearAttributeError(); + } + return result; +#endif +} + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStrNoError(__pyx_mstate_global->__pyx_b, name); + if (unlikely(!result) && !PyErr_Occurred()) { + PyErr_Format(PyExc_NameError, + "name '%U' is not defined", name); + } + return result; +} + +/* TupleAndListFromArray (used by fastcall) */ +#if !CYTHON_COMPILING_IN_CPYTHON && CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + Py_ssize_t i; + if (n <= 0) { + return __Pyx_NewRef(__pyx_mstate_global->__pyx_empty_tuple); + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + for (i = 0; i < n; i++) { + if (unlikely(__Pyx_PyTuple_SET_ITEM(res, i, src[i]) < (0))) { + Py_DECREF(res); + return NULL; + } + Py_INCREF(src[i]); + } + return res; +} +#elif CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE void __Pyx_copy_object_array(PyObject *const *CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) { + PyObject *v; + Py_ssize_t i; + for (i = 0; i < length; i++) { + v = dest[i] = src[i]; + Py_INCREF(v); + } +} +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return __Pyx_NewRef(__pyx_mstate_global->__pyx_empty_tuple); + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyTupleObject*)res)->ob_item, n); + return res; +} +static CYTHON_INLINE PyObject * +__Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return PyList_New(0); + } + res = PyList_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyListObject*)res)->ob_item, n); + return res; +} +#endif + +/* BytesEquals (used by UnicodeEquals) */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_GRAAL ||\ + !(CYTHON_ASSUME_SAFE_SIZE && CYTHON_ASSUME_SAFE_MACROS) + return PyObject_RichCompareBool(s1, s2, equals); +#else + if (s1 == s2) { + return (equals == Py_EQ); + } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { + const char *ps1, *ps2; + Py_ssize_t length = PyBytes_GET_SIZE(s1); + if (length != PyBytes_GET_SIZE(s2)) + return (equals == Py_NE); + ps1 = PyBytes_AS_STRING(s1); + ps2 = PyBytes_AS_STRING(s2); + if (ps1[0] != ps2[0]) { + return (equals == Py_NE); + } else if (length == 1) { + return (equals == Py_EQ); + } else { + int result; +#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) + Py_hash_t hash1, hash2; + hash1 = ((PyBytesObject*)s1)->ob_shash; + hash2 = ((PyBytesObject*)s2)->ob_shash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + return (equals == Py_NE); + } +#endif + result = memcmp(ps1, ps2, (size_t)length); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { + return (equals == Py_NE); + } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { + return (equals == Py_NE); + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +#endif +} + +/* UnicodeEquals (used by fastcall) */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_GRAAL + return PyObject_RichCompareBool(s1, s2, equals); +#else + int s1_is_unicode, s2_is_unicode; + if (s1 == s2) { + goto return_eq; + } + s1_is_unicode = PyUnicode_CheckExact(s1); + s2_is_unicode = PyUnicode_CheckExact(s2); + if (s1_is_unicode & s2_is_unicode) { + Py_ssize_t length, length2; + int kind; + void *data1, *data2; + #if !CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) + return -1; + #endif + length = __Pyx_PyUnicode_GET_LENGTH(s1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(length < 0)) return -1; + #endif + length2 = __Pyx_PyUnicode_GET_LENGTH(s2); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(length2 < 0)) return -1; + #endif + if (length != length2) { + goto return_ne; + } +#if CYTHON_USE_UNICODE_INTERNALS + { + Py_hash_t hash1, hash2; + hash1 = ((PyASCIIObject*)s1)->hash; + hash2 = ((PyASCIIObject*)s2)->hash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + goto return_ne; + } + } +#endif + kind = __Pyx_PyUnicode_KIND(s1); + if (kind != __Pyx_PyUnicode_KIND(s2)) { + goto return_ne; + } + data1 = __Pyx_PyUnicode_DATA(s1); + data2 = __Pyx_PyUnicode_DATA(s2); + if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { + goto return_ne; + } else if (length == 1) { + goto return_eq; + } else { + int result = memcmp(data1, data2, (size_t)(length * kind)); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & s2_is_unicode) { + goto return_ne; + } else if ((s2 == Py_None) & s1_is_unicode) { + goto return_ne; + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +return_eq: + return (equals == Py_EQ); +return_ne: + return (equals == Py_NE); +#endif +} + +/* fastcall */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s) +{ + Py_ssize_t i, n = __Pyx_PyTuple_GET_SIZE(kwnames); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(n == -1)) return NULL; + #endif + for (i = 0; i < n; i++) + { + PyObject *namei = __Pyx_PyTuple_GET_ITEM(kwnames, i); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(!namei)) return NULL; + #endif + if (s == namei) return kwvalues[i]; + } + for (i = 0; i < n; i++) + { + PyObject *namei = __Pyx_PyTuple_GET_ITEM(kwnames, i); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(!namei)) return NULL; + #endif + int eq = __Pyx_PyUnicode_Equals(s, namei, Py_EQ); + if (unlikely(eq != 0)) { + if (unlikely(eq < 0)) return NULL; + return kwvalues[i]; + } + } + return NULL; +} +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 || CYTHON_COMPILING_IN_LIMITED_API +CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues) { + Py_ssize_t i, nkwargs; + PyObject *dict; +#if !CYTHON_ASSUME_SAFE_SIZE + nkwargs = PyTuple_Size(kwnames); + if (unlikely(nkwargs < 0)) return NULL; +#else + nkwargs = PyTuple_GET_SIZE(kwnames); +#endif + dict = PyDict_New(); + if (unlikely(!dict)) + return NULL; + for (i=0; itp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallMethO (used by PyObjectFastCall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = __Pyx_CyOrPyCFunction_GET_FUNCTION(func); + self = __Pyx_CyOrPyCFunction_GET_SELF(func); + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectFastCall (used by PyObjectCallOneArg) */ +#if PY_VERSION_HEX < 0x03090000 || CYTHON_COMPILING_IN_LIMITED_API +static PyObject* __Pyx_PyObject_FastCall_fallback(PyObject *func, PyObject * const*args, size_t nargs, PyObject *kwargs) { + PyObject *argstuple; + PyObject *result = 0; + size_t i; + argstuple = PyTuple_New((Py_ssize_t)nargs); + if (unlikely(!argstuple)) return NULL; + for (i = 0; i < nargs; i++) { + Py_INCREF(args[i]); + if (__Pyx_PyTuple_SET_ITEM(argstuple, (Py_ssize_t)i, args[i]) != (0)) goto bad; + } + result = __Pyx_PyObject_Call(func, argstuple, kwargs); + bad: + Py_DECREF(argstuple); + return result; +} +#endif +#if CYTHON_VECTORCALL && !CYTHON_COMPILING_IN_LIMITED_API + #if PY_VERSION_HEX < 0x03090000 + #define __Pyx_PyVectorcall_Function(callable) _PyVectorcall_Function(callable) + #elif CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE vectorcallfunc __Pyx_PyVectorcall_Function(PyObject *callable) { + PyTypeObject *tp = Py_TYPE(callable); + #if defined(__Pyx_CyFunction_USED) + if (__Pyx_CyFunction_CheckExact(callable)) { + return __Pyx_CyFunction_func_vectorcall(callable); + } + #endif + if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) { + return NULL; + } + assert(PyCallable_Check(callable)); + Py_ssize_t offset = tp->tp_vectorcall_offset; + assert(offset > 0); + vectorcallfunc ptr; + memcpy(&ptr, (char *) callable + offset, sizeof(ptr)); + return ptr; +} + #else + #define __Pyx_PyVectorcall_Function(callable) PyVectorcall_Function(callable) + #endif +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject *const *args, size_t _nargs, PyObject *kwargs) { + Py_ssize_t nargs = __Pyx_PyVectorcall_NARGS(_nargs); +#if CYTHON_COMPILING_IN_CPYTHON + if (nargs == 0 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_NOARGS)) + return __Pyx_PyObject_CallMethO(func, NULL); + } + else if (nargs == 1 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_O)) + return __Pyx_PyObject_CallMethO(func, args[0]); + } +#endif + if (kwargs == NULL) { + #if CYTHON_VECTORCALL + #if CYTHON_COMPILING_IN_LIMITED_API + return PyObject_Vectorcall(func, args, _nargs, NULL); + #else + vectorcallfunc f = __Pyx_PyVectorcall_Function(func); + if (f) { + return f(func, args, _nargs, NULL); + } + #endif + #endif + } + if (nargs == 0) { + return __Pyx_PyObject_Call(func, __pyx_mstate_global->__pyx_empty_tuple, kwargs); + } + #if PY_VERSION_HEX >= 0x03090000 && !CYTHON_COMPILING_IN_LIMITED_API + return PyObject_VectorcallDict(func, args, (size_t)nargs, kwargs); + #else + return __Pyx_PyObject_FastCall_fallback(func, args, (size_t)nargs, kwargs); + #endif +} + +/* PyObjectCallOneArg (used by CallUnboundCMethod0) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *args[2] = {NULL, arg}; + return __Pyx_PyObject_FastCall(func, args+1, 1 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* UnpackUnboundCMethod (used by CallUnboundCMethod0) */ +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030C0000 +static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject *args, PyObject *kwargs) { + PyObject *result; + PyObject *selfless_args = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); + if (unlikely(!selfless_args)) return NULL; + result = PyObject_Call(method, selfless_args, kwargs); + Py_DECREF(selfless_args); + return result; +} +#elif CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03090000 +static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { + return _PyObject_Vectorcall + (method, args ? args+1 : NULL, nargs ? nargs-1 : 0, kwnames); +} +#else +static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { + return +#if PY_VERSION_HEX < 0x03090000 + _PyObject_Vectorcall +#else + PyObject_Vectorcall +#endif + (method, args ? args+1 : NULL, nargs ? (size_t) nargs-1 : 0, kwnames); +} +#endif +static PyMethodDef __Pyx_UnboundCMethod_Def = { + "CythonUnboundCMethod", + __PYX_REINTERPRET_FUNCION(PyCFunction, __Pyx_SelflessCall), +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030C0000 + METH_VARARGS | METH_KEYWORDS, +#else + METH_FASTCALL | METH_KEYWORDS, +#endif + NULL +}; +static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) { + PyObject *method, *result=NULL; + method = __Pyx_PyObject_GetAttrStr(target->type, *target->method_name); + if (unlikely(!method)) + return -1; + result = method; +#if CYTHON_COMPILING_IN_CPYTHON + if (likely(__Pyx_TypeCheck(method, &PyMethodDescr_Type))) + { + PyMethodDescrObject *descr = (PyMethodDescrObject*) method; + target->func = descr->d_method->ml_meth; + target->flag = descr->d_method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_STACKLESS); + } else +#endif +#if CYTHON_COMPILING_IN_PYPY +#else + if (PyCFunction_Check(method)) +#endif + { + PyObject *self; + int self_found; +#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY + self = PyObject_GetAttrString(method, "__self__"); + if (!self) { + PyErr_Clear(); + } +#else + self = PyCFunction_GET_SELF(method); +#endif + self_found = (self && self != Py_None); +#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY + Py_XDECREF(self); +#endif + if (self_found) { + PyObject *unbound_method = PyCFunction_New(&__Pyx_UnboundCMethod_Def, method); + if (unlikely(!unbound_method)) return -1; + Py_DECREF(method); + result = unbound_method; + } + } +#if !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + if (unlikely(target->method)) { + Py_DECREF(result); + } else +#endif + target->method = result; + return 0; +} + +/* CallUnboundCMethod0 */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self) { + int was_initialized = __Pyx_CachedCFunction_GetAndSetInitializing(cfunc); + if (likely(was_initialized == 2 && cfunc->func)) { + if (likely(cfunc->flag == METH_NOARGS)) + return __Pyx_CallCFunction(cfunc, self, NULL); + if (likely(cfunc->flag == METH_FASTCALL)) + return __Pyx_CallCFunctionFast(cfunc, self, NULL, 0); + if (cfunc->flag == (METH_FASTCALL | METH_KEYWORDS)) + return __Pyx_CallCFunctionFastWithKeywords(cfunc, self, NULL, 0, NULL); + if (likely(cfunc->flag == (METH_VARARGS | METH_KEYWORDS))) + return __Pyx_CallCFunctionWithKeywords(cfunc, self, __pyx_mstate_global->__pyx_empty_tuple, NULL); + if (cfunc->flag == METH_VARARGS) + return __Pyx_CallCFunction(cfunc, self, __pyx_mstate_global->__pyx_empty_tuple); + return __Pyx__CallUnboundCMethod0(cfunc, self); + } +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + else if (unlikely(was_initialized == 1)) { + __Pyx_CachedCFunction tmp_cfunc = { +#ifndef __cplusplus + 0 +#endif + }; + tmp_cfunc.type = cfunc->type; + tmp_cfunc.method_name = cfunc->method_name; + return __Pyx__CallUnboundCMethod0(&tmp_cfunc, self); + } +#endif + PyObject *result = __Pyx__CallUnboundCMethod0(cfunc, self); + __Pyx_CachedCFunction_SetFinishedInitializing(cfunc); + return result; +} +#endif +static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self) { + PyObject *result; + if (unlikely(!cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; + result = __Pyx_PyObject_CallOneArg(cfunc->method, self); + return result; +} + +/* py_dict_items (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d) { + return __Pyx_CallUnboundCMethod0(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_items, d); +} + +/* py_dict_values (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Values(PyObject* d) { + return __Pyx_CallUnboundCMethod0(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_values, d); +} + +/* OwnedDictNext (used by ParseKeywordsImpl) */ +#if CYTHON_AVOID_BORROWED_REFS +static int __Pyx_PyDict_NextRef(PyObject *p, PyObject **ppos, PyObject **pkey, PyObject **pvalue) { + PyObject *next = NULL; + if (!*ppos) { + if (pvalue) { + PyObject *dictview = pkey ? __Pyx_PyDict_Items(p) : __Pyx_PyDict_Values(p); + if (unlikely(!dictview)) goto bad; + *ppos = PyObject_GetIter(dictview); + Py_DECREF(dictview); + } else { + *ppos = PyObject_GetIter(p); + } + if (unlikely(!*ppos)) goto bad; + } + next = PyIter_Next(*ppos); + if (!next) { + if (PyErr_Occurred()) goto bad; + return 0; + } + if (pkey && pvalue) { + *pkey = __Pyx_PySequence_ITEM(next, 0); + if (unlikely(*pkey)) goto bad; + *pvalue = __Pyx_PySequence_ITEM(next, 1); + if (unlikely(*pvalue)) goto bad; + Py_DECREF(next); + } else if (pkey) { + *pkey = next; + } else { + assert(pvalue); + *pvalue = next; + } + return 1; + bad: + Py_XDECREF(next); +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d0000 + PyErr_FormatUnraisable("Exception ignored in __Pyx_PyDict_NextRef"); +#else + PyErr_WriteUnraisable(__pyx_mstate_global->__pyx_n_u_Pyx_PyDict_NextRef); +#endif + if (pkey) *pkey = NULL; + if (pvalue) *pvalue = NULL; + return 0; +} +#else // !CYTHON_AVOID_BORROWED_REFS +static int __Pyx_PyDict_NextRef(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) { + int result = PyDict_Next(p, ppos, pkey, pvalue); + if (likely(result == 1)) { + if (pkey) Py_INCREF(*pkey); + if (pvalue) Py_INCREF(*pvalue); + } + return result; +} +#endif + +/* RaiseDoubleKeywords (used by ParseKeywordsImpl) */ +static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); +} + +/* CallUnboundCMethod2 */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject *__Pyx_CallUnboundCMethod2(__Pyx_CachedCFunction *cfunc, PyObject *self, PyObject *arg1, PyObject *arg2) { + int was_initialized = __Pyx_CachedCFunction_GetAndSetInitializing(cfunc); + if (likely(was_initialized == 2 && cfunc->func)) { + PyObject *args[2] = {arg1, arg2}; + if (cfunc->flag == METH_FASTCALL) { + return __Pyx_CallCFunctionFast(cfunc, self, args, 2); + } + if (cfunc->flag == (METH_FASTCALL | METH_KEYWORDS)) + return __Pyx_CallCFunctionFastWithKeywords(cfunc, self, args, 2, NULL); + } +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + else if (unlikely(was_initialized == 1)) { + __Pyx_CachedCFunction tmp_cfunc = { +#ifndef __cplusplus + 0 +#endif + }; + tmp_cfunc.type = cfunc->type; + tmp_cfunc.method_name = cfunc->method_name; + return __Pyx__CallUnboundCMethod2(&tmp_cfunc, self, arg1, arg2); + } +#endif + PyObject *result = __Pyx__CallUnboundCMethod2(cfunc, self, arg1, arg2); + __Pyx_CachedCFunction_SetFinishedInitializing(cfunc); + return result; +} +#endif +static PyObject* __Pyx__CallUnboundCMethod2(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg1, PyObject* arg2){ + if (unlikely(!cfunc->func && !cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; +#if CYTHON_COMPILING_IN_CPYTHON + if (cfunc->func && (cfunc->flag & METH_VARARGS)) { + PyObject *result = NULL; + PyObject *args = PyTuple_New(2); + if (unlikely(!args)) return NULL; + Py_INCREF(arg1); + PyTuple_SET_ITEM(args, 0, arg1); + Py_INCREF(arg2); + PyTuple_SET_ITEM(args, 1, arg2); + if (cfunc->flag & METH_KEYWORDS) + result = __Pyx_CallCFunctionWithKeywords(cfunc, self, args, NULL); + else + result = __Pyx_CallCFunction(cfunc, self, args); + Py_DECREF(args); + return result; + } +#endif + { + PyObject *args[4] = {NULL, self, arg1, arg2}; + return __Pyx_PyObject_FastCall(cfunc->method, args+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); + } +} + +/* ParseKeywordsImpl (used by ParseKeywords) */ +static int __Pyx_ValidateDuplicatePosArgs( + PyObject *kwds, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + const char* function_name) +{ + PyObject ** const *name = argnames; + while (name != first_kw_arg) { + PyObject *key = **name; + int found = PyDict_Contains(kwds, key); + if (unlikely(found)) { + if (found == 1) __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; + } + name++; + } + return 0; +bad: + return -1; +} +#if CYTHON_USE_UNICODE_INTERNALS +static CYTHON_INLINE int __Pyx_UnicodeKeywordsEqual(PyObject *s1, PyObject *s2) { + int kind; + Py_ssize_t len = PyUnicode_GET_LENGTH(s1); + if (len != PyUnicode_GET_LENGTH(s2)) return 0; + kind = PyUnicode_KIND(s1); + if (kind != PyUnicode_KIND(s2)) return 0; + const void *data1 = PyUnicode_DATA(s1); + const void *data2 = PyUnicode_DATA(s2); + return (memcmp(data1, data2, (size_t) len * (size_t) kind) == 0); +} +#endif +static int __Pyx_MatchKeywordArg_str( + PyObject *key, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + size_t *index_found, + const char *function_name) +{ + PyObject ** const *name; + #if CYTHON_USE_UNICODE_INTERNALS + Py_hash_t key_hash = ((PyASCIIObject*)key)->hash; + if (unlikely(key_hash == -1)) { + key_hash = PyObject_Hash(key); + if (unlikely(key_hash == -1)) + goto bad; + } + #endif + name = first_kw_arg; + while (*name) { + PyObject *name_str = **name; + #if CYTHON_USE_UNICODE_INTERNALS + if (key_hash == ((PyASCIIObject*)name_str)->hash && __Pyx_UnicodeKeywordsEqual(name_str, key)) { + *index_found = (size_t) (name - argnames); + return 1; + } + #else + #if CYTHON_ASSUME_SAFE_SIZE + if (PyUnicode_GET_LENGTH(name_str) == PyUnicode_GET_LENGTH(key)) + #endif + { + int cmp = PyUnicode_Compare(name_str, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + *index_found = (size_t) (name - argnames); + return 1; + } + } + #endif + name++; + } + name = argnames; + while (name != first_kw_arg) { + PyObject *name_str = **name; + #if CYTHON_USE_UNICODE_INTERNALS + if (unlikely(key_hash == ((PyASCIIObject*)name_str)->hash)) { + if (__Pyx_UnicodeKeywordsEqual(name_str, key)) + goto arg_passed_twice; + } + #else + #if CYTHON_ASSUME_SAFE_SIZE + if (PyUnicode_GET_LENGTH(name_str) == PyUnicode_GET_LENGTH(key)) + #endif + { + if (unlikely(name_str == key)) goto arg_passed_twice; + int cmp = PyUnicode_Compare(name_str, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + } + #endif + name++; + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +bad: + return -1; +} +static int __Pyx_MatchKeywordArg_nostr( + PyObject *key, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + size_t *index_found, + const char *function_name) +{ + PyObject ** const *name; + if (unlikely(!PyUnicode_Check(key))) goto invalid_keyword_type; + name = first_kw_arg; + while (*name) { + int cmp = PyObject_RichCompareBool(**name, key, Py_EQ); + if (cmp == 1) { + *index_found = (size_t) (name - argnames); + return 1; + } + if (unlikely(cmp == -1)) goto bad; + name++; + } + name = argnames; + while (name != first_kw_arg) { + int cmp = PyObject_RichCompareBool(**name, key, Py_EQ); + if (unlikely(cmp != 0)) { + if (cmp == 1) goto arg_passed_twice; + else goto bad; + } + name++; + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +bad: + return -1; +} +static CYTHON_INLINE int __Pyx_MatchKeywordArg( + PyObject *key, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + size_t *index_found, + const char *function_name) +{ + return likely(PyUnicode_CheckExact(key)) ? + __Pyx_MatchKeywordArg_str(key, argnames, first_kw_arg, index_found, function_name) : + __Pyx_MatchKeywordArg_nostr(key, argnames, first_kw_arg, index_found, function_name); +} +static void __Pyx_RejectUnknownKeyword( + PyObject *kwds, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + const char *function_name) +{ + #if CYTHON_AVOID_BORROWED_REFS + PyObject *pos = NULL; + #else + Py_ssize_t pos = 0; + #endif + PyObject *key = NULL; + __Pyx_BEGIN_CRITICAL_SECTION(kwds); + while ( + #if CYTHON_AVOID_BORROWED_REFS + __Pyx_PyDict_NextRef(kwds, &pos, &key, NULL) + #else + PyDict_Next(kwds, &pos, &key, NULL) + #endif + ) { + PyObject** const *name = first_kw_arg; + while (*name && (**name != key)) name++; + if (!*name) { + size_t index_found = 0; + int cmp = __Pyx_MatchKeywordArg(key, argnames, first_kw_arg, &index_found, function_name); + if (cmp != 1) { + if (cmp == 0) { + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(key); + #endif + break; + } + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(key); + #endif + } + __Pyx_END_CRITICAL_SECTION(); + #if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(pos); + #endif + assert(PyErr_Occurred()); +} +static int __Pyx_ParseKeywordDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs) +{ + PyObject** const *name; + PyObject** const *first_kw_arg = argnames + num_pos_args; + Py_ssize_t extracted = 0; +#if !CYTHON_COMPILING_IN_PYPY || defined(PyArg_ValidateKeywordArguments) + if (unlikely(!PyArg_ValidateKeywordArguments(kwds))) return -1; +#endif + name = first_kw_arg; + while (*name && num_kwargs > extracted) { + PyObject * key = **name; + PyObject *value; + int found = 0; + #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + found = PyDict_GetItemRef(kwds, key, &value); + #else + value = PyDict_GetItemWithError(kwds, key); + if (value) { + Py_INCREF(value); + found = 1; + } else { + if (unlikely(PyErr_Occurred())) goto bad; + } + #endif + if (found) { + if (unlikely(found < 0)) goto bad; + values[name-argnames] = value; + extracted++; + } + name++; + } + if (num_kwargs > extracted) { + if (ignore_unknown_kwargs) { + if (unlikely(__Pyx_ValidateDuplicatePosArgs(kwds, argnames, first_kw_arg, function_name) == -1)) + goto bad; + } else { + __Pyx_RejectUnknownKeyword(kwds, argnames, first_kw_arg, function_name); + goto bad; + } + } + return 0; +bad: + return -1; +} +static int __Pyx_ParseKeywordDictToDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject** const *name; + PyObject** const *first_kw_arg = argnames + num_pos_args; + Py_ssize_t len; +#if !CYTHON_COMPILING_IN_PYPY || defined(PyArg_ValidateKeywordArguments) + if (unlikely(!PyArg_ValidateKeywordArguments(kwds))) return -1; +#endif + if (PyDict_Update(kwds2, kwds) < 0) goto bad; + name = first_kw_arg; + while (*name) { + PyObject *key = **name; + PyObject *value; +#if !CYTHON_COMPILING_IN_LIMITED_API && (PY_VERSION_HEX >= 0x030d00A2 || defined(PyDict_Pop)) + int found = PyDict_Pop(kwds2, key, &value); + if (found) { + if (unlikely(found < 0)) goto bad; + values[name-argnames] = value; + } +#elif __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + int found = PyDict_GetItemRef(kwds2, key, &value); + if (found) { + if (unlikely(found < 0)) goto bad; + values[name-argnames] = value; + if (unlikely(PyDict_DelItem(kwds2, key) < 0)) goto bad; + } +#else + #if CYTHON_COMPILING_IN_CPYTHON + value = _PyDict_Pop(kwds2, key, kwds2); + #else + value = __Pyx_CallUnboundCMethod2(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_pop, kwds2, key, kwds2); + #endif + if (value == kwds2) { + Py_DECREF(value); + } else { + if (unlikely(!value)) goto bad; + values[name-argnames] = value; + } +#endif + name++; + } + len = PyDict_Size(kwds2); + if (len > 0) { + return __Pyx_ValidateDuplicatePosArgs(kwds, argnames, first_kw_arg, function_name); + } else if (unlikely(len == -1)) { + goto bad; + } + return 0; +bad: + return -1; +} +static int __Pyx_ParseKeywordsTuple( + PyObject *kwds, + PyObject * const *kwvalues, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs) +{ + PyObject *key = NULL; + PyObject** const * name; + PyObject** const *first_kw_arg = argnames + num_pos_args; + for (Py_ssize_t pos = 0; pos < num_kwargs; pos++) { +#if CYTHON_AVOID_BORROWED_REFS + key = __Pyx_PySequence_ITEM(kwds, pos); +#else + key = __Pyx_PyTuple_GET_ITEM(kwds, pos); +#endif +#if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(!key)) goto bad; +#endif + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + PyObject *value = kwvalues[pos]; + values[name-argnames] = __Pyx_NewRef(value); + } else { + size_t index_found = 0; + int cmp = __Pyx_MatchKeywordArg(key, argnames, first_kw_arg, &index_found, function_name); + if (cmp == 1) { + PyObject *value = kwvalues[pos]; + values[index_found] = __Pyx_NewRef(value); + } else { + if (unlikely(cmp == -1)) goto bad; + if (kwds2) { + PyObject *value = kwvalues[pos]; + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else if (!ignore_unknown_kwargs) { + goto invalid_keyword; + } + } + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(key); + key = NULL; + #endif + } + return 0; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + goto bad; +bad: + #if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(key); + #endif + return -1; +} + +/* ParseKeywords */ +static int __Pyx_ParseKeywords( + PyObject *kwds, + PyObject * const *kwvalues, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs) +{ + if (CYTHON_METH_FASTCALL && likely(PyTuple_Check(kwds))) + return __Pyx_ParseKeywordsTuple(kwds, kwvalues, argnames, kwds2, values, num_pos_args, num_kwargs, function_name, ignore_unknown_kwargs); + else if (kwds2) + return __Pyx_ParseKeywordDictToDict(kwds, argnames, kwds2, values, num_pos_args, function_name); + else + return __Pyx_ParseKeywordDict(kwds, argnames, values, num_pos_args, num_kwargs, function_name, ignore_unknown_kwargs); +} + +/* RaiseArgTupleInvalid */ +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* PyObjectSetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr_name, PyObject* value) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_setattro)) + return tp->tp_setattro(obj, attr_name, value); + return PyObject_SetAttr(obj, attr_name, value); +} +#endif + +/* PyDictVersioning (used by GetModuleGlobalName) */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* GetModuleGlobalName */ +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ + PyObject *result; +#if CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(!__pyx_m)) { + if (!PyErr_Occurred()) + PyErr_SetNone(PyExc_NameError); + return NULL; + } + result = PyObject_GetAttr(__pyx_m, name); + if (likely(result)) { + return result; + } + PyErr_Clear(); +#elif CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + if (unlikely(__Pyx_PyDict_GetItemRef(__pyx_mstate_global->__pyx_d, name, &result) == -1)) PyErr_Clear(); + __PYX_UPDATE_DICT_CACHE(__pyx_mstate_global->__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return result; + } +#else + result = _PyDict_GetItem_KnownHash(__pyx_mstate_global->__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_mstate_global->__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); +} + +/* PyObjectFastCallMethod */ +#if !CYTHON_VECTORCALL || PY_VERSION_HEX < 0x03090000 +static PyObject *__Pyx_PyObject_FastCallMethod(PyObject *name, PyObject *const *args, size_t nargsf) { + PyObject *result; + PyObject *attr = PyObject_GetAttr(args[0], name); + if (unlikely(!attr)) + return NULL; + result = __Pyx_PyObject_FastCall(attr, args+1, nargsf - 1); + Py_DECREF(attr); + return result; +} +#endif + +/* RaiseTooManyValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +/* RaiseNeedMoreValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +/* IterFinish */ +static CYTHON_INLINE int __Pyx_IterFinish(void) { + PyObject* exc_type; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + exc_type = __Pyx_PyErr_CurrentExceptionType(); + if (unlikely(exc_type)) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) + return -1; + __Pyx_PyErr_Clear(); + return 0; + } + return 0; +} + +/* UnpackItemEndCheck */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { + if (unlikely(retval)) { + Py_DECREF(retval); + __Pyx_RaiseTooManyValuesError(expected); + return -1; + } + return __Pyx_IterFinish(); +} + +/* PyLongBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_Fallback___Pyx_PyLong_AddObjC(PyObject *op1, PyObject *op2, int inplace) { + return (inplace ? PyNumber_InPlaceAdd : PyNumber_Add)(op1, op2); +} +#if CYTHON_USE_PYLONG_INTERNALS +static PyObject* __Pyx_Unpacked___Pyx_PyLong_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + const long b = intval; + long a; + const PY_LONG_LONG llb = intval; + PY_LONG_LONG lla; + if (unlikely(__Pyx_PyLong_IsZero(op1))) { + return __Pyx_NewRef(op2); + } + const int is_positive = __Pyx_PyLong_IsPos(op1); + const digit* digits = __Pyx_PyLong_Digits(op1); + const Py_ssize_t size = __Pyx_PyLong_DigitCount(op1); + if (likely(size == 1)) { + a = (long) digits[0]; + if (!is_positive) a *= -1; + } else { + switch (size) { + case 2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) a *= -1; + goto calculate_long; + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + if (!is_positive) lla *= -1; + goto calculate_long_long; + } + break; + case 3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) a *= -1; + goto calculate_long; + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + if (!is_positive) lla *= -1; + goto calculate_long_long; + } + break; + case 4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) a *= -1; + goto calculate_long; + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + if (!is_positive) lla *= -1; + goto calculate_long_long; + } + break; + } + return PyLong_Type.tp_as_number->nb_add(op1, op2); + } + calculate_long: + { + long x; + x = a + b; + return PyLong_FromLong(x); + } + calculate_long_long: + { + PY_LONG_LONG llx; + llx = lla + llb; + return PyLong_FromLongLong(llx); + } + +} +#endif +static PyObject* __Pyx_Float___Pyx_PyLong_AddObjC(PyObject *float_val, long intval, int zerodivision_check) { + CYTHON_UNUSED_VAR(zerodivision_check); + const long b = intval; + double a = __Pyx_PyFloat_AS_DOUBLE(float_val); + double result; + + result = ((double)a) + (double)b; + return PyFloat_FromDouble(result); +} +static CYTHON_INLINE PyObject* __Pyx_PyLong_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_UNUSED_VAR(zerodivision_check); + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op1))) { + return __Pyx_Unpacked___Pyx_PyLong_AddObjC(op1, op2, intval, inplace, zerodivision_check); + } + #endif + if (PyFloat_CheckExact(op1)) { + return __Pyx_Float___Pyx_PyLong_AddObjC(op1, intval, zerodivision_check); + } + return __Pyx_Fallback___Pyx_PyLong_AddObjC(op1, op2, inplace); +} +#endif + +/* RaiseException */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyException_SetTraceback(value, tb); +#elif CYTHON_FAST_THREAD_STATE + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} + +/* GetItemInt */ +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { + PyObject *r; + if (unlikely(!j)) return NULL; + r = PyObject_GetItem(o, j); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck, int unsafe_shared) { + CYTHON_MAYBE_UNUSED_VAR(unsafe_shared); +#if CYTHON_ASSUME_SAFE_SIZE + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyList_GET_SIZE(o); + } + if ((CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS || !CYTHON_ASSUME_SAFE_MACROS)) { + return __Pyx_PyList_GetItemRefFast(o, wrapped_i, unsafe_shared); + } else + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { + return __Pyx_NewRef(PyList_GET_ITEM(o, wrapped_i)); + } + return __Pyx_GetItemInt_Generic(o, PyLong_FromSsize_t(i)); +#else + (void)wraparound; + (void)boundscheck; + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck, int unsafe_shared) { + CYTHON_MAYBE_UNUSED_VAR(unsafe_shared); +#if CYTHON_ASSUME_SAFE_SIZE && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyTuple_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { + return __Pyx_NewRef(PyTuple_GET_ITEM(o, wrapped_i)); + } + return __Pyx_GetItemInt_Generic(o, PyLong_FromSsize_t(i)); +#else + (void)wraparound; + (void)boundscheck; + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, + int wraparound, int boundscheck, int unsafe_shared) { + CYTHON_MAYBE_UNUSED_VAR(unsafe_shared); +#if CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); + if ((CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS)) { + return __Pyx_PyList_GetItemRefFast(o, n, unsafe_shared); + } else if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { + return __Pyx_NewRef(PyList_GET_ITEM(o, n)); + } + } else + #if !CYTHON_AVOID_BORROWED_REFS + if (PyTuple_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { + return __Pyx_NewRef(PyTuple_GET_ITEM(o, n)); + } + } else + #endif +#endif +#if CYTHON_USE_TYPE_SLOTS && !CYTHON_COMPILING_IN_PYPY + { + PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping; + PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence; + if (!is_list && mm && mm->mp_subscript) { + PyObject *r, *key = PyLong_FromSsize_t(i); + if (unlikely(!key)) return NULL; + r = mm->mp_subscript(o, key); + Py_DECREF(key); + return r; + } + if (is_list || likely(sm && sm->sq_item)) { + if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) { + Py_ssize_t l = sm->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); + } + } + return sm->sq_item(o, i); + } + } +#else + if (is_list || !PyMapping_Check(o)) { + return PySequence_GetItem(o, i); + } +#endif + (void)wraparound; + (void)boundscheck; + return __Pyx_GetItemInt_Generic(o, PyLong_FromSsize_t(i)); +} + +/* ObjectGetItem */ +#if CYTHON_USE_TYPE_SLOTS +static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject *index) { + PyObject *runerr = NULL; + Py_ssize_t key_value; + key_value = __Pyx_PyIndex_AsSsize_t(index); + if (likely(key_value != -1 || !(runerr = PyErr_Occurred()))) { + return __Pyx_GetItemInt_Fast(obj, key_value, 0, 1, 1, 1); + } + if (PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { + __Pyx_TypeName index_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(index)); + PyErr_Clear(); + PyErr_Format(PyExc_IndexError, + "cannot fit '" __Pyx_FMT_TYPENAME "' into an index-sized integer", index_type_name); + __Pyx_DECREF_TypeName(index_type_name); + } + return NULL; +} +static PyObject *__Pyx_PyObject_GetItem_Slow(PyObject *obj, PyObject *key) { + __Pyx_TypeName obj_type_name; + if (likely(PyType_Check(obj))) { + PyObject *meth = __Pyx_PyObject_GetAttrStrNoError(obj, __pyx_mstate_global->__pyx_n_u_class_getitem); + if (!meth) { + PyErr_Clear(); + } else { + PyObject *result = __Pyx_PyObject_CallOneArg(meth, key); + Py_DECREF(meth); + return result; + } + } + obj_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, + "'" __Pyx_FMT_TYPENAME "' object is not subscriptable", obj_type_name); + __Pyx_DECREF_TypeName(obj_type_name); + return NULL; +} +static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject *key) { + PyTypeObject *tp = Py_TYPE(obj); + PyMappingMethods *mm = tp->tp_as_mapping; + PySequenceMethods *sm = tp->tp_as_sequence; + if (likely(mm && mm->mp_subscript)) { + return mm->mp_subscript(obj, key); + } + if (likely(sm && sm->sq_item)) { + return __Pyx_PyObject_GetIndex(obj, key); + } + return __Pyx_PyObject_GetItem_Slow(obj, key); +} +#endif + +/* SliceObject */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(PyObject* obj, + Py_ssize_t cstart, Py_ssize_t cstop, + PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice, + int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) { + __Pyx_TypeName obj_type_name; +#if CYTHON_USE_TYPE_SLOTS + PyMappingMethods* mp = Py_TYPE(obj)->tp_as_mapping; + if (likely(mp && mp->mp_subscript)) +#endif + { + PyObject* result; + PyObject *py_slice, *py_start, *py_stop; + if (_py_slice) { + py_slice = *_py_slice; + } else { + PyObject* owned_start = NULL; + PyObject* owned_stop = NULL; + if (_py_start) { + py_start = *_py_start; + } else { + if (has_cstart) { + owned_start = py_start = PyLong_FromSsize_t(cstart); + if (unlikely(!py_start)) goto bad; + } else + py_start = Py_None; + } + if (_py_stop) { + py_stop = *_py_stop; + } else { + if (has_cstop) { + owned_stop = py_stop = PyLong_FromSsize_t(cstop); + if (unlikely(!py_stop)) { + Py_XDECREF(owned_start); + goto bad; + } + } else + py_stop = Py_None; + } + py_slice = PySlice_New(py_start, py_stop, Py_None); + Py_XDECREF(owned_start); + Py_XDECREF(owned_stop); + if (unlikely(!py_slice)) goto bad; + } +#if CYTHON_USE_TYPE_SLOTS + result = mp->mp_subscript(obj, py_slice); +#else + result = PyObject_GetItem(obj, py_slice); +#endif + if (!_py_slice) { + Py_DECREF(py_slice); + } + return result; + } + obj_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, + "'" __Pyx_FMT_TYPENAME "' object is unsliceable", obj_type_name); + __Pyx_DECREF_TypeName(obj_type_name); +bad: + return NULL; +} + +/* PyLongBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_Fallback___Pyx_PyLong_SubtractObjC(PyObject *op1, PyObject *op2, int inplace) { + return (inplace ? PyNumber_InPlaceSubtract : PyNumber_Subtract)(op1, op2); +} +#if CYTHON_USE_PYLONG_INTERNALS +static PyObject* __Pyx_Unpacked___Pyx_PyLong_SubtractObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + const long b = intval; + long a; + const PY_LONG_LONG llb = intval; + PY_LONG_LONG lla; + if (unlikely(__Pyx_PyLong_IsZero(op1))) { + return PyLong_FromLong(-intval); + } + const int is_positive = __Pyx_PyLong_IsPos(op1); + const digit* digits = __Pyx_PyLong_Digits(op1); + const Py_ssize_t size = __Pyx_PyLong_DigitCount(op1); + if (likely(size == 1)) { + a = (long) digits[0]; + if (!is_positive) a *= -1; + } else { + switch (size) { + case 2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) a *= -1; + goto calculate_long; + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + if (!is_positive) lla *= -1; + goto calculate_long_long; + } + break; + case 3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) a *= -1; + goto calculate_long; + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + if (!is_positive) lla *= -1; + goto calculate_long_long; + } + break; + case 4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) a *= -1; + goto calculate_long; + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + if (!is_positive) lla *= -1; + goto calculate_long_long; + } + break; + } + return PyLong_Type.tp_as_number->nb_subtract(op1, op2); + } + calculate_long: + { + long x; + x = a - b; + return PyLong_FromLong(x); + } + calculate_long_long: + { + PY_LONG_LONG llx; + llx = lla - llb; + return PyLong_FromLongLong(llx); + } + +} +#endif +static PyObject* __Pyx_Float___Pyx_PyLong_SubtractObjC(PyObject *float_val, long intval, int zerodivision_check) { + CYTHON_UNUSED_VAR(zerodivision_check); + const long b = intval; + double a = __Pyx_PyFloat_AS_DOUBLE(float_val); + double result; + + result = ((double)a) - (double)b; + return PyFloat_FromDouble(result); +} +static CYTHON_INLINE PyObject* __Pyx_PyLong_SubtractObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_UNUSED_VAR(zerodivision_check); + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op1))) { + return __Pyx_Unpacked___Pyx_PyLong_SubtractObjC(op1, op2, intval, inplace, zerodivision_check); + } + #endif + if (PyFloat_CheckExact(op1)) { + return __Pyx_Float___Pyx_PyLong_SubtractObjC(op1, intval, zerodivision_check); + } + return __Pyx_Fallback___Pyx_PyLong_SubtractObjC(op1, op2, inplace); +} +#endif + +/* pybytes_as_double (used by pynumber_float) */ +static double __Pyx_SlowPyString_AsDouble(PyObject *obj) { + PyObject *float_value = PyFloat_FromString(obj); + if (likely(float_value)) { + double value = __Pyx_PyFloat_AS_DOUBLE(float_value); + Py_DECREF(float_value); + return value; + } + return (double)-1; +} +static const char* __Pyx__PyBytes_AsDouble_Copy(const char* start, char* buffer, Py_ssize_t length) { + int last_was_punctuation = 1; + int parse_error_found = 0; + Py_ssize_t i; + for (i=0; i < length; i++) { + char chr = start[i]; + int is_punctuation = (chr == '_') | (chr == '.') | (chr == 'e') | (chr == 'E'); + *buffer = chr; + buffer += (chr != '_'); + parse_error_found |= last_was_punctuation & is_punctuation; + last_was_punctuation = is_punctuation; + } + parse_error_found |= last_was_punctuation; + *buffer = '\0'; + return unlikely(parse_error_found) ? NULL : buffer; +} +static double __Pyx__PyBytes_AsDouble_inf_nan(const char* start, Py_ssize_t length) { + int matches = 1; + char sign = start[0]; + int is_signed = (sign == '+') | (sign == '-'); + start += is_signed; + length -= is_signed; + switch (start[0]) { + #ifdef Py_NAN + case 'n': + case 'N': + if (unlikely(length != 3)) goto parse_failure; + matches &= (start[1] == 'a' || start[1] == 'A'); + matches &= (start[2] == 'n' || start[2] == 'N'); + if (unlikely(!matches)) goto parse_failure; + return (sign == '-') ? -Py_NAN : Py_NAN; + #endif + case 'i': + case 'I': + if (unlikely(length < 3)) goto parse_failure; + matches &= (start[1] == 'n' || start[1] == 'N'); + matches &= (start[2] == 'f' || start[2] == 'F'); + if (likely(length == 3 && matches)) + return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL; + if (unlikely(length != 8)) goto parse_failure; + matches &= (start[3] == 'i' || start[3] == 'I'); + matches &= (start[4] == 'n' || start[4] == 'N'); + matches &= (start[5] == 'i' || start[5] == 'I'); + matches &= (start[6] == 't' || start[6] == 'T'); + matches &= (start[7] == 'y' || start[7] == 'Y'); + if (unlikely(!matches)) goto parse_failure; + return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL; + case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + break; + default: + goto parse_failure; + } + return 0.0; +parse_failure: + return -1.0; +} +static CYTHON_INLINE int __Pyx__PyBytes_AsDouble_IsSpace(char ch) { + return (ch == 0x20) | !((ch < 0x9) | (ch > 0xd)); +} +CYTHON_UNUSED static double __Pyx__PyBytes_AsDouble(PyObject *obj, const char* start, Py_ssize_t length) { + double value; + Py_ssize_t i, digits; + const char *last = start + length; + char *end; + while (__Pyx__PyBytes_AsDouble_IsSpace(*start)) + start++; + while (start < last - 1 && __Pyx__PyBytes_AsDouble_IsSpace(last[-1])) + last--; + length = last - start; + if (unlikely(length <= 0)) goto fallback; + value = __Pyx__PyBytes_AsDouble_inf_nan(start, length); + if (unlikely(value == -1.0)) goto fallback; + if (value != 0.0) return value; + digits = 0; + for (i=0; i < length; digits += start[i++] != '_'); + if (likely(digits == length)) { + value = PyOS_string_to_double(start, &end, NULL); + } else if (digits < 40) { + char number[40]; + last = __Pyx__PyBytes_AsDouble_Copy(start, number, length); + if (unlikely(!last)) goto fallback; + value = PyOS_string_to_double(number, &end, NULL); + } else { + char *number = (char*) PyMem_Malloc((digits + 1) * sizeof(char)); + if (unlikely(!number)) goto fallback; + last = __Pyx__PyBytes_AsDouble_Copy(start, number, length); + if (unlikely(!last)) { + PyMem_Free(number); + goto fallback; + } + value = PyOS_string_to_double(number, &end, NULL); + PyMem_Free(number); + } + if (likely(end == last) || (value == (double)-1 && PyErr_Occurred())) { + return value; + } +fallback: + return __Pyx_SlowPyString_AsDouble(obj); +} + +/* pynumber_float */ +static CYTHON_INLINE PyObject* __Pyx__PyNumber_Float(PyObject* obj) { + double val; + if (PyLong_CheckExact(obj)) { +#if CYTHON_USE_PYLONG_INTERNALS + if (likely(__Pyx_PyLong_IsCompact(obj))) { + val = (double) __Pyx_PyLong_CompactValue(obj); + goto no_error; + } +#endif + val = PyLong_AsDouble(obj); + } else if (PyUnicode_CheckExact(obj)) { + val = __Pyx_PyUnicode_AsDouble(obj); + } else if (PyBytes_CheckExact(obj)) { + val = __Pyx_PyBytes_AsDouble(obj); + } else if (PyByteArray_CheckExact(obj)) { + val = __Pyx_PyByteArray_AsDouble(obj); + } else { + return PyNumber_Float(obj); + } + if (unlikely(val == -1 && PyErr_Occurred())) { + return NULL; + } +#if CYTHON_USE_PYLONG_INTERNALS +no_error: +#endif + return PyFloat_FromDouble(val); +} + +/* PyObjectVectorCallKwBuilder */ +#if CYTHON_VECTORCALL +static int __Pyx_VectorcallBuilder_AddArg(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n) { + (void)__Pyx_PyObject_FastCallDict; + if (__Pyx_PyTuple_SET_ITEM(builder, n, key) != (0)) return -1; + Py_INCREF(key); + args[n] = value; + return 0; +} +CYTHON_UNUSED static int __Pyx_VectorcallBuilder_AddArg_Check(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n) { + (void)__Pyx_VectorcallBuilder_AddArgStr; + if (unlikely(!PyUnicode_Check(key))) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + return -1; + } + return __Pyx_VectorcallBuilder_AddArg(key, value, builder, args, n); +} +static int __Pyx_VectorcallBuilder_AddArgStr(const char *key, PyObject *value, PyObject *builder, PyObject **args, int n) { + PyObject *pyKey = PyUnicode_FromString(key); + if (!pyKey) return -1; + return __Pyx_VectorcallBuilder_AddArg(pyKey, value, builder, args, n); +} +#else // CYTHON_VECTORCALL +CYTHON_UNUSED static int __Pyx_VectorcallBuilder_AddArg_Check(PyObject *key, PyObject *value, PyObject *builder, CYTHON_UNUSED PyObject **args, CYTHON_UNUSED int n) { + if (unlikely(!PyUnicode_Check(key))) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + return -1; + } + return PyDict_SetItem(builder, key, value); +} +#endif + +/* IterNextPlain (used by IterNext) */ +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 +static PyObject *__Pyx_GetBuiltinNext_LimitedAPI(void) { + if (unlikely(!__pyx_mstate_global->__Pyx_GetBuiltinNext_LimitedAPI_cache)) + __pyx_mstate_global->__Pyx_GetBuiltinNext_LimitedAPI_cache = __Pyx_GetBuiltinName(__pyx_mstate_global->__pyx_n_u_next_3); + return __pyx_mstate_global->__Pyx_GetBuiltinNext_LimitedAPI_cache; +} +#endif +static CYTHON_INLINE PyObject *__Pyx_PyIter_Next_Plain(PyObject *iterator) { +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 + PyObject *result; + PyObject *next = __Pyx_GetBuiltinNext_LimitedAPI(); + if (unlikely(!next)) return NULL; + result = PyObject_CallFunctionObjArgs(next, iterator, NULL); + return result; +#else + (void)__Pyx_GetBuiltinName; // only for early limited API + iternextfunc iternext = __Pyx_PyObject_GetIterNextFunc(iterator); + assert(iternext); + return iternext(iterator); +#endif +} + +/* IterNext */ +static PyObject *__Pyx_PyIter_Next2Default(PyObject* defval) { + PyObject* exc_type; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + exc_type = __Pyx_PyErr_CurrentExceptionType(); + if (unlikely(exc_type)) { + if (!defval || unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) + return NULL; + __Pyx_PyErr_Clear(); + Py_INCREF(defval); + return defval; + } + if (defval) { + Py_INCREF(defval); + return defval; + } + __Pyx_PyErr_SetNone(PyExc_StopIteration); + return NULL; +} +static void __Pyx_PyIter_Next_ErrorNoIterator(PyObject *iterator) { + __Pyx_TypeName iterator_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(iterator)); + PyErr_Format(PyExc_TypeError, + __Pyx_FMT_TYPENAME " object is not an iterator", iterator_type_name); + __Pyx_DECREF_TypeName(iterator_type_name); +} +static CYTHON_INLINE PyObject *__Pyx_PyIter_Next2(PyObject* iterator, PyObject* defval) { + PyObject* next; +#if !CYTHON_COMPILING_IN_LIMITED_API + iternextfunc iternext = __Pyx_PyObject_TryGetSlot(iterator, tp_iternext, iternextfunc); + if (likely(iternext)) { + next = iternext(iterator); + if (likely(next)) + return next; + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 + if (unlikely(iternext == &_PyObject_NextNotImplemented)) + return NULL; + #endif + } else if (CYTHON_USE_TYPE_SLOTS) { + __Pyx_PyIter_Next_ErrorNoIterator(iterator); + return NULL; + } else +#endif + if (unlikely(!PyIter_Check(iterator))) { + __Pyx_PyIter_Next_ErrorNoIterator(iterator); + return NULL; + } else { + next = defval ? PyIter_Next(iterator) : __Pyx_PyIter_Next_Plain(iterator); + if (likely(next)) + return next; + } + return __Pyx_PyIter_Next2Default(defval); +} + +/* GetTopmostException (used by SaveResetException) */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * +__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_value == NULL || exc_info->exc_value == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; + } + return exc_info; +} +#endif + +/* SaveResetException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + PyObject *exc_value = exc_info->exc_value; + if (exc_value == NULL || exc_value == Py_None) { + *value = NULL; + *type = NULL; + *tb = NULL; + } else { + *value = exc_value; + Py_INCREF(*value); + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + *tb = PyException_GetTraceback(exc_value); + } + #elif CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + *type = exc_info->exc_type; + *value = exc_info->exc_value; + *tb = exc_info->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #else + *type = tstate->exc_type; + *value = tstate->exc_value; + *tb = tstate->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #endif +} +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = tstate->exc_info; + PyObject *tmp_value = exc_info->exc_value; + exc_info->exc_value = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); + #else + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = type; + exc_info->exc_value = value; + exc_info->exc_traceback = tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = type; + tstate->exc_value = value; + tstate->exc_traceback = tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); + #endif +} +#endif + +/* GetException */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) +#endif +{ + PyObject *local_type = NULL, *local_value, *local_tb = NULL; +#if CYTHON_FAST_THREAD_STATE + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if PY_VERSION_HEX >= 0x030C0000 + local_value = tstate->current_exception; + tstate->current_exception = 0; + #else + local_type = tstate->curexc_type; + local_value = tstate->curexc_value; + local_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; + #endif +#elif __PYX_LIMITED_VERSION_HEX > 0x030C0000 + local_value = PyErr_GetRaisedException(); +#else + PyErr_Fetch(&local_type, &local_value, &local_tb); +#endif +#if __PYX_LIMITED_VERSION_HEX > 0x030C0000 + if (likely(local_value)) { + local_type = (PyObject*) Py_TYPE(local_value); + Py_INCREF(local_type); + local_tb = PyException_GetTraceback(local_value); + } +#else + PyErr_NormalizeException(&local_type, &local_value, &local_tb); +#if CYTHON_FAST_THREAD_STATE + if (unlikely(tstate->curexc_type)) +#else + if (unlikely(PyErr_Occurred())) +#endif + goto bad; + if (local_tb) { + if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) + goto bad; + } +#endif // __PYX_LIMITED_VERSION_HEX > 0x030C0000 + Py_XINCREF(local_tb); + Py_XINCREF(local_type); + Py_XINCREF(local_value); + *type = local_type; + *value = local_value; + *tb = local_tb; +#if CYTHON_FAST_THREAD_STATE + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + #if PY_VERSION_HEX >= 0x030B00a4 + tmp_value = exc_info->exc_value; + exc_info->exc_value = local_value; + tmp_type = NULL; + tmp_tb = NULL; + Py_XDECREF(local_type); + Py_XDECREF(local_tb); + #else + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + #endif + } + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = local_type; + tstate->exc_value = local_value; + tstate->exc_traceback = local_tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#elif __PYX_LIMITED_VERSION_HEX >= 0x030b0000 + PyErr_SetHandledException(local_value); + Py_XDECREF(local_value); + Py_XDECREF(local_type); + Py_XDECREF(local_tb); +#else + PyErr_SetExcInfo(local_type, local_value, local_tb); +#endif + return 0; +#if __PYX_LIMITED_VERSION_HEX <= 0x030C0000 +bad: + *type = 0; + *value = 0; + *tb = 0; + Py_XDECREF(local_type); + Py_XDECREF(local_value); + Py_XDECREF(local_tb); + return -1; +#endif +} + +/* PyObjectCallNoArg (used by PyObjectCallMethod0) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { + PyObject *arg[2] = {NULL, NULL}; + return __Pyx_PyObject_FastCall(func, arg + 1, 0 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectGetMethod (used by PyObjectCallMethod0) */ +#if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))) +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { + PyObject *attr; +#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP + __Pyx_TypeName type_name; + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrgetfunc f = NULL; + PyObject **dictptr, *dict; + int meth_found = 0; + assert (*method == NULL); + if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; + } + if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { + return 0; + } + descr = _PyType_Lookup(tp, name); + if (likely(descr != NULL)) { + Py_INCREF(descr); +#if defined(Py_TPFLAGS_METHOD_DESCRIPTOR) && Py_TPFLAGS_METHOD_DESCRIPTOR + if (__Pyx_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)) +#else + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type))) + #endif +#endif + { + meth_found = 1; + } else { + f = Py_TYPE(descr)->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + } + } + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL && (dict = *dictptr) != NULL) { + Py_INCREF(dict); + attr = __Pyx_PyDict_GetItemStr(dict, name); + if (attr != NULL) { + Py_INCREF(attr); + Py_DECREF(dict); + Py_XDECREF(descr); + goto try_unpack; + } + Py_DECREF(dict); + } + if (meth_found) { + *method = descr; + return 1; + } + if (f != NULL) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + if (likely(descr != NULL)) { + *method = descr; + return 0; + } + type_name = __Pyx_PyType_GetFullyQualifiedName(tp); + PyErr_Format(PyExc_AttributeError, + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", + type_name, name); + __Pyx_DECREF_TypeName(type_name); + return 0; +#else + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; +#endif +try_unpack: +#if CYTHON_UNPACK_METHODS + if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { + PyObject *function = PyMethod_GET_FUNCTION(attr); + Py_INCREF(function); + Py_DECREF(attr); + *method = function; + return 1; + } +#endif + *method = attr; + return 0; +} +#endif + +/* PyObjectCallMethod0 (used by pop) */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) { +#if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000)) + PyObject *args[1] = {obj}; + (void) __Pyx_PyObject_CallOneArg; + (void) __Pyx_PyObject_CallNoArg; + return PyObject_VectorcallMethod(method_name, args, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +#else + PyObject *method = NULL, *result = NULL; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_CallOneArg(method, obj); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) goto bad; + result = __Pyx_PyObject_CallNoArg(method); + Py_DECREF(method); +bad: + return result; +#endif +} + +/* pop */ +static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L) { + if (__Pyx_IS_TYPE(L, &PySet_Type)) { + return PySet_Pop(L); + } + return __Pyx_PyObject_CallMethod0(L, __pyx_mstate_global->__pyx_n_u_pop); +} +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE +static CYTHON_INLINE PyObject* __Pyx_PyList_Pop(PyObject* L) { + if (likely(PyList_GET_SIZE(L) > (((PyListObject*)L)->allocated >> 1))) { + __Pyx_SET_SIZE(L, Py_SIZE(L) - 1); + return PyList_GET_ITEM(L, PyList_GET_SIZE(L)); + } + return __Pyx_CallUnboundCMethod0(&__pyx_mstate_global->__pyx_umethod_PyList_Type_pop, L); +} +#endif + +/* PyObjectCall2Args (used by PyObjectCallMethod1) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args[3] = {NULL, arg1, arg2}; + return __Pyx_PyObject_FastCall(function, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectCallMethod1 (used by append) */ +#if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))) +static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) { + PyObject *result = __Pyx_PyObject_CallOneArg(method, arg); + Py_DECREF(method); + return result; +} +#endif +static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) { +#if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000)) + PyObject *args[2] = {obj, arg}; + (void) __Pyx_PyObject_CallOneArg; + (void) __Pyx_PyObject_Call2Args; + return PyObject_VectorcallMethod(method_name, args, 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +#else + PyObject *method = NULL, *result; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_Call2Args(method, obj, arg); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) return NULL; + return __Pyx__PyObject_CallMethod1(method, arg); +#endif +} + +/* append */ +static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x) { + if (likely(PyList_CheckExact(L))) { + if (unlikely(__Pyx_PyList_Append(L, x) < 0)) return -1; + } else { + PyObject* retval = __Pyx_PyObject_CallMethod1(L, __pyx_mstate_global->__pyx_n_u_append, x); + if (unlikely(!retval)) + return -1; + Py_DECREF(retval); + } + return 0; +} + +/* SwapException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_value = exc_info->exc_value; + exc_info->exc_value = *value; + if (tmp_value == NULL || tmp_value == Py_None) { + Py_XDECREF(tmp_value); + tmp_value = NULL; + tmp_type = NULL; + tmp_tb = NULL; + } else { + tmp_type = (PyObject*) Py_TYPE(tmp_value); + Py_INCREF(tmp_type); + #if CYTHON_COMPILING_IN_CPYTHON + tmp_tb = ((PyBaseExceptionObject*) tmp_value)->traceback; + Py_XINCREF(tmp_tb); + #else + tmp_tb = PyException_GetTraceback(tmp_value); + #endif + } + #elif CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = *type; + exc_info->exc_value = *value; + exc_info->exc_traceback = *tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = *type; + tstate->exc_value = *value; + tstate->exc_traceback = *tb; + #endif + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); + PyErr_SetExcInfo(*type, *value, *tb); + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#endif + +/* HasAttr */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d0000 +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { + PyObject *r; + if (unlikely(!PyUnicode_Check(n))) { + PyErr_SetString(PyExc_TypeError, + "hasattr(): attribute name must be string"); + return -1; + } + r = __Pyx_PyObject_GetAttrStrNoError(o, n); + if (!r) { + return (unlikely(PyErr_Occurred())) ? -1 : 0; + } else { + Py_DECREF(r); + return 1; + } +} +#endif + +/* GetAttr3 */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d0000 +static PyObject *__Pyx_GetAttr3Default(PyObject *d) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + return NULL; + __Pyx_PyErr_Clear(); + Py_INCREF(d); + return d; +} +#endif +static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { + PyObject *r; +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + int res = PyObject_GetOptionalAttr(o, n, &r); + return (res != 0) ? r : __Pyx_NewRef(d); +#else + #if CYTHON_USE_TYPE_SLOTS + if (likely(PyUnicode_Check(n))) { + r = __Pyx_PyObject_GetAttrStrNoError(o, n); + if (unlikely(!r) && likely(!PyErr_Occurred())) { + r = __Pyx_NewRef(d); + } + return r; + } + #endif + r = PyObject_GetAttr(o, n); + return (likely(r)) ? r : __Pyx_GetAttr3Default(d); +#endif +} + +/* ImportImpl (used by Import) */ +static int __Pyx__Import_GetModule(PyObject *qualname, PyObject **module) { + PyObject *imported_module = PyImport_GetModule(qualname); + if (unlikely(!imported_module)) { + *module = NULL; + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + *module = imported_module; + return 1; +} +static int __Pyx__Import_Lookup(PyObject *qualname, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject **module) { + PyObject *imported_module; + PyObject *top_level_package_name; + Py_ssize_t i; + int status, module_found; + Py_ssize_t dot_index; + module_found = __Pyx__Import_GetModule(qualname, &imported_module); + if (unlikely(!module_found || module_found == -1)) { + *module = NULL; + return module_found; + } + if (imported_names) { + for (i = 0; i < len_imported_names; i++) { + PyObject *imported_name = imported_names[i]; +#if __PYX_LIMITED_VERSION_HEX < 0x030d0000 + int has_imported_attribute = PyObject_HasAttr(imported_module, imported_name); +#else + int has_imported_attribute = PyObject_HasAttrWithError(imported_module, imported_name); + if (unlikely(has_imported_attribute == -1)) goto error; +#endif + if (!has_imported_attribute) { + goto not_found; + } + } + *module = imported_module; + return 1; + } + dot_index = PyUnicode_FindChar(qualname, '.', 0, PY_SSIZE_T_MAX, 1); + if (dot_index == -1) { + *module = imported_module; + return 1; + } + if (unlikely(dot_index == -2)) goto error; + top_level_package_name = PyUnicode_Substring(qualname, 0, dot_index); + if (unlikely(!top_level_package_name)) goto error; + Py_DECREF(imported_module); + status = __Pyx__Import_GetModule(top_level_package_name, module); + Py_DECREF(top_level_package_name); + return status; +error: + Py_DECREF(imported_module); + *module = NULL; + return -1; +not_found: + Py_DECREF(imported_module); + *module = NULL; + return 0; +} +static PyObject *__Pyx__Import(PyObject *name, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject *qualname, PyObject *moddict, int level) { + PyObject *module = 0; + PyObject *empty_dict = 0; + PyObject *from_list = 0; + int module_found; + if (!qualname) { + qualname = name; + } + module_found = __Pyx__Import_Lookup(qualname, imported_names, len_imported_names, &module); + if (likely(module_found == 1)) { + return module; + } else if (unlikely(module_found == -1)) { + return NULL; + } + empty_dict = PyDict_New(); + if (unlikely(!empty_dict)) + goto bad; + if (imported_names) { +#if CYTHON_COMPILING_IN_CPYTHON + from_list = __Pyx_PyList_FromArray(imported_names, len_imported_names); + if (unlikely(!from_list)) + goto bad; +#else + from_list = PyList_New(len_imported_names); + if (unlikely(!from_list)) goto bad; + for (Py_ssize_t i=0; i__pyx_d, level); +} + +/* ImportFrom */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { + PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); + if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { + const char* module_name_str = 0; + PyObject* module_name = 0; + PyObject* module_dot = 0; + PyObject* full_name = 0; + PyErr_Clear(); + module_name_str = PyModule_GetName(module); + if (unlikely(!module_name_str)) { goto modbad; } + module_name = PyUnicode_FromString(module_name_str); + if (unlikely(!module_name)) { goto modbad; } + module_dot = PyUnicode_Concat(module_name, __pyx_mstate_global->__pyx_kp_u__8); + if (unlikely(!module_dot)) { goto modbad; } + full_name = PyUnicode_Concat(module_dot, name); + if (unlikely(!full_name)) { goto modbad; } + #if (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) ||\ + CYTHON_COMPILING_IN_GRAAL + { + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + goto modbad; + value = PyObject_GetItem(modules, full_name); + } + #else + value = PyImport_GetModule(full_name); + #endif + modbad: + Py_XDECREF(full_name); + Py_XDECREF(module_dot); + Py_XDECREF(module_name); + } + if (unlikely(!value)) { + PyErr_Format(PyExc_ImportError, "cannot import name %S", name); + } + return value; +} + +/* Py3UpdateBases */ +static PyObject* +__Pyx_PEP560_update_bases(PyObject *bases) +{ + Py_ssize_t i, j, size_bases; + PyObject *base = NULL, *meth, *new_base, *result, *new_bases = NULL; +#if CYTHON_ASSUME_SAFE_SIZE + size_bases = PyTuple_GET_SIZE(bases); +#else + size_bases = PyTuple_Size(bases); + if (size_bases < 0) return NULL; +#endif + for (i = 0; i < size_bases; i++) { +#if CYTHON_AVOID_BORROWED_REFS + Py_CLEAR(base); +#endif +#if CYTHON_ASSUME_SAFE_MACROS + base = PyTuple_GET_ITEM(bases, i); +#else + base = PyTuple_GetItem(bases, i); + if (!base) goto error; +#endif +#if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(base); +#endif + if (PyType_Check(base)) { + if (new_bases) { + if (PyList_Append(new_bases, base) < 0) { + goto error; + } + } + continue; + } + meth = __Pyx_PyObject_GetAttrStrNoError(base, __pyx_mstate_global->__pyx_n_u_mro_entries); + if (!meth && PyErr_Occurred()) { + goto error; + } + if (!meth) { + if (new_bases) { + if (PyList_Append(new_bases, base) < 0) { + goto error; + } + } + continue; + } + new_base = __Pyx_PyObject_CallOneArg(meth, bases); + Py_DECREF(meth); + if (!new_base) { + goto error; + } + if (!PyTuple_Check(new_base)) { + PyErr_SetString(PyExc_TypeError, + "__mro_entries__ must return a tuple"); + Py_DECREF(new_base); + goto error; + } + if (!new_bases) { + if (!(new_bases = PyList_New(i))) { + goto error; + } + for (j = 0; j < i; j++) { + PyObject *base_from_list; +#if CYTHON_ASSUME_SAFE_MACROS + base_from_list = PyTuple_GET_ITEM(bases, j); + PyList_SET_ITEM(new_bases, j, base_from_list); + Py_INCREF(base_from_list); +#else + base_from_list = PyTuple_GetItem(bases, j); + if (!base_from_list) goto error; + Py_INCREF(base_from_list); + if (PyList_SetItem(new_bases, j, base_from_list) < 0) goto error; +#endif + } + } +#if CYTHON_ASSUME_SAFE_SIZE + j = PyList_GET_SIZE(new_bases); +#else + j = PyList_Size(new_bases); + if (j < 0) goto error; +#endif + if (PyList_SetSlice(new_bases, j, j, new_base) < 0) { + goto error; + } + Py_DECREF(new_base); + } + if (!new_bases) { + Py_INCREF(bases); + return bases; + } + result = PyList_AsTuple(new_bases); + Py_DECREF(new_bases); +#if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(base); +#endif + return result; +error: + Py_XDECREF(new_bases); +#if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(base); +#endif + return NULL; +} + +/* CalculateMetaclass */ +static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases) { + Py_ssize_t i, nbases; +#if CYTHON_ASSUME_SAFE_SIZE + nbases = PyTuple_GET_SIZE(bases); +#else + nbases = PyTuple_Size(bases); + if (nbases < 0) return NULL; +#endif + for (i=0; i < nbases; i++) { + PyTypeObject *tmptype; +#if CYTHON_ASSUME_SAFE_MACROS + PyObject *tmp = PyTuple_GET_ITEM(bases, i); +#else + PyObject *tmp = PyTuple_GetItem(bases, i); + if (!tmp) return NULL; +#endif + tmptype = Py_TYPE(tmp); + if (!metaclass) { + metaclass = tmptype; + continue; + } + if (PyType_IsSubtype(metaclass, tmptype)) + continue; + if (PyType_IsSubtype(tmptype, metaclass)) { + metaclass = tmptype; + continue; + } + PyErr_SetString(PyExc_TypeError, + "metaclass conflict: " + "the metaclass of a derived class " + "must be a (non-strict) subclass " + "of the metaclasses of all its bases"); + return NULL; + } + if (!metaclass) { + metaclass = &PyType_Type; + } + Py_INCREF((PyObject*) metaclass); + return (PyObject*) metaclass; +} + +/* dict_setdefault (used by FetchCommonType) */ +static CYTHON_INLINE PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value) { + PyObject* value; +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX >= 0x030C0000 + PyObject *args[] = {d, key, default_value}; + value = PyObject_VectorcallMethod(__pyx_mstate_global->__pyx_n_u_setdefault, args, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +#elif CYTHON_COMPILING_IN_LIMITED_API + value = PyObject_CallMethodObjArgs(d, __pyx_mstate_global->__pyx_n_u_setdefault, key, default_value, NULL); +#elif PY_VERSION_HEX >= 0x030d0000 + PyDict_SetDefaultRef(d, key, default_value, &value); +#else + value = PyDict_SetDefault(d, key, default_value); + if (unlikely(!value)) return NULL; + Py_INCREF(value); +#endif + return value; +} + +/* LimitedApiGetTypeDict (used by SetItemOnTypeDict) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static Py_ssize_t __Pyx_GetTypeDictOffset(void) { + PyObject *tp_dictoffset_o; + Py_ssize_t tp_dictoffset; + tp_dictoffset_o = PyObject_GetAttrString((PyObject*)(&PyType_Type), "__dictoffset__"); + if (unlikely(!tp_dictoffset_o)) return -1; + tp_dictoffset = PyLong_AsSsize_t(tp_dictoffset_o); + Py_DECREF(tp_dictoffset_o); + if (unlikely(tp_dictoffset == 0)) { + PyErr_SetString( + PyExc_TypeError, + "'type' doesn't have a dictoffset"); + return -1; + } else if (unlikely(tp_dictoffset < 0)) { + PyErr_SetString( + PyExc_TypeError, + "'type' has an unexpected negative dictoffset. " + "Please report this as Cython bug"); + return -1; + } + return tp_dictoffset; +} +static PyObject *__Pyx_GetTypeDict(PyTypeObject *tp) { + static Py_ssize_t tp_dictoffset = 0; + if (unlikely(tp_dictoffset == 0)) { + tp_dictoffset = __Pyx_GetTypeDictOffset(); + if (unlikely(tp_dictoffset == -1 && PyErr_Occurred())) { + tp_dictoffset = 0; // try again next time? + return NULL; + } + } + return *(PyObject**)((char*)tp + tp_dictoffset); +} +#endif + +/* SetItemOnTypeDict (used by FixUpExtensionType) */ +static int __Pyx__SetItemOnTypeDict(PyTypeObject *tp, PyObject *k, PyObject *v) { + int result; + PyObject *tp_dict; +#if CYTHON_COMPILING_IN_LIMITED_API + tp_dict = __Pyx_GetTypeDict(tp); + if (unlikely(!tp_dict)) return -1; +#else + tp_dict = tp->tp_dict; +#endif + result = PyDict_SetItem(tp_dict, k, v); + if (likely(!result)) { + PyType_Modified(tp); + if (unlikely(PyObject_HasAttr(v, __pyx_mstate_global->__pyx_n_u_set_name))) { + PyObject *setNameResult = PyObject_CallMethodObjArgs(v, __pyx_mstate_global->__pyx_n_u_set_name, (PyObject *) tp, k, NULL); + if (!setNameResult) return -1; + Py_DECREF(setNameResult); + } + } + return result; +} + +/* FixUpExtensionType (used by FetchCommonType) */ +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) { +#if __PYX_LIMITED_VERSION_HEX > 0x030900B1 + CYTHON_UNUSED_VAR(spec); + CYTHON_UNUSED_VAR(type); + CYTHON_UNUSED_VAR(__Pyx__SetItemOnTypeDict); +#else + const PyType_Slot *slot = spec->slots; + int changed = 0; +#if !CYTHON_COMPILING_IN_LIMITED_API + while (slot && slot->slot && slot->slot != Py_tp_members) + slot++; + if (slot && slot->slot == Py_tp_members) { +#if !CYTHON_COMPILING_IN_CPYTHON + const +#endif // !CYTHON_COMPILING_IN_CPYTHON) + PyMemberDef *memb = (PyMemberDef*) slot->pfunc; + while (memb && memb->name) { + if (memb->name[0] == '_' && memb->name[1] == '_') { + if (strcmp(memb->name, "__weaklistoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_weaklistoffset = memb->offset; + changed = 1; + } + else if (strcmp(memb->name, "__dictoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_dictoffset = memb->offset; + changed = 1; + } +#if CYTHON_METH_FASTCALL + else if (strcmp(memb->name, "__vectorcalloffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_vectorcall_offset = memb->offset; + changed = 1; + } +#endif // CYTHON_METH_FASTCALL +#if !CYTHON_COMPILING_IN_PYPY + else if (strcmp(memb->name, "__module__") == 0) { + PyObject *descr; + assert(memb->type == T_OBJECT); + assert(memb->flags == 0 || memb->flags == READONLY); + descr = PyDescr_NewMember(type, memb); + if (unlikely(!descr)) + return -1; + int set_item_result = PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr); + Py_DECREF(descr); + if (unlikely(set_item_result < 0)) { + return -1; + } + changed = 1; + } +#endif // !CYTHON_COMPILING_IN_PYPY + } + memb++; + } + } +#endif // !CYTHON_COMPILING_IN_LIMITED_API +#if !CYTHON_COMPILING_IN_PYPY + slot = spec->slots; + while (slot && slot->slot && slot->slot != Py_tp_getset) + slot++; + if (slot && slot->slot == Py_tp_getset) { + PyGetSetDef *getset = (PyGetSetDef*) slot->pfunc; + while (getset && getset->name) { + if (getset->name[0] == '_' && getset->name[1] == '_' && strcmp(getset->name, "__module__") == 0) { + PyObject *descr = PyDescr_NewGetSet(type, getset); + if (unlikely(!descr)) + return -1; + #if CYTHON_COMPILING_IN_LIMITED_API + PyObject *pyname = PyUnicode_FromString(getset->name); + if (unlikely(!pyname)) { + Py_DECREF(descr); + return -1; + } + int set_item_result = __Pyx_SetItemOnTypeDict(type, pyname, descr); + Py_DECREF(pyname); + #else + CYTHON_UNUSED_VAR(__Pyx__SetItemOnTypeDict); + int set_item_result = PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr); + #endif + Py_DECREF(descr); + if (unlikely(set_item_result < 0)) { + return -1; + } + changed = 1; + } + ++getset; + } + } +#else + CYTHON_UNUSED_VAR(__Pyx__SetItemOnTypeDict); +#endif // !CYTHON_COMPILING_IN_PYPY + if (changed) + PyType_Modified(type); +#endif // PY_VERSION_HEX > 0x030900B1 + return 0; +} + +/* AddModuleRef (used by FetchSharedCythonModule) */ +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + static PyObject *__Pyx_PyImport_AddModuleObjectRef(PyObject *name) { + PyObject *module_dict = PyImport_GetModuleDict(); + PyObject *m; + if (PyMapping_GetOptionalItem(module_dict, name, &m) < 0) { + return NULL; + } + if (m != NULL && PyModule_Check(m)) { + return m; + } + Py_XDECREF(m); + m = PyModule_NewObject(name); + if (m == NULL) + return NULL; + if (PyDict_CheckExact(module_dict)) { + PyObject *new_m; + (void)PyDict_SetDefaultRef(module_dict, name, m, &new_m); + Py_DECREF(m); + return new_m; + } else { + if (PyObject_SetItem(module_dict, name, m) != 0) { + Py_DECREF(m); + return NULL; + } + return m; + } + } + static PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *py_name = PyUnicode_FromString(name); + if (!py_name) return NULL; + PyObject *module = __Pyx_PyImport_AddModuleObjectRef(py_name); + Py_DECREF(py_name); + return module; + } +#elif __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#else + static PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *module = PyImport_AddModule(name); + Py_XINCREF(module); + return module; + } +#endif + +/* FetchSharedCythonModule (used by FetchCommonType) */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void) { + return __Pyx_PyImport_AddModuleRef(__PYX_ABI_MODULE_NAME); +} + +/* FetchCommonType (used by CommonTypesMetaclass) */ +#if __PYX_LIMITED_VERSION_HEX < 0x030C0000 +static PyObject* __Pyx_PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *result = __Pyx_PyType_FromModuleAndSpec(module, spec, bases); + if (result && metaclass) { + PyObject *old_tp = (PyObject*)Py_TYPE(result); + Py_INCREF((PyObject*)metaclass); +#if __PYX_LIMITED_VERSION_HEX >= 0x03090000 + Py_SET_TYPE(result, metaclass); +#else + result->ob_type = metaclass; +#endif + Py_DECREF(old_tp); + } + return result; +} +#else +#define __Pyx_PyType_FromMetaclass(me, mo, s, b) PyType_FromMetaclass(me, mo, s, b) +#endif +static int __Pyx_VerifyCachedType(PyObject *cached_type, + const char *name, + Py_ssize_t expected_basicsize) { + Py_ssize_t basicsize; + if (!PyType_Check(cached_type)) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s is not a type object", name); + return -1; + } + if (expected_basicsize == 0) { + return 0; // size is inherited, nothing useful to check + } +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_basicsize; + py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__"); + if (unlikely(!py_basicsize)) return -1; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = NULL; + if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) return -1; +#else + basicsize = ((PyTypeObject*) cached_type)->tp_basicsize; +#endif + if (basicsize != expected_basicsize) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s has the wrong size, try recompiling", + name); + return -1; + } + return 0; +} +static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *abi_module = NULL, *cached_type = NULL, *abi_module_dict, *new_cached_type, *py_object_name; + int get_item_ref_result; + const char* object_name = strrchr(spec->name, '.'); + object_name = object_name ? object_name+1 : spec->name; + py_object_name = PyUnicode_FromString(object_name); + if (!py_object_name) return NULL; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) goto done; + abi_module_dict = PyModule_GetDict(abi_module); + if (!abi_module_dict) goto done; + get_item_ref_result = __Pyx_PyDict_GetItemRef(abi_module_dict, py_object_name, &cached_type); + if (get_item_ref_result == 1) { + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + spec->basicsize) < 0) { + goto bad; + } + goto done; + } else if (unlikely(get_item_ref_result == -1)) { + goto bad; + } + cached_type = __Pyx_PyType_FromMetaclass( + metaclass, + CYTHON_USE_MODULE_STATE ? module : abi_module, + spec, bases); + if (unlikely(!cached_type)) goto bad; + if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad; + new_cached_type = __Pyx_PyDict_SetDefault(abi_module_dict, py_object_name, cached_type); + if (unlikely(new_cached_type != cached_type)) { + if (unlikely(!new_cached_type)) goto bad; + Py_DECREF(cached_type); + cached_type = new_cached_type; + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + spec->basicsize) < 0) { + goto bad; + } + goto done; + } else { + Py_DECREF(new_cached_type); + } +done: + Py_XDECREF(abi_module); + Py_DECREF(py_object_name); + assert(cached_type == NULL || PyType_Check(cached_type)); + return (PyTypeObject *) cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} + +/* CommonTypesMetaclass (used by CythonFunctionShared) */ +static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) { + return PyUnicode_FromString(__PYX_ABI_MODULE_NAME); +} +#if __PYX_LIMITED_VERSION_HEX < 0x030A0000 +static PyObject* __pyx_CommonTypesMetaclass_call(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *args, CYTHON_UNUSED PyObject *kwds) { + PyErr_SetString(PyExc_TypeError, "Cannot instantiate Cython internal types"); + return NULL; +} +static int __pyx_CommonTypesMetaclass_setattr(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *attr, CYTHON_UNUSED PyObject *value) { + PyErr_SetString(PyExc_TypeError, "Cython internal types are immutable"); + return -1; +} +#endif +static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = { + {"__module__", __pyx_CommonTypesMetaclass_get_module, NULL, NULL, NULL}, + {0, 0, 0, 0, 0} +}; +static PyType_Slot __pyx_CommonTypesMetaclass_slots[] = { + {Py_tp_getset, (void *)__pyx_CommonTypesMetaclass_getset}, + #if __PYX_LIMITED_VERSION_HEX < 0x030A0000 + {Py_tp_call, (void*)__pyx_CommonTypesMetaclass_call}, + {Py_tp_new, (void*)__pyx_CommonTypesMetaclass_call}, + {Py_tp_setattro, (void*)__pyx_CommonTypesMetaclass_setattr}, + #endif + {0, 0} +}; +static PyType_Spec __pyx_CommonTypesMetaclass_spec = { + __PYX_TYPE_MODULE_PREFIX "_common_types_metatype", + 0, + 0, + Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_DEFAULT, + __pyx_CommonTypesMetaclass_slots +}; +static int __pyx_CommonTypesMetaclass_init(PyObject *module) { + __pyx_mstatetype *mstate = __Pyx_PyModule_GetState(module); + PyObject *bases = PyTuple_Pack(1, &PyType_Type); + if (unlikely(!bases)) { + return -1; + } + mstate->__pyx_CommonTypesMetaclassType = __Pyx_FetchCommonTypeFromSpec(NULL, module, &__pyx_CommonTypesMetaclass_spec, bases); + Py_DECREF(bases); + if (unlikely(mstate->__pyx_CommonTypesMetaclassType == NULL)) { + return -1; + } + return 0; +} + +/* CallTypeTraverse (used by CythonFunctionShared) */ +#if !CYTHON_USE_TYPE_SPECS || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x03090000) +#else +static int __Pyx_call_type_traverse(PyObject *o, int always_call, visitproc visit, void *arg) { + #if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x03090000 + if (__Pyx_get_runtime_version() < 0x03090000) return 0; + #endif + if (!always_call) { + PyTypeObject *base = __Pyx_PyObject_GetSlot(o, tp_base, PyTypeObject*); + unsigned long flags = PyType_GetFlags(base); + if (flags & Py_TPFLAGS_HEAPTYPE) { + return 0; + } + } + Py_VISIT((PyObject*)Py_TYPE(o)); + return 0; +} +#endif + +/* PyMethodNew (used by CythonFunctionShared) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + PyObject *result; + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + #if __PYX_LIMITED_VERSION_HEX >= 0x030C0000 + { + PyObject *args[] = {func, self}; + result = PyObject_Vectorcall(__pyx_mstate_global->__Pyx_CachedMethodType, args, 2, NULL); + } + #else + result = PyObject_CallFunctionObjArgs(__pyx_mstate_global->__Pyx_CachedMethodType, func, self, NULL); + #endif + return result; +} +#else +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + return PyMethod_New(func, self); +} +#endif + +/* PyVectorcallFastCallDict (used by CythonFunctionShared) */ +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL +static PyObject *__Pyx_PyVectorcall_FastCallDict_kw(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + PyObject *res = NULL; + PyObject *kwnames; + PyObject **newargs; + PyObject **kwvalues; + Py_ssize_t i; + #if CYTHON_AVOID_BORROWED_REFS + PyObject *pos; + #else + Py_ssize_t pos; + #endif + size_t j; + PyObject *key, *value; + unsigned long keys_are_strings; + #if !CYTHON_ASSUME_SAFE_SIZE + Py_ssize_t nkw = PyDict_Size(kw); + if (unlikely(nkw == -1)) return NULL; + #else + Py_ssize_t nkw = PyDict_GET_SIZE(kw); + #endif + newargs = (PyObject **)PyMem_Malloc((nargs + (size_t)nkw) * sizeof(args[0])); + if (unlikely(newargs == NULL)) { + PyErr_NoMemory(); + return NULL; + } + for (j = 0; j < nargs; j++) newargs[j] = args[j]; + kwnames = PyTuple_New(nkw); + if (unlikely(kwnames == NULL)) { + PyMem_Free(newargs); + return NULL; + } + kwvalues = newargs + nargs; + pos = 0; + i = 0; + keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; + while (__Pyx_PyDict_NextRef(kw, &pos, &key, &value)) { + keys_are_strings &= + #if CYTHON_COMPILING_IN_LIMITED_API + PyType_GetFlags(Py_TYPE(key)); + #else + Py_TYPE(key)->tp_flags; + #endif + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(PyTuple_SetItem(kwnames, i, key) < 0)) goto cleanup; + #else + PyTuple_SET_ITEM(kwnames, i, key); + #endif + kwvalues[i] = value; + i++; + } + if (unlikely(!keys_are_strings)) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + goto cleanup; + } + res = vc(func, newargs, nargs, kwnames); +cleanup: + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(pos); + #endif + Py_DECREF(kwnames); + for (i = 0; i < nkw; i++) + Py_DECREF(kwvalues[i]); + PyMem_Free(newargs); + return res; +} +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + Py_ssize_t kw_size = + likely(kw == NULL) ? + 0 : +#if !CYTHON_ASSUME_SAFE_SIZE + PyDict_Size(kw); +#else + PyDict_GET_SIZE(kw); +#endif + if (kw_size == 0) { + return vc(func, args, nargs, NULL); + } +#if !CYTHON_ASSUME_SAFE_SIZE + else if (unlikely(kw_size == -1)) { + return NULL; + } +#endif + return __Pyx_PyVectorcall_FastCallDict_kw(func, vc, args, nargs, kw); +} +#endif + +/* CythonFunctionShared (used by CythonFunction) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunctionNoMethod(PyObject *func, void (*cfunc)(void)) { + if (__Pyx_CyFunction_Check(func)) { + return PyCFunction_GetFunction(((__pyx_CyFunctionObject*)func)->func) == (PyCFunction) cfunc; + } else if (PyCFunction_Check(func)) { + return PyCFunction_GetFunction(func) == (PyCFunction) cfunc; + } + return 0; +} +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void (*cfunc)(void)) { + if ((PyObject*)Py_TYPE(func) == __pyx_mstate_global->__Pyx_CachedMethodType) { + int result; + PyObject *newFunc = PyObject_GetAttr(func, __pyx_mstate_global->__pyx_n_u_func); + if (unlikely(!newFunc)) { + PyErr_Clear(); // It's only an optimization, so don't throw an error + return 0; + } + result = __Pyx__IsSameCyOrCFunctionNoMethod(newFunc, cfunc); + Py_DECREF(newFunc); + return result; + } + return __Pyx__IsSameCyOrCFunctionNoMethod(func, cfunc); +} +#else +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void (*cfunc)(void)) { + if (PyMethod_Check(func)) { + func = PyMethod_GET_FUNCTION(func); + } + return __Pyx_CyOrPyCFunction_Check(func) && __Pyx_CyOrPyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +} +#endif +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj) { +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + __Pyx_Py_XDECREF_SET( + __Pyx_CyFunction_GetClassObj(f), + ((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#else + __Pyx_Py_XDECREF_SET( + ((PyCMethodObject *) (f))->mm_class, + (PyTypeObject*)((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#endif +} +static PyObject * +__Pyx_CyFunction_get_doc_locked(__pyx_CyFunctionObject *op) +{ + if (unlikely(op->func_doc == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_doc = PyObject_GetAttrString(op->func, "__doc__"); + if (unlikely(!op->func_doc)) return NULL; +#else + if (((PyCFunctionObject*)op)->m_ml->ml_doc) { + op->func_doc = PyUnicode_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); + if (unlikely(op->func_doc == NULL)) + return NULL; + } else { + Py_INCREF(Py_None); + return Py_None; + } +#endif + } + Py_INCREF(op->func_doc); + return op->func_doc; +} +static PyObject * +__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure) { + PyObject *result; + CYTHON_UNUSED_VAR(closure); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_doc_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (value == NULL) { + value = Py_None; + } + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_doc, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_name_locked(__pyx_CyFunctionObject *op) +{ + if (unlikely(op->func_name == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_name = PyObject_GetAttrString(op->func, "__name__"); +#else + op->func_name = PyUnicode_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#endif + if (unlikely(op->func_name == NULL)) + return NULL; + } + Py_INCREF(op->func_name); + return op->func_name; +} +static PyObject * +__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, void *context) +{ + PyObject *result = NULL; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_name_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL || !PyUnicode_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_name, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + PyObject *result; + __Pyx_BEGIN_CRITICAL_SECTION(op); + Py_INCREF(op->func_qualname); + result = op->func_qualname; + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL || !PyUnicode_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_qualname, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 +static PyObject * +__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_dict == NULL)) { + op->func_dict = PyDict_New(); + if (unlikely(op->func_dict == NULL)) + return NULL; + } + Py_INCREF(op->func_dict); + return op->func_dict; +} +#endif +static PyObject * +__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_globals); + return op->func_globals; +} +static PyObject * +__Pyx_CyFunction_get_closure(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(op); + CYTHON_UNUSED_VAR(context); + Py_INCREF(Py_None); + return Py_None; +} +static PyObject * +__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, void *context) +{ + PyObject* result = (op->func_code) ? op->func_code : Py_None; + CYTHON_UNUSED_VAR(context); + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { + int result = 0; + PyObject *res = op->defaults_getter((PyObject *) op); + if (unlikely(!res)) + return -1; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + op->defaults_tuple = PyTuple_GET_ITEM(res, 0); + Py_INCREF(op->defaults_tuple); + op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); + Py_INCREF(op->defaults_kwdict); + #else + op->defaults_tuple = __Pyx_PySequence_ITEM(res, 0); + if (unlikely(!op->defaults_tuple)) result = -1; + else { + op->defaults_kwdict = __Pyx_PySequence_ITEM(res, 1); + if (unlikely(!op->defaults_kwdict)) result = -1; + } + #endif + Py_DECREF(res); + return result; +} +static int +__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyTuple_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__defaults__ must be set to a tuple object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__defaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->defaults_tuple, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_defaults_locked(__pyx_CyFunctionObject *op) { + PyObject* result = op->defaults_tuple; + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_tuple; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = NULL; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_defaults_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__kwdefaults__ must be set to a dict object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__kwdefaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->defaults_kwdict, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults_locked(__pyx_CyFunctionObject *op) { + PyObject* result = op->defaults_kwdict; + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_kwdict; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_kwdefaults_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value || value == Py_None) { + value = NULL; + } else if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__annotations__ must be set to a dict object"); + return -1; + } + Py_XINCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_annotations, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_annotations_locked(__pyx_CyFunctionObject *op) { + PyObject* result = op->func_annotations; + if (unlikely(!result)) { + result = PyDict_New(); + if (unlikely(!result)) return NULL; + op->func_annotations = result; + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, void *context) { + PyObject *result; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_annotations_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static PyObject * +__Pyx_CyFunction_get_is_coroutine_value(__pyx_CyFunctionObject *op) { + int is_coroutine = op->flags & __Pyx_CYFUNCTION_COROUTINE; + if (is_coroutine) { + PyObject *is_coroutine_value, *module, *fromlist, *marker = __pyx_mstate_global->__pyx_n_u_is_coroutine; + fromlist = PyList_New(1); + if (unlikely(!fromlist)) return NULL; + Py_INCREF(marker); +#if CYTHON_ASSUME_SAFE_MACROS + PyList_SET_ITEM(fromlist, 0, marker); +#else + if (unlikely(PyList_SetItem(fromlist, 0, marker) < 0)) { + Py_DECREF(marker); + Py_DECREF(fromlist); + return NULL; + } +#endif + module = PyImport_ImportModuleLevelObject(__pyx_mstate_global->__pyx_n_u_asyncio_coroutines, NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + if (unlikely(!module)) goto ignore; + is_coroutine_value = __Pyx_PyObject_GetAttrStr(module, marker); + Py_DECREF(module); + if (likely(is_coroutine_value)) { + return is_coroutine_value; + } +ignore: + PyErr_Clear(); + } + return __Pyx_PyBool_FromLong(is_coroutine); +} +static PyObject * +__Pyx_CyFunction_get_is_coroutine(__pyx_CyFunctionObject *op, void *context) { + PyObject *result; + CYTHON_UNUSED_VAR(context); + if (op->func_is_coroutine) { + return __Pyx_NewRef(op->func_is_coroutine); + } + result = __Pyx_CyFunction_get_is_coroutine_value(op); + if (unlikely(!result)) + return NULL; + __Pyx_BEGIN_CRITICAL_SECTION(op); + if (op->func_is_coroutine) { + Py_DECREF(result); + result = __Pyx_NewRef(op->func_is_coroutine); + } else { + op->func_is_coroutine = __Pyx_NewRef(result); + } + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static void __Pyx_CyFunction_raise_argument_count_error(__pyx_CyFunctionObject *func, const char* message, Py_ssize_t size) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_name = __Pyx_CyFunction_get_name(func, NULL); + if (!py_name) return; + PyErr_Format(PyExc_TypeError, + "%.200S() %s (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, message, size); + Py_DECREF(py_name); +#else + const char* name = ((PyCFunctionObject*)func)->m_ml->ml_name; + PyErr_Format(PyExc_TypeError, + "%.200s() %s (%" CYTHON_FORMAT_SSIZE_T "d given)", + name, message, size); +#endif +} +static void __Pyx_CyFunction_raise_type_error(__pyx_CyFunctionObject *func, const char* message) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_name = __Pyx_CyFunction_get_name(func, NULL); + if (!py_name) return; + PyErr_Format(PyExc_TypeError, + "%.200S() %s", + py_name, message); + Py_DECREF(py_name); +#else + const char* name = ((PyCFunctionObject*)func)->m_ml->ml_name; + PyErr_Format(PyExc_TypeError, + "%.200s() %s", + name, message); +#endif +} +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject * +__Pyx_CyFunction_get_module(__pyx_CyFunctionObject *op, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_GetAttrString(op->func, "__module__"); +} +static int +__Pyx_CyFunction_set_module(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_SetAttrString(op->func, "__module__", value); +} +#endif +static PyGetSetDef __pyx_CyFunction_getsets[] = { + {"func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {"__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {"func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {"__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {"__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 + {"func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)PyObject_GenericSetDict, 0, 0}, + {"__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)PyObject_GenericSetDict, 0, 0}, +#else + {"func_dict", (getter)PyObject_GenericGetDict, (setter)PyObject_GenericSetDict, 0, 0}, + {"__dict__", (getter)PyObject_GenericGetDict, (setter)PyObject_GenericSetDict, 0, 0}, +#endif + {"func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {"__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {"func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {"__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {"func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {"__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {"func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {"__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {"__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, + {"__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, + {"_is_coroutine", (getter)__Pyx_CyFunction_get_is_coroutine, 0, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API + {"__module__", (getter)__Pyx_CyFunction_get_module, (setter)__Pyx_CyFunction_set_module, 0, 0}, +#endif + {0, 0, 0, 0, 0} +}; +static PyMemberDef __pyx_CyFunction_members[] = { +#if !CYTHON_COMPILING_IN_LIMITED_API + {"__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), 0, 0}, +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + {"__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0}, +#endif +#if CYTHON_METH_FASTCALL +#if CYTHON_COMPILING_IN_LIMITED_API + {"__vectorcalloffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_vectorcall), READONLY, 0}, +#else + {"__vectorcalloffset__", T_PYSSIZET, offsetof(PyCFunctionObject, vectorcall), READONLY, 0}, +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + {"__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0}, +#else + {"__weaklistoffset__", T_PYSSIZET, offsetof(PyCFunctionObject, m_weakreflist), READONLY, 0}, +#endif +#endif + {0, 0, 0, 0, 0} +}; +static PyObject * +__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, PyObject *args) +{ + PyObject *result = NULL; + CYTHON_UNUSED_VAR(args); + __Pyx_BEGIN_CRITICAL_SECTION(m); + Py_INCREF(m->func_qualname); + result = m->func_qualname; + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static PyMethodDef __pyx_CyFunction_methods[] = { + {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, + {0, 0, 0, 0} +}; +#if CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) +#else +#define __Pyx_CyFunction_weakreflist(cyfunc) (((PyCFunctionObject*)cyfunc)->m_weakreflist) +#endif +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { +#if !CYTHON_COMPILING_IN_LIMITED_API + PyCFunctionObject *cf = (PyCFunctionObject*) op; +#endif + if (unlikely(op == NULL)) + return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + op->func = PyCFunction_NewEx(ml, (PyObject*)op, module); + if (unlikely(!op->func)) return NULL; +#endif + op->flags = flags; + __Pyx_CyFunction_weakreflist(op) = NULL; +#if !CYTHON_COMPILING_IN_LIMITED_API + cf->m_ml = ml; + cf->m_self = (PyObject *) op; +#endif + Py_XINCREF(closure); + op->func_closure = closure; +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_XINCREF(module); + cf->m_module = module; +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + op->func_dict = NULL; +#endif + op->func_name = NULL; + Py_INCREF(qualname); + op->func_qualname = qualname; + op->func_doc = NULL; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + op->func_classobj = NULL; +#else + ((PyCMethodObject*)op)->mm_class = NULL; +#endif + op->func_globals = globals; + Py_INCREF(op->func_globals); + Py_XINCREF(code); + op->func_code = code; + op->defaults = NULL; + op->defaults_tuple = NULL; + op->defaults_kwdict = NULL; + op->defaults_getter = NULL; + op->func_annotations = NULL; + op->func_is_coroutine = NULL; +#if CYTHON_METH_FASTCALL + switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { + case METH_NOARGS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS; + break; + case METH_O: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O; + break; + case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD; + break; + case METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS; + break; + case METH_VARARGS | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = NULL; + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + Py_DECREF(op); + return NULL; + } +#endif + return (PyObject *) op; +} +static int +__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) +{ + Py_CLEAR(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func); +#else + Py_CLEAR(((PyCFunctionObject*)m)->m_module); +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func_dict); +#elif PY_VERSION_HEX < 0x030d0000 + _PyObject_ClearManagedDict((PyObject*)m); +#else + PyObject_ClearManagedDict((PyObject*)m); +#endif + Py_CLEAR(m->func_name); + Py_CLEAR(m->func_qualname); + Py_CLEAR(m->func_doc); + Py_CLEAR(m->func_globals); + Py_CLEAR(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API +#if PY_VERSION_HEX < 0x030900B1 + Py_CLEAR(__Pyx_CyFunction_GetClassObj(m)); +#else + { + PyObject *cls = (PyObject*) ((PyCMethodObject *) (m))->mm_class; + ((PyCMethodObject *) (m))->mm_class = NULL; + Py_XDECREF(cls); + } +#endif +#endif + Py_CLEAR(m->defaults_tuple); + Py_CLEAR(m->defaults_kwdict); + Py_CLEAR(m->func_annotations); + Py_CLEAR(m->func_is_coroutine); + Py_CLEAR(m->defaults); + return 0; +} +static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + if (__Pyx_CyFunction_weakreflist(m) != NULL) + PyObject_ClearWeakRefs((PyObject *) m); + __Pyx_CyFunction_clear(m); + __Pyx_PyHeapTypeObject_GC_Del(m); +} +static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + PyObject_GC_UnTrack(m); + __Pyx__CyFunction_dealloc(m); +} +static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) +{ + { + int e = __Pyx_call_type_traverse((PyObject*)m, 1, visit, arg); + if (e) return e; + } + Py_VISIT(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func); +#else + Py_VISIT(((PyCFunctionObject*)m)->m_module); +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func_dict); +#else + { + int e = +#if PY_VERSION_HEX < 0x030d0000 + _PyObject_VisitManagedDict +#else + PyObject_VisitManagedDict +#endif + ((PyObject*)m, visit, arg); + if (e != 0) return e; + } +#endif + __Pyx_VISIT_CONST(m->func_name); + __Pyx_VISIT_CONST(m->func_qualname); + Py_VISIT(m->func_doc); + Py_VISIT(m->func_globals); + __Pyx_VISIT_CONST(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(__Pyx_CyFunction_GetClassObj(m)); +#endif + Py_VISIT(m->defaults_tuple); + Py_VISIT(m->defaults_kwdict); + Py_VISIT(m->func_is_coroutine); + Py_VISIT(m->defaults); + return 0; +} +static PyObject* +__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) +{ + PyObject *repr; + __Pyx_BEGIN_CRITICAL_SECTION(op); + repr = PyUnicode_FromFormat("", + op->func_qualname, (void *)op); + __Pyx_END_CRITICAL_SECTION(); + return repr; +} +static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *f = ((__pyx_CyFunctionObject*)func)->func; + PyCFunction meth; + int flags; + meth = PyCFunction_GetFunction(f); + if (unlikely(!meth)) return NULL; + flags = PyCFunction_GetFlags(f); + if (unlikely(flags < 0)) return NULL; +#else + PyCFunctionObject* f = (PyCFunctionObject*)func; + PyCFunction meth = f->m_ml->ml_meth; + int flags = f->m_ml->ml_flags; +#endif + Py_ssize_t size; + switch (flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { + case METH_VARARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) + return (*meth)(self, arg); + break; + case METH_VARARGS | METH_KEYWORDS: + return (*(PyCFunctionWithKeywords)(void(*)(void))meth)(self, arg, kw); + case METH_NOARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_SIZE + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 0)) + return (*meth)(self, NULL); + __Pyx_CyFunction_raise_argument_count_error( + (__pyx_CyFunctionObject*)func, + "takes no arguments", size); + return NULL; + } + break; + case METH_O: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_SIZE + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 1)) { + PyObject *result, *arg0; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + arg0 = PyTuple_GET_ITEM(arg, 0); + #else + arg0 = __Pyx_PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; + #endif + result = (*meth)(self, arg0); + #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(arg0); + #endif + return result; + } + __Pyx_CyFunction_raise_argument_count_error( + (__pyx_CyFunctionObject*)func, + "takes exactly one argument", size); + return NULL; + } + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + return NULL; + } + __Pyx_CyFunction_raise_type_error( + (__pyx_CyFunctionObject*)func, "takes no keyword arguments"); + return NULL; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *self, *result; +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)func)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)func)->m_self; +#endif + result = __Pyx_CyFunction_CallMethod(func, self, arg, kw); + return result; +} +static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) { + PyObject *result; + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL + __pyx_vectorcallfunc vc = __Pyx_CyFunction_func_vectorcall(cyfunc); + if (vc) { +#if CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE + return __Pyx_PyVectorcall_FastCallDict(func, vc, &PyTuple_GET_ITEM(args, 0), (size_t)PyTuple_GET_SIZE(args), kw); +#else + (void) &__Pyx_PyVectorcall_FastCallDict; + return PyVectorcall_Call(func, args, kw); +#endif + } +#endif + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + Py_ssize_t argc; + PyObject *new_args; + PyObject *self; +#if CYTHON_ASSUME_SAFE_SIZE + argc = PyTuple_GET_SIZE(args); +#else + argc = PyTuple_Size(args); + if (unlikely(argc < 0)) return NULL; +#endif + new_args = PyTuple_GetSlice(args, 1, argc); + if (unlikely(!new_args)) + return NULL; + self = PyTuple_GetItem(args, 0); + if (unlikely(!self)) { + Py_DECREF(new_args); + PyErr_Format(PyExc_TypeError, + "unbound method %.200S() needs an argument", + cyfunc->func_qualname); + return NULL; + } + result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw); + Py_DECREF(new_args); + } else { + result = __Pyx_CyFunction_Call(func, args, kw); + } + return result; +} +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL +static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionObject *cyfunc, Py_ssize_t nargs, PyObject *kwnames) +{ + int ret = 0; + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + if (unlikely(nargs < 1)) { + __Pyx_CyFunction_raise_type_error( + cyfunc, "needs an argument"); + return -1; + } + ret = 1; + } + if (unlikely(kwnames) && unlikely(__Pyx_PyTuple_GET_SIZE(kwnames))) { + __Pyx_CyFunction_raise_type_error( + cyfunc, "takes no keyword arguments"); + return -1; + } + return ret; +} +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + if (unlikely(nargs != 0)) { + __Pyx_CyFunction_raise_argument_count_error( + cyfunc, "takes no arguments", nargs); + return NULL; + } + return meth(self, NULL); +} +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + if (unlikely(nargs != 1)) { + __Pyx_CyFunction_raise_argument_count_error( + cyfunc, "takes exactly one argument", nargs); + return NULL; + } + return meth(self, args[0]); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + return ((__Pyx_PyCFunctionFastWithKeywords)(void(*)(void))meth)(self, args, nargs, kwnames); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyTypeObject *cls = (PyTypeObject *) __Pyx_CyFunction_GetClassObj(cyfunc); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + #if PY_VERSION_HEX < 0x030e00A6 + size_t nargs_value = (size_t) nargs; + #else + Py_ssize_t nargs_value = nargs; + #endif + return ((__Pyx_PyCMethod)(void(*)(void))meth)(self, cls, args, nargs_value, kwnames); +} +#endif +static PyType_Slot __pyx_CyFunctionType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc}, + {Py_tp_repr, (void *)__Pyx_CyFunction_repr}, + {Py_tp_call, (void *)__Pyx_CyFunction_CallAsMethod}, + {Py_tp_traverse, (void *)__Pyx_CyFunction_traverse}, + {Py_tp_clear, (void *)__Pyx_CyFunction_clear}, + {Py_tp_methods, (void *)__pyx_CyFunction_methods}, + {Py_tp_members, (void *)__pyx_CyFunction_members}, + {Py_tp_getset, (void *)__pyx_CyFunction_getsets}, + {Py_tp_descr_get, (void *)__Pyx_PyMethod_New}, + {0, 0}, +}; +static PyType_Spec __pyx_CyFunctionType_spec = { + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if CYTHON_METH_FASTCALL +#if defined(Py_TPFLAGS_HAVE_VECTORCALL) + Py_TPFLAGS_HAVE_VECTORCALL | +#elif defined(_Py_TPFLAGS_HAVE_VECTORCALL) + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif +#endif // CYTHON_METH_FASTCALL +#if PY_VERSION_HEX >= 0x030C0000 && !CYTHON_COMPILING_IN_LIMITED_API + Py_TPFLAGS_MANAGED_DICT | +#endif + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + __pyx_CyFunctionType_slots +}; +static int __pyx_CyFunction_init(PyObject *module) { + __pyx_mstatetype *mstate = __Pyx_PyModule_GetState(module); + mstate->__pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec( + mstate->__pyx_CommonTypesMetaclassType, module, &__pyx_CyFunctionType_spec, NULL); + if (unlikely(mstate->__pyx_CyFunctionType == NULL)) { + return -1; + } + return 0; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_InitDefaults(PyObject *func, PyTypeObject *defaults_type) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults = PyObject_CallObject((PyObject*)defaults_type, NULL); // _PyObject_New(defaults_type); + if (unlikely(!m->defaults)) + return NULL; + return m->defaults; +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_tuple = tuple; + Py_INCREF(tuple); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_kwdict = dict; + Py_INCREF(dict); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->func_annotations = dict; + Py_INCREF(dict); +} + +/* CythonFunction */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { + PyObject *op = __Pyx_CyFunction_Init( + PyObject_GC_New(__pyx_CyFunctionObject, __pyx_mstate_global->__pyx_CyFunctionType), + ml, flags, qualname, closure, module, globals, code + ); + if (likely(op)) { + PyObject_GC_Track(op); + } + return op; +} + +/* PyObjectLookupSpecial (used by Py3ClassCreate) */ +#if CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx__PyObject_LookupSpecial(PyObject* obj, PyObject* attr_name, int with_error) { + PyObject *res; + PyTypeObject *tp = Py_TYPE(obj); + res = _PyType_Lookup(tp, attr_name); + if (likely(res)) { + descrgetfunc f = Py_TYPE(res)->tp_descr_get; + if (!f) { + Py_INCREF(res); + } else { + res = f(res, obj, (PyObject *)tp); + } + } else if (with_error) { + PyErr_SetObject(PyExc_AttributeError, attr_name); + } + return res; +} +#endif + +/* Py3ClassCreate */ +static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, + PyObject *qualname, PyObject *mkw, PyObject *modname, PyObject *doc) { + PyObject *ns; + if (metaclass) { + PyObject *prep = __Pyx_PyObject_GetAttrStrNoError(metaclass, __pyx_mstate_global->__pyx_n_u_prepare); + if (prep) { + PyObject *pargs[3] = {NULL, name, bases}; + ns = __Pyx_PyObject_FastCallDict(prep, pargs+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET, mkw); + Py_DECREF(prep); + } else { + if (unlikely(PyErr_Occurred())) + return NULL; + ns = PyDict_New(); + } + } else { + ns = PyDict_New(); + } + if (unlikely(!ns)) + return NULL; + if (unlikely(PyObject_SetItem(ns, __pyx_mstate_global->__pyx_n_u_module, modname) < 0)) goto bad; + if (unlikely(PyObject_SetItem(ns, __pyx_mstate_global->__pyx_n_u_qualname, qualname) < 0)) goto bad; + if (unlikely(doc && PyObject_SetItem(ns, __pyx_mstate_global->__pyx_n_u_doc, doc) < 0)) goto bad; + return ns; +bad: + Py_DECREF(ns); + return NULL; +} +static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, + PyObject *dict, PyObject *mkw, + int calculate_metaclass, int allow_py2_metaclass) { + PyObject *result; + PyObject *owned_metaclass = NULL; + PyObject *margs[4] = {NULL, name, bases, dict}; + if (allow_py2_metaclass) { + owned_metaclass = PyObject_GetItem(dict, __pyx_mstate_global->__pyx_n_u_metaclass); + if (owned_metaclass) { + metaclass = owned_metaclass; + } else if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) { + PyErr_Clear(); + } else { + return NULL; + } + } + if (calculate_metaclass && (!metaclass || PyType_Check(metaclass))) { + metaclass = __Pyx_CalculateMetaclass((PyTypeObject*) metaclass, bases); + Py_XDECREF(owned_metaclass); + if (unlikely(!metaclass)) + return NULL; + owned_metaclass = metaclass; + } + result = __Pyx_PyObject_FastCallDict(metaclass, margs+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET, mkw); + Py_XDECREF(owned_metaclass); + return result; +} + +/* CLineInTraceback (used by AddTraceback) */ +#if CYTHON_CLINE_IN_TRACEBACK && CYTHON_CLINE_IN_TRACEBACK_RUNTIME +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 +#define __Pyx_PyProbablyModule_GetDict(o) __Pyx_XNewRef(PyModule_GetDict(o)) +#elif !CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __Pyx_PyProbablyModule_GetDict(o) PyObject_GenericGetDict(o, NULL); +#else +PyObject* __Pyx_PyProbablyModule_GetDict(PyObject *o) { + PyObject **dict_ptr = _PyObject_GetDictPtr(o); + return dict_ptr ? __Pyx_XNewRef(*dict_ptr) : NULL; +} +#endif +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { + PyObject *use_cline = NULL; + PyObject *ptype, *pvalue, *ptraceback; + PyObject *cython_runtime_dict; + CYTHON_MAYBE_UNUSED_VAR(tstate); + if (unlikely(!__pyx_mstate_global->__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + cython_runtime_dict = __Pyx_PyProbablyModule_GetDict(__pyx_mstate_global->__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, cython_runtime_dict, + __Pyx_PyDict_SetDefault(cython_runtime_dict, __pyx_mstate_global->__pyx_n_u_cline_in_traceback, Py_False)) + } + if (use_cline == NULL || use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + Py_XDECREF(use_cline); + Py_XDECREF(cython_runtime_dict); + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache (used by AddTraceback) */ +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static __Pyx_CachedCodeObjectType *__pyx__find_code_object(struct __Pyx_CodeObjectCache *code_cache, int code_line) { + __Pyx_CachedCodeObjectType* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!code_cache->entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(code_cache->entries, code_cache->count, code_line); + if (unlikely(pos >= code_cache->count) || unlikely(code_cache->entries[pos].code_line != code_line)) { + return NULL; + } + code_object = code_cache->entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static __Pyx_CachedCodeObjectType *__pyx_find_code_object(int code_line) { +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && !CYTHON_ATOMICS + (void)__pyx__find_code_object; + return NULL; // Most implementation should have atomics. But otherwise, don't make it thread-safe, just miss. +#else + struct __Pyx_CodeObjectCache *code_cache = &__pyx_mstate_global->__pyx_code_cache; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_nonatomic_int_type old_count = __pyx_atomic_incr_acq_rel(&code_cache->accessor_count); + if (old_count < 0) { + __pyx_atomic_decr_acq_rel(&code_cache->accessor_count); + return NULL; + } +#endif + __Pyx_CachedCodeObjectType *result = __pyx__find_code_object(code_cache, code_line); +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_atomic_decr_acq_rel(&code_cache->accessor_count); +#endif + return result; +#endif +} +static void __pyx__insert_code_object(struct __Pyx_CodeObjectCache *code_cache, int code_line, __Pyx_CachedCodeObjectType* code_object) +{ + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = code_cache->entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + code_cache->entries = entries; + code_cache->max_count = 64; + code_cache->count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(code_cache->entries, code_cache->count, code_line); + if ((pos < code_cache->count) && unlikely(code_cache->entries[pos].code_line == code_line)) { + __Pyx_CachedCodeObjectType* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_INCREF(code_object); + Py_DECREF(tmp); + return; + } + if (code_cache->count == code_cache->max_count) { + int new_max = code_cache->max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + code_cache->entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + code_cache->entries = entries; + code_cache->max_count = new_max; + } + for (i=code_cache->count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + code_cache->count++; + Py_INCREF(code_object); +} +static void __pyx_insert_code_object(int code_line, __Pyx_CachedCodeObjectType* code_object) { +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && !CYTHON_ATOMICS + (void)__pyx__insert_code_object; + return; // Most implementation should have atomics. But otherwise, don't make it thread-safe, just fail. +#else + struct __Pyx_CodeObjectCache *code_cache = &__pyx_mstate_global->__pyx_code_cache; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_nonatomic_int_type expected = 0; + if (!__pyx_atomic_int_cmp_exchange(&code_cache->accessor_count, &expected, INT_MIN)) { + return; + } +#endif + __pyx__insert_code_object(code_cache, code_line, code_object); +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_atomic_sub(&code_cache->accessor_count, INT_MIN); +#endif +#endif +} + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION) + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyCode_Replace_For_AddTraceback(PyObject *code, PyObject *scratch_dict, + PyObject *firstlineno, PyObject *name) { + PyObject *replace = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_firstlineno", firstlineno))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_name", name))) return NULL; + replace = PyObject_GetAttrString(code, "replace"); + if (likely(replace)) { + PyObject *result = PyObject_Call(replace, __pyx_mstate_global->__pyx_empty_tuple, scratch_dict); + Py_DECREF(replace); + return result; + } + PyErr_Clear(); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyObject *code_object = NULL, *py_py_line = NULL, *py_funcname = NULL, *dict = NULL; + PyObject *replace = NULL, *getframe = NULL, *frame = NULL; + PyObject *exc_type, *exc_value, *exc_traceback; + int success = 0; + if (c_line) { + c_line = __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line); + } + PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); + code_object = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!code_object) { + code_object = Py_CompileString("_getframe()", filename, Py_eval_input); + if (unlikely(!code_object)) goto bad; + py_py_line = PyLong_FromLong(py_line); + if (unlikely(!py_py_line)) goto bad; + if (c_line) { + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + } else { + py_funcname = PyUnicode_FromString(funcname); + } + if (unlikely(!py_funcname)) goto bad; + dict = PyDict_New(); + if (unlikely(!dict)) goto bad; + { + PyObject *old_code_object = code_object; + code_object = __Pyx_PyCode_Replace_For_AddTraceback(code_object, dict, py_py_line, py_funcname); + Py_DECREF(old_code_object); + } + if (unlikely(!code_object)) goto bad; + __pyx_insert_code_object(c_line ? -c_line : py_line, code_object); + } else { + dict = PyDict_New(); + } + getframe = PySys_GetObject("_getframe"); + if (unlikely(!getframe)) goto bad; + if (unlikely(PyDict_SetItemString(dict, "_getframe", getframe))) goto bad; + frame = PyEval_EvalCode(code_object, dict, dict); + if (unlikely(!frame) || frame == Py_None) goto bad; + success = 1; + bad: + PyErr_Restore(exc_type, exc_value, exc_traceback); + Py_XDECREF(code_object); + Py_XDECREF(py_py_line); + Py_XDECREF(py_funcname); + Py_XDECREF(dict); + Py_XDECREF(replace); + if (success) { + PyTraceBack_Here( + (struct _frame*)frame); + } + Py_XDECREF(frame); +} +#else +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = NULL; + PyObject *py_funcname = NULL; + if (c_line) { + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + funcname = PyUnicode_AsUTF8(py_funcname); + if (!funcname) goto bad; + } + py_code = PyCode_NewEmpty(filename, funcname, py_line); + Py_XDECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_funcname); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject *ptype, *pvalue, *ptraceback; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) { + /* If the code object creation fails, then we should clear the + fetched exception references and propagate the new exception */ + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + goto bad; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_mstate_global->__pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} +#endif + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyLong_From_long(long value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyLong_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#if !CYTHON_COMPILING_IN_PYPY + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyLong_FromLong((long) value); + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); + } + } + { + unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d00A4 + if (is_unsigned) { + return PyLong_FromUnsignedNativeBytes(bytes, sizeof(value), -1); + } else { + return PyLong_FromNativeBytes(bytes, sizeof(value), -1); + } +#elif !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 + int one = 1; int little = (int)*(unsigned char *)&one; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); +#else + int one = 1; int little = (int)*(unsigned char *)&one; + PyObject *from_bytes, *result = NULL, *kwds = NULL; + PyObject *py_bytes = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(long)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + { + PyObject *args[3+(CYTHON_VECTORCALL ? 1 : 0)] = { NULL, py_bytes, order_str }; + if (!is_unsigned) { + kwds = __Pyx_MakeVectorcallBuilderKwds(1); + if (!kwds) goto limited_bad; + if (__Pyx_VectorcallBuilder_AddArgStr("signed", __Pyx_NewRef(Py_True), kwds, args+3, 0) < 0) goto limited_bad; + } + result = __Pyx_Object_Vectorcall_CallFromBuilder(from_bytes, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET, kwds); + } + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif + } +} + +/* FormatTypeName */ +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030d0000 +static __Pyx_TypeName +__Pyx_PyType_GetFullyQualifiedName(PyTypeObject* tp) +{ + PyObject *module = NULL, *name = NULL, *result = NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030b0000 + name = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_mstate_global->__pyx_n_u_qualname); + #else + name = PyType_GetQualName(tp); + #endif + if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) goto bad; + module = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_mstate_global->__pyx_n_u_module); + if (unlikely(module == NULL) || unlikely(!PyUnicode_Check(module))) goto bad; + if (PyUnicode_CompareWithASCIIString(module, "builtins") == 0) { + result = name; + name = NULL; + goto done; + } + result = PyUnicode_FromFormat("%U.%U", module, name); + if (unlikely(result == NULL)) goto bad; + done: + Py_XDECREF(name); + Py_XDECREF(module); + return result; + bad: + PyErr_Clear(); + if (name) { + result = name; + name = NULL; + } else { + result = __Pyx_NewRef(__pyx_mstate_global->__pyx_kp_u__18); + } + goto done; +} +#endif + +/* CIntFromPyVerify (used by CIntFromPy) */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyLong_As_long(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (unlikely(!PyLong_Check(x))) { + long val; + PyObject *tmp = __Pyx_PyNumber_Long(x); + if (!tmp) return (long) -1; + val = __Pyx_PyLong_As_long(tmp); + Py_DECREF(tmp); + return val; + } + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 2 * PyLong_SHIFT)) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 3 * PyLong_SHIFT)) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 4 * PyLong_SHIFT)) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(long) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) + } else if ((sizeof(long) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(long) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(long) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) + } else if ((sizeof(long) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) + } + } + { + long val; + int ret = -1; +#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API + Py_ssize_t bytes_copied = PyLong_AsNativeBytes( + x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0)); + if (unlikely(bytes_copied == -1)) { + } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) { + goto raise_overflow; + } else { + ret = 0; + } +#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)x, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *v; + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (likely(PyLong_CheckExact(x))) { + v = __Pyx_NewRef(x); + } else { + v = PyNumber_Long(x); + if (unlikely(!v)) return (long) -1; + assert(PyLong_CheckExact(v)); + } + { + int result = PyObject_RichCompareBool(v, Py_False, Py_LT); + if (unlikely(result < 0)) { + Py_DECREF(v); + return (long) -1; + } + is_negative = result == 1; + } + if (is_unsigned && unlikely(is_negative)) { + Py_DECREF(v); + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + Py_DECREF(v); + if (unlikely(!stepval)) + return (long) -1; + } else { + stepval = v; + } + v = NULL; + val = (long) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(long) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + long idigit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + val |= ((long) idigit) << bits; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + } + Py_DECREF(shift); shift = NULL; + Py_DECREF(mask); mask = NULL; + { + long idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(long) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((long) idigit) << bits; + } + if (!is_unsigned) { + if (unlikely(val & (((long) 1) << (sizeof(long) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + if (unlikely(ret)) + return (long) -1; + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyLong_As_int(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (unlikely(!PyLong_Check(x))) { + int val; + PyObject *tmp = __Pyx_PyNumber_Long(x); + if (!tmp) return (int) -1; + val = __Pyx_PyLong_As_int(tmp); + Py_DECREF(tmp); + return val; + } + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 2 * PyLong_SHIFT)) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 3 * PyLong_SHIFT)) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 4 * PyLong_SHIFT)) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(int) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) + } else if ((sizeof(int) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(int) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(int) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) + } else if ((sizeof(int) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) + } + } + { + int val; + int ret = -1; +#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API + Py_ssize_t bytes_copied = PyLong_AsNativeBytes( + x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0)); + if (unlikely(bytes_copied == -1)) { + } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) { + goto raise_overflow; + } else { + ret = 0; + } +#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)x, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *v; + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (likely(PyLong_CheckExact(x))) { + v = __Pyx_NewRef(x); + } else { + v = PyNumber_Long(x); + if (unlikely(!v)) return (int) -1; + assert(PyLong_CheckExact(v)); + } + { + int result = PyObject_RichCompareBool(v, Py_False, Py_LT); + if (unlikely(result < 0)) { + Py_DECREF(v); + return (int) -1; + } + is_negative = result == 1; + } + if (is_unsigned && unlikely(is_negative)) { + Py_DECREF(v); + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + Py_DECREF(v); + if (unlikely(!stepval)) + return (int) -1; + } else { + stepval = v; + } + v = NULL; + val = (int) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(int) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + long idigit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + val |= ((int) idigit) << bits; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + } + Py_DECREF(shift); shift = NULL; + Py_DECREF(mask); mask = NULL; + { + long idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(int) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((int) idigit) << bits; + } + if (!is_unsigned) { + if (unlikely(val & (((int) 1) << (sizeof(int) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + if (unlikely(ret)) + return (int) -1; + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = __Pyx_PyType_GetSlot(a, tp_base, PyTypeObject*); + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (cls == a || cls == b) return 1; + mro = cls->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + PyObject *base = PyTuple_GET_ITEM(mro, i); + if (base == (PyObject *)a || base == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(cls, a) || __Pyx_InBases(cls, b); +} +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + if (exc_type1) { + return __Pyx_IsAnySubtype2((PyTypeObject*)err, (PyTypeObject*)exc_type1, (PyTypeObject*)exc_type2); + } else { + return __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } +} +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); + for (i=0; i>= 8; + ++i; + } + __Pyx_cached_runtime_version = version; + } +} +#endif +static unsigned long __Pyx_get_runtime_version(void) { +#if __PYX_LIMITED_VERSION_HEX >= 0x030b0000 + return Py_Version & ~0xFFUL; +#else + return __Pyx_cached_runtime_version; +#endif +} + +/* CheckBinaryVersion */ +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer) { + const unsigned long MAJOR_MINOR = 0xFFFF0000UL; + if ((rt_version & MAJOR_MINOR) == (ct_version & MAJOR_MINOR)) + return 0; + if (likely(allow_newer && (rt_version & MAJOR_MINOR) > (ct_version & MAJOR_MINOR))) + return 1; + { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compile time Python version %d.%d " + "of module '%.100s' " + "%s " + "runtime version %d.%d", + (int) (ct_version >> 24), (int) ((ct_version >> 16) & 0xFF), + __Pyx_MODULE_NAME, + (allow_newer) ? "was newer than" : "does not match", + (int) (rt_version >> 24), (int) ((rt_version >> 16) & 0xFF) + ); + return PyErr_WarnEx(NULL, message, 1); + } +} + +/* NewCodeObj */ +#if CYTHON_COMPILING_IN_LIMITED_API + static PyObject* __Pyx__PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyObject *exception_table = NULL; + PyObject *types_module=NULL, *code_type=NULL, *result=NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030b0000 + PyObject *version_info; + PyObject *py_minor_version = NULL; + #endif + long minor_version = 0; + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + #if __PYX_LIMITED_VERSION_HEX >= 0x030b0000 + minor_version = 11; + #else + if (!(version_info = PySys_GetObject("version_info"))) goto end; + if (!(py_minor_version = PySequence_GetItem(version_info, 1))) goto end; + minor_version = PyLong_AsLong(py_minor_version); + Py_DECREF(py_minor_version); + if (minor_version == -1 && PyErr_Occurred()) goto end; + #endif + if (!(types_module = PyImport_ImportModule("types"))) goto end; + if (!(code_type = PyObject_GetAttrString(types_module, "CodeType"))) goto end; + if (minor_version <= 7) { + (void)p; + result = PyObject_CallFunction(code_type, "iiiiiOOOOOOiOOO", a, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else if (minor_version <= 10) { + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOiOOO", a,p, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else { + if (!(exception_table = PyBytes_FromStringAndSize(NULL, 0))) goto end; + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOOiOOOO", a,p, k, l, s, f, code, + c, n, v, fn, name, name, fline, lnos, exception_table, fv, cell); + } + end: + Py_XDECREF(code_type); + Py_XDECREF(exception_table); + Py_XDECREF(types_module); + if (type) { + PyErr_Restore(type, value, traceback); + } + return result; + } +#elif PY_VERSION_HEX >= 0x030B0000 + static PyCodeObject* __Pyx__PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyCodeObject *result; + result = + #if PY_VERSION_HEX >= 0x030C0000 + PyUnstable_Code_NewWithPosOnlyArgs + #else + PyCode_NewWithPosOnlyArgs + #endif + (a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, __pyx_mstate_global->__pyx_empty_bytes); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030c00A1 + if (likely(result)) + result->_co_firsttraceable = 0; + #endif + return result; + } +#elif !CYTHON_COMPILING_IN_PYPY + #define __Pyx__PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_NewWithPosOnlyArgs(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx__PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif +static PyObject* __Pyx_PyCode_New( + const __Pyx_PyCode_New_function_description descr, + PyObject * const *varnames, + PyObject *filename, + PyObject *funcname, + PyObject *line_table, + PyObject *tuple_dedup_map +) { + PyObject *code_obj = NULL, *varnames_tuple_dedup = NULL, *code_bytes = NULL; + Py_ssize_t var_count = (Py_ssize_t) descr.nlocals; + PyObject *varnames_tuple = PyTuple_New(var_count); + if (unlikely(!varnames_tuple)) return NULL; + for (Py_ssize_t i=0; i < var_count; i++) { + Py_INCREF(varnames[i]); + if (__Pyx_PyTuple_SET_ITEM(varnames_tuple, i, varnames[i]) != (0)) goto done; + } + #if CYTHON_COMPILING_IN_LIMITED_API + varnames_tuple_dedup = PyDict_GetItem(tuple_dedup_map, varnames_tuple); + if (!varnames_tuple_dedup) { + if (unlikely(PyDict_SetItem(tuple_dedup_map, varnames_tuple, varnames_tuple) < 0)) goto done; + varnames_tuple_dedup = varnames_tuple; + } + #else + varnames_tuple_dedup = PyDict_SetDefault(tuple_dedup_map, varnames_tuple, varnames_tuple); + if (unlikely(!varnames_tuple_dedup)) goto done; + #endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(varnames_tuple_dedup); + #endif + if (__PYX_LIMITED_VERSION_HEX >= (0x030b0000) && line_table != NULL && !CYTHON_COMPILING_IN_GRAAL) { + Py_ssize_t line_table_length = __Pyx_PyBytes_GET_SIZE(line_table); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(line_table_length == -1)) goto done; + #endif + Py_ssize_t code_len = (line_table_length * 2 + 4) & ~3LL; + code_bytes = PyBytes_FromStringAndSize(NULL, code_len); + if (unlikely(!code_bytes)) goto done; + char* c_code_bytes = PyBytes_AsString(code_bytes); + if (unlikely(!c_code_bytes)) goto done; + memset(c_code_bytes, 0, (size_t) code_len); + } + code_obj = (PyObject*) __Pyx__PyCode_New( + (int) descr.argcount, + (int) descr.num_posonly_args, + (int) descr.num_kwonly_args, + (int) descr.nlocals, + 0, + (int) descr.flags, + code_bytes ? code_bytes : __pyx_mstate_global->__pyx_empty_bytes, + __pyx_mstate_global->__pyx_empty_tuple, + __pyx_mstate_global->__pyx_empty_tuple, + varnames_tuple_dedup, + __pyx_mstate_global->__pyx_empty_tuple, + __pyx_mstate_global->__pyx_empty_tuple, + filename, + funcname, + (int) descr.first_line, + (__PYX_LIMITED_VERSION_HEX >= (0x030b0000) && line_table) ? line_table : __pyx_mstate_global->__pyx_empty_bytes + ); +done: + Py_XDECREF(code_bytes); + #if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(varnames_tuple_dedup); + #endif + Py_DECREF(varnames_tuple); + return code_obj; +} + +/* DecompressString */ +static PyObject *__Pyx_DecompressString(const char *s, Py_ssize_t length, int algo) { + PyObject *module, *decompress, *compressed_bytes, *decompressed; + const char* module_name = algo == 3 ? "compression.zstd" : algo == 2 ? "bz2" : "zlib"; + PyObject *methodname = PyUnicode_FromString("decompress"); + if (unlikely(!methodname)) return NULL; + #if __PYX_LIMITED_VERSION_HEX >= 0x030e0000 + if (algo == 3) { + PyObject *fromlist = Py_BuildValue("[O]", methodname); + if (unlikely(!fromlist)) return NULL; + module = PyImport_ImportModuleLevel("compression.zstd", NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + } else + #endif + module = PyImport_ImportModule(module_name); + if (unlikely(!module)) goto import_failed; + decompress = PyObject_GetAttr(module, methodname); + if (unlikely(!decompress)) goto import_failed; + { + #ifdef __cplusplus + char *memview_bytes = const_cast(s); + #else + #if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wcast-qual" + #elif !defined(__INTEL_COMPILER) && defined(__GNUC__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-qual" + #endif + char *memview_bytes = (char*) s; + #if defined(__clang__) + #pragma clang diagnostic pop + #elif !defined(__INTEL_COMPILER) && defined(__GNUC__) + #pragma GCC diagnostic pop + #endif + #endif + #if CYTHON_COMPILING_IN_LIMITED_API && !defined(PyBUF_READ) + int memview_flags = 0x100; + #else + int memview_flags = PyBUF_READ; + #endif + compressed_bytes = PyMemoryView_FromMemory(memview_bytes, length, memview_flags); + } + if (unlikely(!compressed_bytes)) { + Py_DECREF(decompress); + goto bad; + } + decompressed = PyObject_CallFunctionObjArgs(decompress, compressed_bytes, NULL); + Py_DECREF(compressed_bytes); + Py_DECREF(decompress); + Py_DECREF(module); + Py_DECREF(methodname); + return decompressed; +import_failed: + PyErr_Format(PyExc_ImportError, + "Failed to import '%.20s.decompress' - cannot initialise module strings. " + "String compression was configured with the C macro 'CYTHON_COMPRESS_STRINGS=%d'.", + module_name, algo); +bad: + Py_XDECREF(module); + Py_DECREF(methodname); + return NULL; +} + +#include +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s) { + size_t len = strlen(s); + if (unlikely(len > (size_t) PY_SSIZE_T_MAX)) { + PyErr_SetString(PyExc_OverflowError, "byte string is too long"); + return -1; + } + return (Py_ssize_t) len; +} +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return __Pyx_PyUnicode_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return PyByteArray_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + { + const char* result; + Py_ssize_t unicode_length; + CYTHON_MAYBE_UNUSED_VAR(unicode_length); // only for __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + #if __PYX_LIMITED_VERSION_HEX < 0x030A0000 + if (unlikely(PyArg_Parse(o, "s#", &result, length) < 0)) return NULL; + #else + result = PyUnicode_AsUTF8AndSize(o, length); + #endif + #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + unicode_length = PyUnicode_GetLength(o); + if (unlikely(unicode_length < 0)) return NULL; + if (unlikely(unicode_length != *length)) { + PyUnicode_AsASCIIString(o); + return NULL; + } + #endif + return result; + } +#else +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +#endif +} +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 + if (PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif + if (PyByteArray_Check(o)) { +#if (CYTHON_ASSUME_SAFE_SIZE && CYTHON_ASSUME_SAFE_MACROS) || (CYTHON_COMPILING_IN_PYPY && (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE))) + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); +#else + *length = PyByteArray_Size(o); + if (*length == -1) return NULL; + return PyByteArray_AsString(o); +#endif + } else + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_LongWrongResultType(PyObject* result) { + __Pyx_TypeName result_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(result)); + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME "). " + "The ability to return an instance of a strict subclass of int is deprecated, " + "and may be removed in a future version of Python.", + result_type_name)) { + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; + } + __Pyx_DECREF_TypeName(result_type_name); + return result; + } + PyErr_Format(PyExc_TypeError, + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME ")", + result_type_name); + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_Long(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + PyObject *res = NULL; + if (likely(PyLong_Check(x))) + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + if (likely(m && m->nb_int)) { + res = m->nb_int(x); + } +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Long(x); + } +#endif + if (likely(res)) { + if (unlikely(!PyLong_CheckExact(res))) { + return __Pyx_PyNumber_LongWrongResultType(res); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(__Pyx_PyLong_IsCompact(b))) { + return __Pyx_PyLong_CompactValue(b); + } else { + const digit* digits = __Pyx_PyLong_Digits(b); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(b); + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyLong_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) { + if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) { + return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o); + } else { + Py_ssize_t ival; + PyObject *x; + x = PyNumber_Index(o); + if (!x) return -1; + ival = PyLong_AsLong(x); + Py_DECREF(x); + return ival; + } +} +static CYTHON_INLINE PyObject *__Pyx_Owned_Py_None(int b) { + CYTHON_UNUSED_VAR(b); + return __Pyx_NewRef(Py_None); +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return __Pyx_NewRef(b ? Py_True: Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyLong_FromSize_t(size_t ival) { + return PyLong_FromSize_t(ival); +} + + +/* MultiPhaseInitModuleState */ +#if CYTHON_PEP489_MULTI_PHASE_INIT && CYTHON_USE_MODULE_STATE +#ifndef CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +#if (CYTHON_COMPILING_IN_LIMITED_API || PY_VERSION_HEX >= 0x030C0000) + #define CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE 1 +#else + #define CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE 0 +#endif +#endif +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE && !CYTHON_ATOMICS +#error "Module state with PEP489 requires atomics. Currently that's one of\ + C11, C++11, gcc atomic intrinsics or MSVC atomic intrinsics" +#endif +#if !CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +#define __Pyx_ModuleStateLookup_Lock() +#define __Pyx_ModuleStateLookup_Unlock() +#elif !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d0000 +static PyMutex __Pyx_ModuleStateLookup_mutex = {0}; +#define __Pyx_ModuleStateLookup_Lock() PyMutex_Lock(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() PyMutex_Unlock(&__Pyx_ModuleStateLookup_mutex) +#elif defined(__cplusplus) && __cplusplus >= 201103L +#include +static std::mutex __Pyx_ModuleStateLookup_mutex; +#define __Pyx_ModuleStateLookup_Lock() __Pyx_ModuleStateLookup_mutex.lock() +#define __Pyx_ModuleStateLookup_Unlock() __Pyx_ModuleStateLookup_mutex.unlock() +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201112L) && !defined(__STDC_NO_THREADS__) +#include +static mtx_t __Pyx_ModuleStateLookup_mutex; +static once_flag __Pyx_ModuleStateLookup_mutex_once_flag = ONCE_FLAG_INIT; +static void __Pyx_ModuleStateLookup_initialize_mutex(void) { + mtx_init(&__Pyx_ModuleStateLookup_mutex, mtx_plain); +} +#define __Pyx_ModuleStateLookup_Lock()\ + call_once(&__Pyx_ModuleStateLookup_mutex_once_flag, __Pyx_ModuleStateLookup_initialize_mutex);\ + mtx_lock(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() mtx_unlock(&__Pyx_ModuleStateLookup_mutex) +#elif defined(HAVE_PTHREAD_H) +#include +static pthread_mutex_t __Pyx_ModuleStateLookup_mutex = PTHREAD_MUTEX_INITIALIZER; +#define __Pyx_ModuleStateLookup_Lock() pthread_mutex_lock(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() pthread_mutex_unlock(&__Pyx_ModuleStateLookup_mutex) +#elif defined(_WIN32) +#include // synchapi.h on its own doesn't work +static SRWLOCK __Pyx_ModuleStateLookup_mutex = SRWLOCK_INIT; +#define __Pyx_ModuleStateLookup_Lock() AcquireSRWLockExclusive(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() ReleaseSRWLockExclusive(&__Pyx_ModuleStateLookup_mutex) +#else +#error "No suitable lock available for CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE.\ + Requires C standard >= C11, or C++ standard >= C++11,\ + or pthreads, or the Windows 32 API, or Python >= 3.13." +#endif +typedef struct { + int64_t id; + PyObject *module; +} __Pyx_InterpreterIdAndModule; +typedef struct { + char interpreter_id_as_index; + Py_ssize_t count; + Py_ssize_t allocated; + __Pyx_InterpreterIdAndModule table[1]; +} __Pyx_ModuleStateLookupData; +#define __PYX_MODULE_STATE_LOOKUP_SMALL_SIZE 32 +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +static __pyx_atomic_int_type __Pyx_ModuleStateLookup_read_counter = 0; +#endif +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +static __pyx_atomic_ptr_type __Pyx_ModuleStateLookup_data = 0; +#else +static __Pyx_ModuleStateLookupData* __Pyx_ModuleStateLookup_data = NULL; +#endif +static __Pyx_InterpreterIdAndModule* __Pyx_State_FindModuleStateLookupTableLowerBound( + __Pyx_InterpreterIdAndModule* table, + Py_ssize_t count, + int64_t interpreterId) { + __Pyx_InterpreterIdAndModule* begin = table; + __Pyx_InterpreterIdAndModule* end = begin + count; + if (begin->id == interpreterId) { + return begin; + } + while ((end - begin) > __PYX_MODULE_STATE_LOOKUP_SMALL_SIZE) { + __Pyx_InterpreterIdAndModule* halfway = begin + (end - begin)/2; + if (halfway->id == interpreterId) { + return halfway; + } + if (halfway->id < interpreterId) { + begin = halfway; + } else { + end = halfway; + } + } + for (; begin < end; ++begin) { + if (begin->id >= interpreterId) return begin; + } + return begin; +} +static PyObject *__Pyx_State_FindModule(CYTHON_UNUSED void* dummy) { + int64_t interpreter_id = PyInterpreterState_GetID(__Pyx_PyInterpreterState_Get()); + if (interpreter_id == -1) return NULL; +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __Pyx_ModuleStateLookupData* data = (__Pyx_ModuleStateLookupData*)__pyx_atomic_pointer_load_relaxed(&__Pyx_ModuleStateLookup_data); + { + __pyx_atomic_incr_acq_rel(&__Pyx_ModuleStateLookup_read_counter); + if (likely(data)) { + __Pyx_ModuleStateLookupData* new_data = (__Pyx_ModuleStateLookupData*)__pyx_atomic_pointer_load_acquire(&__Pyx_ModuleStateLookup_data); + if (likely(data == new_data)) { + goto read_finished; + } + } + __pyx_atomic_decr_acq_rel(&__Pyx_ModuleStateLookup_read_counter); + __Pyx_ModuleStateLookup_Lock(); + __pyx_atomic_incr_relaxed(&__Pyx_ModuleStateLookup_read_counter); + data = (__Pyx_ModuleStateLookupData*)__pyx_atomic_pointer_load_relaxed(&__Pyx_ModuleStateLookup_data); + __Pyx_ModuleStateLookup_Unlock(); + } + read_finished:; +#else + __Pyx_ModuleStateLookupData* data = __Pyx_ModuleStateLookup_data; +#endif + __Pyx_InterpreterIdAndModule* found = NULL; + if (unlikely(!data)) goto end; + if (data->interpreter_id_as_index) { + if (interpreter_id < data->count) { + found = data->table+interpreter_id; + } + } else { + found = __Pyx_State_FindModuleStateLookupTableLowerBound( + data->table, data->count, interpreter_id); + } + end: + { + PyObject *result=NULL; + if (found && found->id == interpreter_id) { + result = found->module; + } +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __pyx_atomic_decr_acq_rel(&__Pyx_ModuleStateLookup_read_counter); +#endif + return result; + } +} +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +static void __Pyx_ModuleStateLookup_wait_until_no_readers(void) { + while (__pyx_atomic_load(&__Pyx_ModuleStateLookup_read_counter) != 0); +} +#else +#define __Pyx_ModuleStateLookup_wait_until_no_readers() +#endif +static int __Pyx_State_AddModuleInterpIdAsIndex(__Pyx_ModuleStateLookupData **old_data, PyObject* module, int64_t interpreter_id) { + Py_ssize_t to_allocate = (*old_data)->allocated; + while (to_allocate <= interpreter_id) { + if (to_allocate == 0) to_allocate = 1; + else to_allocate *= 2; + } + __Pyx_ModuleStateLookupData *new_data = *old_data; + if (to_allocate != (*old_data)->allocated) { + new_data = (__Pyx_ModuleStateLookupData *)realloc( + *old_data, + sizeof(__Pyx_ModuleStateLookupData)+(to_allocate-1)*sizeof(__Pyx_InterpreterIdAndModule)); + if (!new_data) { + PyErr_NoMemory(); + return -1; + } + for (Py_ssize_t i = new_data->allocated; i < to_allocate; ++i) { + new_data->table[i].id = i; + new_data->table[i].module = NULL; + } + new_data->allocated = to_allocate; + } + new_data->table[interpreter_id].module = module; + if (new_data->count < interpreter_id+1) { + new_data->count = interpreter_id+1; + } + *old_data = new_data; + return 0; +} +static void __Pyx_State_ConvertFromInterpIdAsIndex(__Pyx_ModuleStateLookupData *data) { + __Pyx_InterpreterIdAndModule *read = data->table; + __Pyx_InterpreterIdAndModule *write = data->table; + __Pyx_InterpreterIdAndModule *end = read + data->count; + for (; readmodule) { + write->id = read->id; + write->module = read->module; + ++write; + } + } + data->count = write - data->table; + for (; writeid = 0; + write->module = NULL; + } + data->interpreter_id_as_index = 0; +} +static int __Pyx_State_AddModule(PyObject* module, CYTHON_UNUSED void* dummy) { + int64_t interpreter_id = PyInterpreterState_GetID(__Pyx_PyInterpreterState_Get()); + if (interpreter_id == -1) return -1; + int result = 0; + __Pyx_ModuleStateLookup_Lock(); +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __Pyx_ModuleStateLookupData *old_data = (__Pyx_ModuleStateLookupData *) + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, 0); +#else + __Pyx_ModuleStateLookupData *old_data = __Pyx_ModuleStateLookup_data; +#endif + __Pyx_ModuleStateLookupData *new_data = old_data; + if (!new_data) { + new_data = (__Pyx_ModuleStateLookupData *)calloc(1, sizeof(__Pyx_ModuleStateLookupData)); + if (!new_data) { + result = -1; + PyErr_NoMemory(); + goto end; + } + new_data->allocated = 1; + new_data->interpreter_id_as_index = 1; + } + __Pyx_ModuleStateLookup_wait_until_no_readers(); + if (new_data->interpreter_id_as_index) { + if (interpreter_id < __PYX_MODULE_STATE_LOOKUP_SMALL_SIZE) { + result = __Pyx_State_AddModuleInterpIdAsIndex(&new_data, module, interpreter_id); + goto end; + } + __Pyx_State_ConvertFromInterpIdAsIndex(new_data); + } + { + Py_ssize_t insert_at = 0; + { + __Pyx_InterpreterIdAndModule* lower_bound = __Pyx_State_FindModuleStateLookupTableLowerBound( + new_data->table, new_data->count, interpreter_id); + assert(lower_bound); + insert_at = lower_bound - new_data->table; + if (unlikely(insert_at < new_data->count && lower_bound->id == interpreter_id)) { + lower_bound->module = module; + goto end; // already in table, nothing more to do + } + } + if (new_data->count+1 >= new_data->allocated) { + Py_ssize_t to_allocate = (new_data->count+1)*2; + new_data = + (__Pyx_ModuleStateLookupData*)realloc( + new_data, + sizeof(__Pyx_ModuleStateLookupData) + + (to_allocate-1)*sizeof(__Pyx_InterpreterIdAndModule)); + if (!new_data) { + result = -1; + new_data = old_data; + PyErr_NoMemory(); + goto end; + } + new_data->allocated = to_allocate; + } + ++new_data->count; + int64_t last_id = interpreter_id; + PyObject *last_module = module; + for (Py_ssize_t i=insert_at; icount; ++i) { + int64_t current_id = new_data->table[i].id; + new_data->table[i].id = last_id; + last_id = current_id; + PyObject *current_module = new_data->table[i].module; + new_data->table[i].module = last_module; + last_module = current_module; + } + } + end: +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, new_data); +#else + __Pyx_ModuleStateLookup_data = new_data; +#endif + __Pyx_ModuleStateLookup_Unlock(); + return result; +} +static int __Pyx_State_RemoveModule(CYTHON_UNUSED void* dummy) { + int64_t interpreter_id = PyInterpreterState_GetID(__Pyx_PyInterpreterState_Get()); + if (interpreter_id == -1) return -1; + __Pyx_ModuleStateLookup_Lock(); +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __Pyx_ModuleStateLookupData *data = (__Pyx_ModuleStateLookupData *) + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, 0); +#else + __Pyx_ModuleStateLookupData *data = __Pyx_ModuleStateLookup_data; +#endif + if (data->interpreter_id_as_index) { + if (interpreter_id < data->count) { + data->table[interpreter_id].module = NULL; + } + goto done; + } + { + __Pyx_ModuleStateLookup_wait_until_no_readers(); + __Pyx_InterpreterIdAndModule* lower_bound = __Pyx_State_FindModuleStateLookupTableLowerBound( + data->table, data->count, interpreter_id); + if (!lower_bound) goto done; + if (lower_bound->id != interpreter_id) goto done; + __Pyx_InterpreterIdAndModule *end = data->table+data->count; + for (;lower_boundid = (lower_bound+1)->id; + lower_bound->module = (lower_bound+1)->module; + } + } + --data->count; + if (data->count == 0) { + free(data); + data = NULL; + } + done: +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, data); +#else + __Pyx_ModuleStateLookup_data = data; +#endif + __Pyx_ModuleStateLookup_Unlock(); + return 0; +} +#endif + +/* #### Code section: utility_code_pragmas_end ### */ +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + + + +/* #### Code section: end ### */ +#endif /* Py_PYTHON_H */ diff --git a/.venv/lib/python3.13/site-packages/fontTools/feaLib/lexer.py b/.venv/lib/python3.13/site-packages/fontTools/feaLib/lexer.py new file mode 100644 index 0000000000000000000000000000000000000000..4b6499d06f591efbdb5e603cbcd256840695f431 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/feaLib/lexer.py @@ -0,0 +1,287 @@ +from fontTools.feaLib.error import FeatureLibError, IncludedFeaNotFound +from fontTools.feaLib.location import FeatureLibLocation +import re +import os + +try: + import cython +except ImportError: + # if cython not installed, use mock module with no-op decorators and types + from fontTools.misc import cython + + +class Lexer(object): + NUMBER = "NUMBER" + HEXADECIMAL = "HEXADECIMAL" + OCTAL = "OCTAL" + NUMBERS = (NUMBER, HEXADECIMAL, OCTAL) + FLOAT = "FLOAT" + STRING = "STRING" + NAME = "NAME" + FILENAME = "FILENAME" + GLYPHCLASS = "GLYPHCLASS" + CID = "CID" + SYMBOL = "SYMBOL" + COMMENT = "COMMENT" + NEWLINE = "NEWLINE" + ANONYMOUS_BLOCK = "ANONYMOUS_BLOCK" + + CHAR_WHITESPACE_ = " \t" + CHAR_NEWLINE_ = "\r\n" + CHAR_SYMBOL_ = ",;:-+'{}[]<>()=" + CHAR_DIGIT_ = "0123456789" + CHAR_HEXDIGIT_ = "0123456789ABCDEFabcdef" + CHAR_LETTER_ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + CHAR_NAME_START_ = CHAR_LETTER_ + "_+*:.^~!\\" + CHAR_NAME_CONTINUATION_ = CHAR_LETTER_ + CHAR_DIGIT_ + "_.+*:^~!/-" + + RE_GLYPHCLASS = re.compile(r"^[A-Za-z_0-9.\-]+$") + + MODE_NORMAL_ = "NORMAL" + MODE_FILENAME_ = "FILENAME" + + def __init__(self, text, filename): + self.filename_ = filename + self.line_ = 1 + self.pos_ = 0 + self.line_start_ = 0 + self.text_ = text + self.text_length_ = len(text) + self.mode_ = Lexer.MODE_NORMAL_ + + def __iter__(self): + return self + + def next(self): # Python 2 + return self.__next__() + + def __next__(self): # Python 3 + while True: + token_type, token, location = self.next_() + if token_type != Lexer.NEWLINE: + return (token_type, token, location) + + def location_(self): + column = self.pos_ - self.line_start_ + 1 + return FeatureLibLocation(self.filename_ or "", self.line_, column) + + def next_(self): + self.scan_over_(Lexer.CHAR_WHITESPACE_) + location = self.location_() + start = self.pos_ + text = self.text_ + limit = len(text) + if start >= limit: + raise StopIteration() + cur_char = text[start] + next_char = text[start + 1] if start + 1 < limit else None + + if cur_char == "\n": + self.pos_ += 1 + self.line_ += 1 + self.line_start_ = self.pos_ + return (Lexer.NEWLINE, None, location) + if cur_char == "\r": + self.pos_ += 2 if next_char == "\n" else 1 + self.line_ += 1 + self.line_start_ = self.pos_ + return (Lexer.NEWLINE, None, location) + if cur_char == "#": + self.scan_until_(Lexer.CHAR_NEWLINE_) + return (Lexer.COMMENT, text[start : self.pos_], location) + + if self.mode_ is Lexer.MODE_FILENAME_: + if cur_char != "(": + raise FeatureLibError("Expected '(' before file name", location) + self.scan_until_(")") + cur_char = text[self.pos_] if self.pos_ < limit else None + if cur_char != ")": + raise FeatureLibError("Expected ')' after file name", location) + self.pos_ += 1 + self.mode_ = Lexer.MODE_NORMAL_ + return (Lexer.FILENAME, text[start + 1 : self.pos_ - 1], location) + + if cur_char == "\\" and next_char in Lexer.CHAR_DIGIT_: + self.pos_ += 1 + self.scan_over_(Lexer.CHAR_DIGIT_) + return (Lexer.CID, int(text[start + 1 : self.pos_], 10), location) + if cur_char == "@": + self.pos_ += 1 + self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) + glyphclass = text[start + 1 : self.pos_] + if len(glyphclass) < 1: + raise FeatureLibError("Expected glyph class name", location) + if not Lexer.RE_GLYPHCLASS.match(glyphclass): + raise FeatureLibError( + "Glyph class names must consist of letters, digits, " + "underscore, period or hyphen", + location, + ) + return (Lexer.GLYPHCLASS, glyphclass, location) + if cur_char in Lexer.CHAR_NAME_START_: + self.pos_ += 1 + self.scan_over_(Lexer.CHAR_NAME_CONTINUATION_) + token = text[start : self.pos_] + if token == "include": + self.mode_ = Lexer.MODE_FILENAME_ + return (Lexer.NAME, token, location) + if cur_char == "0" and next_char in "xX": + self.pos_ += 2 + self.scan_over_(Lexer.CHAR_HEXDIGIT_) + return (Lexer.HEXADECIMAL, int(text[start : self.pos_], 16), location) + if cur_char == "0" and next_char in Lexer.CHAR_DIGIT_: + self.scan_over_(Lexer.CHAR_DIGIT_) + return (Lexer.OCTAL, int(text[start : self.pos_], 8), location) + if cur_char in Lexer.CHAR_DIGIT_: + self.scan_over_(Lexer.CHAR_DIGIT_) + if self.pos_ >= limit or text[self.pos_] != ".": + return (Lexer.NUMBER, int(text[start : self.pos_], 10), location) + self.scan_over_(".") + self.scan_over_(Lexer.CHAR_DIGIT_) + return (Lexer.FLOAT, float(text[start : self.pos_]), location) + if cur_char == "-" and next_char in Lexer.CHAR_DIGIT_: + self.pos_ += 1 + self.scan_over_(Lexer.CHAR_DIGIT_) + if self.pos_ >= limit or text[self.pos_] != ".": + return (Lexer.NUMBER, int(text[start : self.pos_], 10), location) + self.scan_over_(".") + self.scan_over_(Lexer.CHAR_DIGIT_) + return (Lexer.FLOAT, float(text[start : self.pos_]), location) + if cur_char in Lexer.CHAR_SYMBOL_: + self.pos_ += 1 + return (Lexer.SYMBOL, cur_char, location) + if cur_char == '"': + self.pos_ += 1 + self.scan_until_('"') + if self.pos_ < self.text_length_ and self.text_[self.pos_] == '"': + self.pos_ += 1 + # strip newlines embedded within a string + string = re.sub("[\r\n]", "", text[start + 1 : self.pos_ - 1]) + return (Lexer.STRING, string, location) + else: + raise FeatureLibError("Expected '\"' to terminate string", location) + raise FeatureLibError("Unexpected character: %r" % cur_char, location) + + def scan_over_(self, valid): + p = self.pos_ + while p < self.text_length_ and self.text_[p] in valid: + p += 1 + self.pos_ = p + + def scan_until_(self, stop_at): + p = self.pos_ + while p < self.text_length_ and self.text_[p] not in stop_at: + p += 1 + self.pos_ = p + + def scan_anonymous_block(self, tag): + location = self.location_() + tag = tag.strip() + self.scan_until_(Lexer.CHAR_NEWLINE_) + self.scan_over_(Lexer.CHAR_NEWLINE_) + regexp = r"}\s*" + tag + r"\s*;" + split = re.split(regexp, self.text_[self.pos_ :], maxsplit=1) + if len(split) != 2: + raise FeatureLibError( + "Expected '} %s;' to terminate anonymous block" % tag, location + ) + self.pos_ += len(split[0]) + return (Lexer.ANONYMOUS_BLOCK, split[0], location) + + +class IncludingLexer(object): + """A Lexer that follows include statements. + + The OpenType feature file specification states that due to + historical reasons, relative imports should be resolved in this + order: + + 1. If the source font is UFO format, then relative to the UFO's + font directory + 2. relative to the top-level include file + 3. relative to the parent include file + + We only support 1 (via includeDir) and 2. + """ + + def __init__(self, featurefile, *, includeDir=None): + """Initializes an IncludingLexer. + + Behavior: + If includeDir is passed, it will be used to determine the top-level + include directory to use for all encountered include statements. If it is + not passed, ``os.path.dirname(featurefile)`` will be considered the + include directory. + """ + + self.lexers_ = [self.make_lexer_(featurefile)] + self.featurefilepath = self.lexers_[0].filename_ + self.includeDir = includeDir + + def __iter__(self): + return self + + def next(self): # Python 2 + return self.__next__() + + def __next__(self): # Python 3 + while self.lexers_: + lexer = self.lexers_[-1] + try: + token_type, token, location = next(lexer) + except StopIteration: + self.lexers_.pop() + continue + if token_type is Lexer.NAME and token == "include": + fname_type, fname_token, fname_location = lexer.next() + if fname_type is not Lexer.FILENAME: + raise FeatureLibError("Expected file name", fname_location) + # semi_type, semi_token, semi_location = lexer.next() + # if semi_type is not Lexer.SYMBOL or semi_token != ";": + # raise FeatureLibError("Expected ';'", semi_location) + if os.path.isabs(fname_token): + path = fname_token + else: + if self.includeDir is not None: + curpath = self.includeDir + elif self.featurefilepath is not None: + curpath = os.path.dirname(self.featurefilepath) + else: + # if the IncludingLexer was initialized from an in-memory + # file-like stream, it doesn't have a 'name' pointing to + # its filesystem path, therefore we fall back to using the + # current working directory to resolve relative includes + curpath = os.getcwd() + path = os.path.join(curpath, fname_token) + if len(self.lexers_) >= 5: + raise FeatureLibError("Too many recursive includes", fname_location) + try: + self.lexers_.append(self.make_lexer_(path)) + except FileNotFoundError as err: + raise IncludedFeaNotFound(fname_token, fname_location) from err + else: + return (token_type, token, location) + raise StopIteration() + + @staticmethod + def make_lexer_(file_or_path): + if hasattr(file_or_path, "read"): + fileobj, closing = file_or_path, False + else: + filename, closing = file_or_path, True + fileobj = open(filename, "r", encoding="utf-8-sig") + data = fileobj.read() + filename = getattr(fileobj, "name", None) + if closing: + fileobj.close() + return Lexer(data, filename) + + def scan_anonymous_block(self, tag): + return self.lexers_[-1].scan_anonymous_block(tag) + + +class NonIncludingLexer(IncludingLexer): + """Lexer that does not follow `include` statements, emits them as-is.""" + + def __next__(self): # Python 3 + return next(self.lexers_[0]) diff --git a/.venv/lib/python3.13/site-packages/fontTools/feaLib/location.py b/.venv/lib/python3.13/site-packages/fontTools/feaLib/location.py new file mode 100644 index 0000000000000000000000000000000000000000..50f761d2d2a13bd101a7db9c259fedc98eed52cf --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/feaLib/location.py @@ -0,0 +1,12 @@ +from typing import NamedTuple + + +class FeatureLibLocation(NamedTuple): + """A location in a feature file""" + + file: str + line: int + column: int + + def __str__(self): + return f"{self.file}:{self.line}:{self.column}" diff --git a/.venv/lib/python3.13/site-packages/fontTools/feaLib/lookupDebugInfo.py b/.venv/lib/python3.13/site-packages/fontTools/feaLib/lookupDebugInfo.py new file mode 100644 index 0000000000000000000000000000000000000000..d4da7de0aed6b87dae6a1d4b417f1c6e099fe1e0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/feaLib/lookupDebugInfo.py @@ -0,0 +1,12 @@ +from typing import NamedTuple + +LOOKUP_DEBUG_INFO_KEY = "com.github.fonttools.feaLib" +LOOKUP_DEBUG_ENV_VAR = "FONTTOOLS_LOOKUP_DEBUGGING" + + +class LookupDebugInfo(NamedTuple): + """Information about where a lookup came from, to be embedded in a font""" + + location: str + name: str + feature: list diff --git a/.venv/lib/python3.13/site-packages/fontTools/feaLib/parser.py b/.venv/lib/python3.13/site-packages/fontTools/feaLib/parser.py new file mode 100644 index 0000000000000000000000000000000000000000..0e211e0032a9cab8a4374461297d7344a9d5c1f4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/feaLib/parser.py @@ -0,0 +1,2394 @@ +from fontTools.feaLib.error import FeatureLibError +from fontTools.feaLib.lexer import Lexer, IncludingLexer, NonIncludingLexer +from fontTools.feaLib.variableScalar import VariableScalar +from fontTools.misc.encodingTools import getEncoding +from fontTools.misc.textTools import bytechr, tobytes, tostr +import fontTools.feaLib.ast as ast +import logging +import os +import re + + +log = logging.getLogger(__name__) + + +class Parser(object): + """Initializes a Parser object. + + Example: + + .. code:: python + + from fontTools.feaLib.parser import Parser + parser = Parser(file, font.getReverseGlyphMap()) + parsetree = parser.parse() + + Note: the ``glyphNames`` iterable serves a double role to help distinguish + glyph names from ranges in the presence of hyphens and to ensure that glyph + names referenced in a feature file are actually part of a font's glyph set. + If the iterable is left empty, no glyph name in glyph set checking takes + place, and all glyph tokens containing hyphens are treated as literal glyph + names, not as ranges. (Adding a space around the hyphen can, in any case, + help to disambiguate ranges from glyph names containing hyphens.) + + By default, the parser will follow ``include()`` statements in the feature + file. To turn this off, pass ``followIncludes=False``. Pass a directory string as + ``includeDir`` to explicitly declare a directory to search included feature files + in. + """ + + extensions = {} + ast = ast + SS_FEATURE_TAGS = {"ss%02d" % i for i in range(1, 20 + 1)} + CV_FEATURE_TAGS = {"cv%02d" % i for i in range(1, 99 + 1)} + + def __init__( + self, featurefile, glyphNames=(), followIncludes=True, includeDir=None, **kwargs + ): + if "glyphMap" in kwargs: + from fontTools.misc.loggingTools import deprecateArgument + + deprecateArgument("glyphMap", "use 'glyphNames' (iterable) instead") + if glyphNames: + raise TypeError( + "'glyphNames' and (deprecated) 'glyphMap' are " "mutually exclusive" + ) + glyphNames = kwargs.pop("glyphMap") + if kwargs: + raise TypeError( + "unsupported keyword argument%s: %s" + % ("" if len(kwargs) == 1 else "s", ", ".join(repr(k) for k in kwargs)) + ) + + self.glyphNames_ = set(glyphNames) + self.doc_ = self.ast.FeatureFile() + self.anchors_ = SymbolTable() + self.glyphclasses_ = SymbolTable() + self.lookups_ = SymbolTable() + self.valuerecords_ = SymbolTable() + self.symbol_tables_ = {self.anchors_, self.valuerecords_} + self.next_token_type_, self.next_token_ = (None, None) + self.cur_comments_ = [] + self.next_token_location_ = None + lexerClass = IncludingLexer if followIncludes else NonIncludingLexer + self.lexer_ = lexerClass(featurefile, includeDir=includeDir) + self.missing = {} + self.advance_lexer_(comments=True) + + def parse(self): + """Parse the file, and return a :class:`fontTools.feaLib.ast.FeatureFile` + object representing the root of the abstract syntax tree containing the + parsed contents of the file.""" + statements = self.doc_.statements + while self.next_token_type_ is not None or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.is_cur_keyword_("include"): + statements.append(self.parse_include_()) + elif self.cur_token_type_ is Lexer.GLYPHCLASS: + statements.append(self.parse_glyphclass_definition_()) + elif self.is_cur_keyword_(("anon", "anonymous")): + statements.append(self.parse_anonymous_()) + elif self.is_cur_keyword_("anchorDef"): + statements.append(self.parse_anchordef_()) + elif self.is_cur_keyword_("languagesystem"): + statements.append(self.parse_languagesystem_()) + elif self.is_cur_keyword_("lookup"): + statements.append(self.parse_lookup_(vertical=False)) + elif self.is_cur_keyword_("markClass"): + statements.append(self.parse_markClass_()) + elif self.is_cur_keyword_("feature"): + statements.append(self.parse_feature_block_()) + elif self.is_cur_keyword_("conditionset"): + statements.append(self.parse_conditionset_()) + elif self.is_cur_keyword_("variation"): + statements.append(self.parse_feature_block_(variation=True)) + elif self.is_cur_keyword_("table"): + statements.append(self.parse_table_()) + elif self.is_cur_keyword_("valueRecordDef"): + statements.append(self.parse_valuerecord_definition_(vertical=False)) + elif ( + self.cur_token_type_ is Lexer.NAME + and self.cur_token_ in self.extensions + ): + statements.append(self.extensions[self.cur_token_](self)) + elif self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == ";": + continue + else: + raise FeatureLibError( + "Expected feature, languagesystem, lookup, markClass, " + 'table, or glyph class definition, got {} "{}"'.format( + self.cur_token_type_, self.cur_token_ + ), + self.cur_token_location_, + ) + # Report any missing glyphs at the end of parsing + if self.missing: + error = [ + " %s (first found at %s)" % (name, loc) + for name, loc in self.missing.items() + ] + raise FeatureLibError( + "The following glyph names are referenced but are missing from the " + "glyph set:\n" + ("\n".join(error)), + None, + ) + return self.doc_ + + def parse_anchor_(self): + # Parses an anchor in any of the four formats given in the feature + # file specification (2.e.vii). + self.expect_symbol_("<") + self.expect_keyword_("anchor") + location = self.cur_token_location_ + + if self.next_token_ == "NULL": # Format D + self.expect_keyword_("NULL") + self.expect_symbol_(">") + return None + + if self.next_token_type_ == Lexer.NAME: # Format E + name = self.expect_name_() + anchordef = self.anchors_.resolve(name) + if anchordef is None: + raise FeatureLibError( + 'Unknown anchor "%s"' % name, self.cur_token_location_ + ) + self.expect_symbol_(">") + return self.ast.Anchor( + anchordef.x, + anchordef.y, + name=name, + contourpoint=anchordef.contourpoint, + xDeviceTable=None, + yDeviceTable=None, + location=location, + ) + + x, y = self.expect_number_(variable=True), self.expect_number_(variable=True) + + contourpoint = None + if self.next_token_ == "contourpoint": # Format B + self.expect_keyword_("contourpoint") + contourpoint = self.expect_number_() + + if self.next_token_ == "<": # Format C + xDeviceTable = self.parse_device_() + yDeviceTable = self.parse_device_() + else: + xDeviceTable, yDeviceTable = None, None + + self.expect_symbol_(">") + return self.ast.Anchor( + x, + y, + name=None, + contourpoint=contourpoint, + xDeviceTable=xDeviceTable, + yDeviceTable=yDeviceTable, + location=location, + ) + + def parse_anchor_marks_(self): + # Parses a sequence of ``[ mark @MARKCLASS]*.`` + anchorMarks = [] # [(self.ast.Anchor, markClassName)*] + while self.next_token_ == "<": + anchor = self.parse_anchor_() + if anchor is None and self.next_token_ != "mark": + continue # without mark, eg. in GPOS type 5 + self.expect_keyword_("mark") + markClass = self.expect_markClass_reference_() + anchorMarks.append((anchor, markClass)) + return anchorMarks + + def parse_anchordef_(self): + # Parses a named anchor definition (`section 2.e.viii `_). + assert self.is_cur_keyword_("anchorDef") + location = self.cur_token_location_ + x, y = self.expect_number_(), self.expect_number_() + contourpoint = None + if self.next_token_ == "contourpoint": + self.expect_keyword_("contourpoint") + contourpoint = self.expect_number_() + name = self.expect_name_() + self.expect_symbol_(";") + anchordef = self.ast.AnchorDefinition( + name, x, y, contourpoint=contourpoint, location=location + ) + self.anchors_.define(name, anchordef) + return anchordef + + def parse_anonymous_(self): + # Parses an anonymous data block (`section 10 `_). + assert self.is_cur_keyword_(("anon", "anonymous")) + tag = self.expect_tag_() + _, content, location = self.lexer_.scan_anonymous_block(tag) + self.advance_lexer_() + self.expect_symbol_("}") + end_tag = self.expect_tag_() + assert tag == end_tag, "bad splitting in Lexer.scan_anonymous_block()" + self.expect_symbol_(";") + return self.ast.AnonymousBlock(tag, content, location=location) + + def parse_attach_(self): + # Parses a GDEF Attach statement (`section 9.b `_) + assert self.is_cur_keyword_("Attach") + location = self.cur_token_location_ + glyphs = self.parse_glyphclass_(accept_glyphname=True) + contourPoints = {self.expect_number_()} + while self.next_token_ != ";": + contourPoints.add(self.expect_number_()) + self.expect_symbol_(";") + return self.ast.AttachStatement(glyphs, contourPoints, location=location) + + def parse_enumerate_(self, vertical): + # Parse an enumerated pair positioning rule (`section 6.b.ii `_). + assert self.cur_token_ in {"enumerate", "enum"} + self.advance_lexer_() + return self.parse_position_(enumerated=True, vertical=vertical) + + def parse_GlyphClassDef_(self): + # Parses 'GlyphClassDef @BASE, @LIGATURES, @MARKS, @COMPONENTS;' + assert self.is_cur_keyword_("GlyphClassDef") + location = self.cur_token_location_ + if self.next_token_ != ",": + baseGlyphs = self.parse_glyphclass_(accept_glyphname=False) + else: + baseGlyphs = None + self.expect_symbol_(",") + if self.next_token_ != ",": + ligatureGlyphs = self.parse_glyphclass_(accept_glyphname=False) + else: + ligatureGlyphs = None + self.expect_symbol_(",") + if self.next_token_ != ",": + markGlyphs = self.parse_glyphclass_(accept_glyphname=False) + else: + markGlyphs = None + self.expect_symbol_(",") + if self.next_token_ != ";": + componentGlyphs = self.parse_glyphclass_(accept_glyphname=False) + else: + componentGlyphs = None + self.expect_symbol_(";") + return self.ast.GlyphClassDefStatement( + baseGlyphs, markGlyphs, ligatureGlyphs, componentGlyphs, location=location + ) + + def parse_glyphclass_definition_(self): + # Parses glyph class definitions such as '@UPPERCASE = [A-Z];' + location, name = self.cur_token_location_, self.cur_token_ + self.expect_symbol_("=") + glyphs = self.parse_glyphclass_(accept_glyphname=False) + self.expect_symbol_(";") + glyphclass = self.ast.GlyphClassDefinition(name, glyphs, location=location) + self.glyphclasses_.define(name, glyphclass) + return glyphclass + + def split_glyph_range_(self, name, location): + # Since v1.20, the OpenType Feature File specification allows + # for dashes in glyph names. A sequence like "a-b-c-d" could + # therefore mean a single glyph whose name happens to be + # "a-b-c-d", or it could mean a range from glyph "a" to glyph + # "b-c-d", or a range from glyph "a-b" to glyph "c-d", or a + # range from glyph "a-b-c" to glyph "d".Technically, this + # example could be resolved because the (pretty complex) + # definition of glyph ranges renders most of these splits + # invalid. But the specification does not say that a compiler + # should try to apply such fancy heuristics. To encourage + # unambiguous feature files, we therefore try all possible + # splits and reject the feature file if there are multiple + # splits possible. It is intentional that we don't just emit a + # warning; warnings tend to get ignored. To fix the problem, + # font designers can trivially add spaces around the intended + # split point, and we emit a compiler error that suggests + # how exactly the source should be rewritten to make things + # unambiguous. + parts = name.split("-") + solutions = [] + for i in range(len(parts)): + start, limit = "-".join(parts[0:i]), "-".join(parts[i:]) + if start in self.glyphNames_ and limit in self.glyphNames_: + solutions.append((start, limit)) + if len(solutions) == 1: + start, limit = solutions[0] + return start, limit + elif len(solutions) == 0: + raise FeatureLibError( + '"%s" is not a glyph in the font, and it can not be split ' + "into a range of known glyphs" % name, + location, + ) + else: + ranges = " or ".join(['"%s - %s"' % (s, l) for s, l in solutions]) + raise FeatureLibError( + 'Ambiguous glyph range "%s"; ' + "please use %s to clarify what you mean" % (name, ranges), + location, + ) + + def parse_glyphclass_(self, accept_glyphname, accept_null=False): + # Parses a glyph class, either named or anonymous, or (if + # ``bool(accept_glyphname)``) a glyph name. If ``bool(accept_null)`` then + # also accept the special NULL glyph. + if accept_glyphname and self.next_token_type_ in (Lexer.NAME, Lexer.CID): + if accept_null and self.next_token_ == "NULL": + # If you want a glyph called NULL, you should escape it. + self.advance_lexer_() + return self.ast.NullGlyph(location=self.cur_token_location_) + glyph = self.expect_glyph_() + self.check_glyph_name_in_glyph_set(glyph) + return self.ast.GlyphName(glyph, location=self.cur_token_location_) + if self.next_token_type_ is Lexer.GLYPHCLASS: + self.advance_lexer_() + gc = self.glyphclasses_.resolve(self.cur_token_) + if gc is None: + raise FeatureLibError( + "Unknown glyph class @%s" % self.cur_token_, + self.cur_token_location_, + ) + if isinstance(gc, self.ast.MarkClass): + return self.ast.MarkClassName(gc, location=self.cur_token_location_) + else: + return self.ast.GlyphClassName(gc, location=self.cur_token_location_) + + self.expect_symbol_("[") + location = self.cur_token_location_ + glyphs = self.ast.GlyphClass(location=location) + while self.next_token_ != "]": + if self.next_token_type_ is Lexer.NAME: + glyph = self.expect_glyph_() + location = self.cur_token_location_ + if "-" in glyph and self.glyphNames_ and glyph not in self.glyphNames_: + start, limit = self.split_glyph_range_(glyph, location) + self.check_glyph_name_in_glyph_set(start, limit) + glyphs.add_range( + start, limit, self.make_glyph_range_(location, start, limit) + ) + elif self.next_token_ == "-": + start = glyph + self.expect_symbol_("-") + limit = self.expect_glyph_() + self.check_glyph_name_in_glyph_set(start, limit) + glyphs.add_range( + start, limit, self.make_glyph_range_(location, start, limit) + ) + else: + if "-" in glyph and not self.glyphNames_: + log.warning( + str( + FeatureLibError( + f"Ambiguous glyph name that looks like a range: {glyph!r}", + location, + ) + ) + ) + self.check_glyph_name_in_glyph_set(glyph) + glyphs.append(glyph) + elif self.next_token_type_ is Lexer.CID: + glyph = self.expect_glyph_() + if self.next_token_ == "-": + range_location = self.cur_token_location_ + range_start = self.cur_token_ + self.expect_symbol_("-") + range_end = self.expect_cid_() + self.check_glyph_name_in_glyph_set( + f"cid{range_start:05d}", + f"cid{range_end:05d}", + ) + glyphs.add_cid_range( + range_start, + range_end, + self.make_cid_range_(range_location, range_start, range_end), + ) + else: + glyph_name = f"cid{self.cur_token_:05d}" + self.check_glyph_name_in_glyph_set(glyph_name) + glyphs.append(glyph_name) + elif self.next_token_type_ is Lexer.GLYPHCLASS: + self.advance_lexer_() + gc = self.glyphclasses_.resolve(self.cur_token_) + if gc is None: + raise FeatureLibError( + "Unknown glyph class @%s" % self.cur_token_, + self.cur_token_location_, + ) + if isinstance(gc, self.ast.MarkClass): + gc = self.ast.MarkClassName(gc, location=self.cur_token_location_) + else: + gc = self.ast.GlyphClassName(gc, location=self.cur_token_location_) + glyphs.add_class(gc) + else: + raise FeatureLibError( + "Expected glyph name, glyph range, " + f"or glyph class reference, found {self.next_token_!r}", + self.next_token_location_, + ) + self.expect_symbol_("]") + return glyphs + + def parse_glyph_pattern_(self, vertical): + # Parses a glyph pattern, including lookups and context, e.g.:: + # + # a b + # a b c' d e + # a b c' lookup ChangeC d e + prefix, glyphs, lookups, values, suffix = ([], [], [], [], []) + hasMarks = False + while self.next_token_ not in {"by", "from", ";", ","}: + gc = self.parse_glyphclass_(accept_glyphname=True) + marked = False + if self.next_token_ == "'": + self.expect_symbol_("'") + hasMarks = marked = True + if marked: + if suffix: + # makeotf also reports this as an error, while FontForge + # silently inserts ' in all the intervening glyphs. + # https://github.com/fonttools/fonttools/pull/1096 + raise FeatureLibError( + "Unsupported contextual target sequence: at most " + "one run of marked (') glyph/class names allowed", + self.cur_token_location_, + ) + glyphs.append(gc) + elif glyphs: + suffix.append(gc) + else: + prefix.append(gc) + + if self.is_next_value_(): + values.append(self.parse_valuerecord_(vertical)) + else: + values.append(None) + + lookuplist = None + while self.next_token_ == "lookup": + if lookuplist is None: + lookuplist = [] + self.expect_keyword_("lookup") + if not marked: + raise FeatureLibError( + "Lookups can only follow marked glyphs", + self.cur_token_location_, + ) + lookup_name = self.expect_name_() + lookup = self.lookups_.resolve(lookup_name) + if lookup is None: + raise FeatureLibError( + 'Unknown lookup "%s"' % lookup_name, self.cur_token_location_ + ) + lookuplist.append(lookup) + if marked: + lookups.append(lookuplist) + + if not glyphs and not suffix: # eg., "sub f f i by" + assert lookups == [] + return ([], prefix, [None] * len(prefix), values, [], hasMarks) + else: + if any(values[: len(prefix)]): + raise FeatureLibError( + "Positioning cannot be applied in the bactrack glyph sequence, " + "before the marked glyph sequence.", + self.cur_token_location_, + ) + marked_values = values[len(prefix) : len(prefix) + len(glyphs)] + if any(marked_values): + if any(values[len(prefix) + len(glyphs) :]): + raise FeatureLibError( + "Positioning values are allowed only in the marked glyph " + "sequence, or after the final glyph node when only one glyph " + "node is marked.", + self.cur_token_location_, + ) + values = marked_values + elif values and values[-1]: + if len(glyphs) > 1 or any(values[:-1]): + raise FeatureLibError( + "Positioning values are allowed only in the marked glyph " + "sequence, or after the final glyph node when only one glyph " + "node is marked.", + self.cur_token_location_, + ) + values = values[-1:] + elif any(values): + raise FeatureLibError( + "Positioning values are allowed only in the marked glyph " + "sequence, or after the final glyph node when only one glyph " + "node is marked.", + self.cur_token_location_, + ) + return (prefix, glyphs, lookups, values, suffix, hasMarks) + + def parse_ignore_glyph_pattern_(self, sub): + location = self.cur_token_location_ + prefix, glyphs, lookups, values, suffix, hasMarks = self.parse_glyph_pattern_( + vertical=False + ) + if any(lookups): + raise FeatureLibError( + f'No lookups can be specified for "ignore {sub}"', location + ) + if not hasMarks: + error = FeatureLibError( + f'Ambiguous "ignore {sub}", there should be least one marked glyph', + location, + ) + log.warning(str(error)) + suffix, glyphs = glyphs[1:], glyphs[0:1] + chainContext = (prefix, glyphs, suffix) + return chainContext + + def parse_ignore_context_(self, sub): + location = self.cur_token_location_ + chainContext = [self.parse_ignore_glyph_pattern_(sub)] + while self.next_token_ == ",": + self.expect_symbol_(",") + chainContext.append(self.parse_ignore_glyph_pattern_(sub)) + self.expect_symbol_(";") + return chainContext + + def parse_ignore_(self): + # Parses an ignore sub/pos rule. + assert self.is_cur_keyword_("ignore") + location = self.cur_token_location_ + self.advance_lexer_() + if self.cur_token_ in ["substitute", "sub"]: + chainContext = self.parse_ignore_context_("sub") + return self.ast.IgnoreSubstStatement(chainContext, location=location) + if self.cur_token_ in ["position", "pos"]: + chainContext = self.parse_ignore_context_("pos") + return self.ast.IgnorePosStatement(chainContext, location=location) + raise FeatureLibError( + 'Expected "substitute" or "position"', self.cur_token_location_ + ) + + def parse_include_(self): + assert self.cur_token_ == "include" + location = self.cur_token_location_ + filename = self.expect_filename_() + # self.expect_symbol_(";") + return ast.IncludeStatement(filename, location=location) + + def parse_language_(self): + assert self.is_cur_keyword_("language") + location = self.cur_token_location_ + language = self.expect_language_tag_() + include_default, required = (True, False) + if self.next_token_ in {"exclude_dflt", "include_dflt"}: + include_default = self.expect_name_() == "include_dflt" + if self.next_token_ == "required": + self.expect_keyword_("required") + required = True + self.expect_symbol_(";") + return self.ast.LanguageStatement( + language, include_default, required, location=location + ) + + def parse_ligatureCaretByIndex_(self): + assert self.is_cur_keyword_("LigatureCaretByIndex") + location = self.cur_token_location_ + glyphs = self.parse_glyphclass_(accept_glyphname=True) + carets = [self.expect_number_()] + while self.next_token_ != ";": + carets.append(self.expect_number_()) + self.expect_symbol_(";") + return self.ast.LigatureCaretByIndexStatement(glyphs, carets, location=location) + + def parse_ligatureCaretByPos_(self): + assert self.is_cur_keyword_("LigatureCaretByPos") + location = self.cur_token_location_ + glyphs = self.parse_glyphclass_(accept_glyphname=True) + carets = [self.expect_number_(variable=True)] + while self.next_token_ != ";": + carets.append(self.expect_number_(variable=True)) + self.expect_symbol_(";") + return self.ast.LigatureCaretByPosStatement(glyphs, carets, location=location) + + def parse_lookup_(self, vertical): + # Parses a ``lookup`` - either a lookup block, or a lookup reference + # inside a feature. + assert self.is_cur_keyword_("lookup") + location, name = self.cur_token_location_, self.expect_name_() + + if self.next_token_ == ";": + lookup = self.lookups_.resolve(name) + if lookup is None: + raise FeatureLibError( + 'Unknown lookup "%s"' % name, self.cur_token_location_ + ) + self.expect_symbol_(";") + return self.ast.LookupReferenceStatement(lookup, location=location) + + use_extension = False + if self.next_token_ == "useExtension": + self.expect_keyword_("useExtension") + use_extension = True + + block = self.ast.LookupBlock(name, use_extension, location=location) + self.parse_block_(block, vertical) + self.lookups_.define(name, block) + return block + + def parse_lookupflag_(self): + # Parses a ``lookupflag`` statement, either specified by number or + # in words. + assert self.is_cur_keyword_("lookupflag") + location = self.cur_token_location_ + + # format B: "lookupflag 6;" + if self.next_token_type_ == Lexer.NUMBER: + value = self.expect_number_() + self.expect_symbol_(";") + return self.ast.LookupFlagStatement(value, location=location) + + # format A: "lookupflag RightToLeft MarkAttachmentType @M;" + value_seen = False + value, markAttachment, markFilteringSet = 0, None, None + flags = { + "RightToLeft": 1, + "IgnoreBaseGlyphs": 2, + "IgnoreLigatures": 4, + "IgnoreMarks": 8, + } + seen = set() + while self.next_token_ != ";": + if self.next_token_ in seen: + raise FeatureLibError( + "%s can be specified only once" % self.next_token_, + self.next_token_location_, + ) + seen.add(self.next_token_) + if self.next_token_ == "MarkAttachmentType": + self.expect_keyword_("MarkAttachmentType") + markAttachment = self.parse_glyphclass_(accept_glyphname=False) + elif self.next_token_ == "UseMarkFilteringSet": + self.expect_keyword_("UseMarkFilteringSet") + markFilteringSet = self.parse_glyphclass_(accept_glyphname=False) + elif self.next_token_ in flags: + value_seen = True + value = value | flags[self.expect_name_()] + else: + raise FeatureLibError( + '"%s" is not a recognized lookupflag' % self.next_token_, + self.next_token_location_, + ) + self.expect_symbol_(";") + + if not any([value_seen, markAttachment, markFilteringSet]): + raise FeatureLibError( + "lookupflag must have a value", self.next_token_location_ + ) + + return self.ast.LookupFlagStatement( + value, + markAttachment=markAttachment, + markFilteringSet=markFilteringSet, + location=location, + ) + + def parse_markClass_(self): + assert self.is_cur_keyword_("markClass") + location = self.cur_token_location_ + glyphs = self.parse_glyphclass_(accept_glyphname=True) + if not glyphs.glyphSet(): + raise FeatureLibError( + "Empty glyph class in mark class definition", location + ) + anchor = self.parse_anchor_() + name = self.expect_class_name_() + self.expect_symbol_(";") + markClass = self.doc_.markClasses.get(name) + if markClass is None: + markClass = self.ast.MarkClass(name) + self.doc_.markClasses[name] = markClass + self.glyphclasses_.define(name, markClass) + mcdef = self.ast.MarkClassDefinition( + markClass, anchor, glyphs, location=location + ) + markClass.addDefinition(mcdef) + return mcdef + + def parse_position_(self, enumerated, vertical): + assert self.cur_token_ in {"position", "pos"} + if self.next_token_ == "cursive": # GPOS type 3 + return self.parse_position_cursive_(enumerated, vertical) + elif self.next_token_ == "base": # GPOS type 4 + return self.parse_position_base_(enumerated, vertical) + elif self.next_token_ == "ligature": # GPOS type 5 + return self.parse_position_ligature_(enumerated, vertical) + elif self.next_token_ == "mark": # GPOS type 6 + return self.parse_position_mark_(enumerated, vertical) + + location = self.cur_token_location_ + prefix, glyphs, lookups, values, suffix, hasMarks = self.parse_glyph_pattern_( + vertical + ) + self.expect_symbol_(";") + + if any(lookups): + # GPOS type 8: Chaining contextual positioning; explicit lookups + if any(values): + raise FeatureLibError( + 'If "lookup" is present, no values must be specified', location + ) + return self.ast.ChainContextPosStatement( + prefix, glyphs, suffix, lookups, location=location + ) + + # Pair positioning, format A: "pos V 10 A -10;" + # Pair positioning, format B: "pos V A -20;" + if not prefix and not suffix and len(glyphs) == 2 and not hasMarks: + if values[0] is None: # Format B: "pos V A -20;" + values.reverse() + return self.ast.PairPosStatement( + glyphs[0], + values[0], + glyphs[1], + values[1], + enumerated=enumerated, + location=location, + ) + + if enumerated: + raise FeatureLibError( + '"enumerate" is only allowed with pair positionings', location + ) + return self.ast.SinglePosStatement( + list(zip(glyphs, values)), + prefix, + suffix, + forceChain=hasMarks, + location=location, + ) + + def parse_position_cursive_(self, enumerated, vertical): + location = self.cur_token_location_ + self.expect_keyword_("cursive") + if enumerated: + raise FeatureLibError( + '"enumerate" is not allowed with ' "cursive attachment positioning", + location, + ) + glyphclass = self.parse_glyphclass_(accept_glyphname=True) + entryAnchor = self.parse_anchor_() + exitAnchor = self.parse_anchor_() + self.expect_symbol_(";") + return self.ast.CursivePosStatement( + glyphclass, entryAnchor, exitAnchor, location=location + ) + + def parse_position_base_(self, enumerated, vertical): + location = self.cur_token_location_ + self.expect_keyword_("base") + if enumerated: + raise FeatureLibError( + '"enumerate" is not allowed with ' + "mark-to-base attachment positioning", + location, + ) + base = self.parse_glyphclass_(accept_glyphname=True) + marks = self.parse_anchor_marks_() + self.expect_symbol_(";") + return self.ast.MarkBasePosStatement(base, marks, location=location) + + def parse_position_ligature_(self, enumerated, vertical): + location = self.cur_token_location_ + self.expect_keyword_("ligature") + if enumerated: + raise FeatureLibError( + '"enumerate" is not allowed with ' + "mark-to-ligature attachment positioning", + location, + ) + ligatures = self.parse_glyphclass_(accept_glyphname=True) + marks = [self.parse_anchor_marks_()] + while self.next_token_ == "ligComponent": + self.expect_keyword_("ligComponent") + marks.append(self.parse_anchor_marks_()) + self.expect_symbol_(";") + return self.ast.MarkLigPosStatement(ligatures, marks, location=location) + + def parse_position_mark_(self, enumerated, vertical): + location = self.cur_token_location_ + self.expect_keyword_("mark") + if enumerated: + raise FeatureLibError( + '"enumerate" is not allowed with ' + "mark-to-mark attachment positioning", + location, + ) + baseMarks = self.parse_glyphclass_(accept_glyphname=True) + marks = self.parse_anchor_marks_() + self.expect_symbol_(";") + return self.ast.MarkMarkPosStatement(baseMarks, marks, location=location) + + def parse_script_(self): + assert self.is_cur_keyword_("script") + location, script = self.cur_token_location_, self.expect_script_tag_() + self.expect_symbol_(";") + return self.ast.ScriptStatement(script, location=location) + + def parse_substitute_(self): + assert self.cur_token_ in {"substitute", "sub", "reversesub", "rsub"} + location = self.cur_token_location_ + reverse = self.cur_token_ in {"reversesub", "rsub"} + ( + old_prefix, + old, + lookups, + values, + old_suffix, + hasMarks, + ) = self.parse_glyph_pattern_(vertical=False) + if any(values): + raise FeatureLibError( + "Substitution statements cannot contain values", location + ) + new = [] + if self.next_token_ == "by": + keyword = self.expect_keyword_("by") + while self.next_token_ != ";": + gc = self.parse_glyphclass_(accept_glyphname=True, accept_null=True) + new.append(gc) + elif self.next_token_ == "from": + keyword = self.expect_keyword_("from") + new = [self.parse_glyphclass_(accept_glyphname=False)] + else: + keyword = None + self.expect_symbol_(";") + if len(new) == 0 and not any(lookups): + raise FeatureLibError( + 'Expected "by", "from" or explicit lookup references', + self.cur_token_location_, + ) + + # GSUB lookup type 3: Alternate substitution. + # Format: "substitute a from [a.1 a.2 a.3];" + if keyword == "from": + if reverse: + raise FeatureLibError( + 'Reverse chaining substitutions do not support "from"', location + ) + if len(old) != 1 or len(old[0].glyphSet()) != 1: + raise FeatureLibError('Expected a single glyph before "from"', location) + if len(new) != 1: + raise FeatureLibError( + 'Expected a single glyphclass after "from"', location + ) + return self.ast.AlternateSubstStatement( + old_prefix, old[0], old_suffix, new[0], location=location + ) + + num_lookups = len([l for l in lookups if l is not None]) + + is_deletion = False + if len(new) == 1 and isinstance(new[0], ast.NullGlyph): + if reverse: + raise FeatureLibError( + "Reverse chaining substitutions do not support glyph deletion", + location, + ) + new = [] # Deletion + is_deletion = True + + # GSUB lookup type 1: Single substitution. + # Format A: "substitute a by a.sc;" + # Format B: "substitute [one.fitted one.oldstyle] by one;" + # Format C: "substitute [a-d] by [A.sc-D.sc];" + if not reverse and len(old) == 1 and len(new) == 1 and num_lookups == 0: + glyphs = list(old[0].glyphSet()) + replacements = list(new[0].glyphSet()) + if len(replacements) == 1: + replacements = replacements * len(glyphs) + if len(glyphs) != len(replacements): + raise FeatureLibError( + 'Expected a glyph class with %d elements after "by", ' + "but found a glyph class with %d elements" + % (len(glyphs), len(replacements)), + location, + ) + return self.ast.SingleSubstStatement( + old, new, old_prefix, old_suffix, forceChain=hasMarks, location=location + ) + + # Glyph deletion, built as GSUB lookup type 2: Multiple substitution + # with empty replacement. + if is_deletion and len(old) == 1 and num_lookups == 0: + return self.ast.MultipleSubstStatement( + old_prefix, + old[0], + old_suffix, + (), + forceChain=hasMarks, + location=location, + ) + + # GSUB lookup type 2: Multiple substitution. + # Format: "substitute f_f_i by f f i;" + # + # GlyphsApp introduces two additional formats: + # Format 1: "substitute [f_i f_l] by [f f] [i l];" + # Format 2: "substitute [f_i f_l] by f [i l];" + # http://handbook.glyphsapp.com/en/layout/multiple-substitution-with-classes/ + if not reverse and len(old) == 1 and len(new) > 1 and num_lookups == 0: + count = len(old[0].glyphSet()) + for n in new: + if not list(n.glyphSet()): + raise FeatureLibError("Empty class in replacement", location) + if len(n.glyphSet()) != 1 and len(n.glyphSet()) != count: + raise FeatureLibError( + f'Expected a glyph class with 1 or {count} elements after "by", ' + f"but found a glyph class with {len(n.glyphSet())} elements", + location, + ) + return self.ast.MultipleSubstStatement( + old_prefix, + old[0], + old_suffix, + new, + forceChain=hasMarks, + location=location, + ) + + # GSUB lookup type 4: Ligature substitution. + # Format: "substitute f f i by f_f_i;" + if ( + not reverse + and len(old) > 1 + and len(new) == 1 + and len(new[0].glyphSet()) == 1 + and num_lookups == 0 + ): + return self.ast.LigatureSubstStatement( + old_prefix, + old, + old_suffix, + list(new[0].glyphSet())[0], + forceChain=hasMarks, + location=location, + ) + + # GSUB lookup type 8: Reverse chaining substitution. + if reverse: + if len(old) != 1: + raise FeatureLibError( + "In reverse chaining single substitutions, " + "only a single glyph or glyph class can be replaced", + location, + ) + if len(new) != 1: + raise FeatureLibError( + "In reverse chaining single substitutions, " + 'the replacement (after "by") must be a single glyph ' + "or glyph class", + location, + ) + if num_lookups != 0: + raise FeatureLibError( + "Reverse chaining substitutions cannot call named lookups", location + ) + glyphs = sorted(list(old[0].glyphSet())) + replacements = sorted(list(new[0].glyphSet())) + if len(replacements) == 1: + replacements = replacements * len(glyphs) + if len(glyphs) != len(replacements): + raise FeatureLibError( + 'Expected a glyph class with %d elements after "by", ' + "but found a glyph class with %d elements" + % (len(glyphs), len(replacements)), + location, + ) + return self.ast.ReverseChainSingleSubstStatement( + old_prefix, old_suffix, old, new, location=location + ) + + if len(old) > 1 and len(new) > 1: + raise FeatureLibError( + "Direct substitution of multiple glyphs by multiple glyphs " + "is not supported", + location, + ) + + # If there are remaining glyphs to parse, this is an invalid GSUB statement + if len(new) != 0 or is_deletion: + raise FeatureLibError("Invalid substitution statement", location) + + # GSUB lookup type 6: Chaining contextual substitution. + rule = self.ast.ChainContextSubstStatement( + old_prefix, old, old_suffix, lookups, location=location + ) + return rule + + def parse_subtable_(self): + assert self.is_cur_keyword_("subtable") + location = self.cur_token_location_ + self.expect_symbol_(";") + return self.ast.SubtableStatement(location=location) + + def parse_size_parameters_(self): + # Parses a ``parameters`` statement used in ``size`` features. See + # `section 8.b `_. + assert self.is_cur_keyword_("parameters") + location = self.cur_token_location_ + DesignSize = self.expect_decipoint_() + SubfamilyID = self.expect_number_() + RangeStart = 0.0 + RangeEnd = 0.0 + if self.next_token_type_ in (Lexer.NUMBER, Lexer.FLOAT) or SubfamilyID != 0: + RangeStart = self.expect_decipoint_() + RangeEnd = self.expect_decipoint_() + + self.expect_symbol_(";") + return self.ast.SizeParameters( + DesignSize, SubfamilyID, RangeStart, RangeEnd, location=location + ) + + def parse_size_menuname_(self): + assert self.is_cur_keyword_("sizemenuname") + location = self.cur_token_location_ + platformID, platEncID, langID, string = self.parse_name_() + return self.ast.FeatureNameStatement( + "size", platformID, platEncID, langID, string, location=location + ) + + def parse_table_(self): + assert self.is_cur_keyword_("table") + location, name = self.cur_token_location_, self.expect_tag_() + table = self.ast.TableBlock(name, location=location) + self.expect_symbol_("{") + handler = { + "GDEF": self.parse_table_GDEF_, + "head": self.parse_table_head_, + "hhea": self.parse_table_hhea_, + "vhea": self.parse_table_vhea_, + "name": self.parse_table_name_, + "BASE": self.parse_table_BASE_, + "OS/2": self.parse_table_OS_2_, + "STAT": self.parse_table_STAT_, + }.get(name) + if handler: + handler(table) + else: + raise FeatureLibError( + '"table %s" is not supported' % name.strip(), location + ) + self.expect_symbol_("}") + end_tag = self.expect_tag_() + if end_tag != name: + raise FeatureLibError( + 'Expected "%s"' % name.strip(), self.cur_token_location_ + ) + self.expect_symbol_(";") + return table + + def parse_table_GDEF_(self, table): + statements = table.statements + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.is_cur_keyword_("Attach"): + statements.append(self.parse_attach_()) + elif self.is_cur_keyword_("GlyphClassDef"): + statements.append(self.parse_GlyphClassDef_()) + elif self.is_cur_keyword_("LigatureCaretByIndex"): + statements.append(self.parse_ligatureCaretByIndex_()) + elif self.is_cur_keyword_("LigatureCaretByPos"): + statements.append(self.parse_ligatureCaretByPos_()) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError( + "Expected Attach, LigatureCaretByIndex, " "or LigatureCaretByPos", + self.cur_token_location_, + ) + + def parse_table_head_(self, table): + statements = table.statements + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.is_cur_keyword_("FontRevision"): + statements.append(self.parse_FontRevision_()) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError("Expected FontRevision", self.cur_token_location_) + + def parse_table_hhea_(self, table): + statements = table.statements + fields = ("CaretOffset", "Ascender", "Descender", "LineGap") + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.cur_token_type_ is Lexer.NAME and self.cur_token_ in fields: + key = self.cur_token_.lower() + value = self.expect_number_() + statements.append( + self.ast.HheaField(key, value, location=self.cur_token_location_) + ) + if self.next_token_ != ";": + raise FeatureLibError( + "Incomplete statement", self.next_token_location_ + ) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError( + "Expected CaretOffset, Ascender, " "Descender or LineGap", + self.cur_token_location_, + ) + + def parse_table_vhea_(self, table): + statements = table.statements + fields = ("VertTypoAscender", "VertTypoDescender", "VertTypoLineGap") + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.cur_token_type_ is Lexer.NAME and self.cur_token_ in fields: + key = self.cur_token_.lower() + value = self.expect_number_() + statements.append( + self.ast.VheaField(key, value, location=self.cur_token_location_) + ) + if self.next_token_ != ";": + raise FeatureLibError( + "Incomplete statement", self.next_token_location_ + ) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError( + "Expected VertTypoAscender, " + "VertTypoDescender or VertTypoLineGap", + self.cur_token_location_, + ) + + def parse_table_name_(self, table): + statements = table.statements + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.is_cur_keyword_("nameid"): + statement = self.parse_nameid_() + if statement: + statements.append(statement) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError("Expected nameid", self.cur_token_location_) + + def parse_name_(self): + """Parses a name record. See `section 9.e `_.""" + platEncID = None + langID = None + if self.next_token_type_ in Lexer.NUMBERS: + platformID = self.expect_any_number_() + location = self.cur_token_location_ + if platformID not in (1, 3): + raise FeatureLibError("Expected platform id 1 or 3", location) + if self.next_token_type_ in Lexer.NUMBERS: + platEncID = self.expect_any_number_() + langID = self.expect_any_number_() + else: + platformID = 3 + location = self.cur_token_location_ + + if platformID == 1: # Macintosh + platEncID = platEncID or 0 # Roman + langID = langID or 0 # English + else: # 3, Windows + platEncID = platEncID or 1 # Unicode + langID = langID or 0x0409 # English + + string = self.expect_string_() + self.expect_symbol_(";") + + encoding = getEncoding(platformID, platEncID, langID) + if encoding is None: + raise FeatureLibError("Unsupported encoding", location) + unescaped = self.unescape_string_(string, encoding) + return platformID, platEncID, langID, unescaped + + def parse_stat_name_(self): + platEncID = None + langID = None + if self.next_token_type_ in Lexer.NUMBERS: + platformID = self.expect_any_number_() + location = self.cur_token_location_ + if platformID not in (1, 3): + raise FeatureLibError("Expected platform id 1 or 3", location) + if self.next_token_type_ in Lexer.NUMBERS: + platEncID = self.expect_any_number_() + langID = self.expect_any_number_() + else: + platformID = 3 + location = self.cur_token_location_ + + if platformID == 1: # Macintosh + platEncID = platEncID or 0 # Roman + langID = langID or 0 # English + else: # 3, Windows + platEncID = platEncID or 1 # Unicode + langID = langID or 0x0409 # English + + string = self.expect_string_() + encoding = getEncoding(platformID, platEncID, langID) + if encoding is None: + raise FeatureLibError("Unsupported encoding", location) + unescaped = self.unescape_string_(string, encoding) + return platformID, platEncID, langID, unescaped + + def parse_nameid_(self): + assert self.cur_token_ == "nameid", self.cur_token_ + location, nameID = self.cur_token_location_, self.expect_any_number_() + if nameID > 32767: + raise FeatureLibError( + "Name id value cannot be greater than 32767", self.cur_token_location_ + ) + platformID, platEncID, langID, string = self.parse_name_() + return self.ast.NameRecord( + nameID, platformID, platEncID, langID, string, location=location + ) + + def unescape_string_(self, string, encoding): + if encoding == "utf_16_be": + s = re.sub(r"\\[0-9a-fA-F]{4}", self.unescape_unichr_, string) + else: + unescape = lambda m: self.unescape_byte_(m, encoding) + s = re.sub(r"\\[0-9a-fA-F]{2}", unescape, string) + # We now have a Unicode string, but it might contain surrogate pairs. + # We convert surrogates to actual Unicode by round-tripping through + # Python's UTF-16 codec in a special mode. + utf16 = tobytes(s, "utf_16_be", "surrogatepass") + return tostr(utf16, "utf_16_be") + + @staticmethod + def unescape_unichr_(match): + n = match.group(0)[1:] + return chr(int(n, 16)) + + @staticmethod + def unescape_byte_(match, encoding): + n = match.group(0)[1:] + return bytechr(int(n, 16)).decode(encoding) + + def find_previous(self, statements, class_): + for previous in reversed(statements): + if isinstance(previous, self.ast.Comment): + continue + elif isinstance(previous, class_): + return previous + else: + # If we find something that doesn't match what we're looking + # for, and isn't a comment, fail + return None + # Out of statements to look at + return None + + def parse_table_BASE_(self, table): + statements = table.statements + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.is_cur_keyword_("HorizAxis.BaseTagList"): + horiz_bases = self.parse_base_tag_list_() + elif self.is_cur_keyword_("HorizAxis.BaseScriptList"): + horiz_scripts = self.parse_base_script_list_(len(horiz_bases)) + statements.append( + self.ast.BaseAxis( + horiz_bases, + horiz_scripts, + False, + location=self.cur_token_location_, + ) + ) + elif self.is_cur_keyword_("HorizAxis.MinMax"): + base_script_list = self.find_previous(statements, ast.BaseAxis) + if base_script_list is None: + raise FeatureLibError( + "MinMax must be preceded by BaseScriptList", + self.cur_token_location_, + ) + if base_script_list.vertical: + raise FeatureLibError( + "HorizAxis.MinMax must be preceded by HorizAxis statements", + self.cur_token_location_, + ) + base_script_list.minmax.append(self.parse_base_minmax_()) + elif self.is_cur_keyword_("VertAxis.BaseTagList"): + vert_bases = self.parse_base_tag_list_() + elif self.is_cur_keyword_("VertAxis.BaseScriptList"): + vert_scripts = self.parse_base_script_list_(len(vert_bases)) + statements.append( + self.ast.BaseAxis( + vert_bases, + vert_scripts, + True, + location=self.cur_token_location_, + ) + ) + elif self.is_cur_keyword_("VertAxis.MinMax"): + base_script_list = self.find_previous(statements, ast.BaseAxis) + if base_script_list is None: + raise FeatureLibError( + "MinMax must be preceded by BaseScriptList", + self.cur_token_location_, + ) + if not base_script_list.vertical: + raise FeatureLibError( + "VertAxis.MinMax must be preceded by VertAxis statements", + self.cur_token_location_, + ) + base_script_list.minmax.append(self.parse_base_minmax_()) + elif self.cur_token_ == ";": + continue + + def parse_table_OS_2_(self, table): + statements = table.statements + numbers = ( + "FSType", + "TypoAscender", + "TypoDescender", + "TypoLineGap", + "winAscent", + "winDescent", + "XHeight", + "CapHeight", + "WeightClass", + "WidthClass", + "LowerOpSize", + "UpperOpSize", + ) + ranges = ("UnicodeRange", "CodePageRange") + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.cur_token_type_ is Lexer.NAME: + key = self.cur_token_.lower() + value = None + if self.cur_token_ in numbers: + value = self.expect_number_() + elif self.is_cur_keyword_("Panose"): + value = [] + for i in range(10): + value.append(self.expect_number_()) + elif self.cur_token_ in ranges: + value = [] + while self.next_token_ != ";": + value.append(self.expect_number_()) + elif self.is_cur_keyword_("Vendor"): + value = self.expect_string_() + statements.append( + self.ast.OS2Field(key, value, location=self.cur_token_location_) + ) + elif self.cur_token_ == ";": + continue + + def parse_STAT_ElidedFallbackName(self): + assert self.is_cur_keyword_("ElidedFallbackName") + self.expect_symbol_("{") + names = [] + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_() + if self.is_cur_keyword_("name"): + platformID, platEncID, langID, string = self.parse_stat_name_() + nameRecord = self.ast.STATNameStatement( + "stat", + platformID, + platEncID, + langID, + string, + location=self.cur_token_location_, + ) + names.append(nameRecord) + else: + if self.cur_token_ != ";": + raise FeatureLibError( + f"Unexpected token {self.cur_token_} " f"in ElidedFallbackName", + self.cur_token_location_, + ) + self.expect_symbol_("}") + if not names: + raise FeatureLibError('Expected "name"', self.cur_token_location_) + return names + + def parse_STAT_design_axis(self): + assert self.is_cur_keyword_("DesignAxis") + names = [] + axisTag = self.expect_tag_() + if ( + axisTag not in ("ital", "opsz", "slnt", "wdth", "wght") + and not axisTag.isupper() + ): + log.warning(f"Unregistered axis tag {axisTag} should be uppercase.") + axisOrder = self.expect_number_() + self.expect_symbol_("{") + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_() + if self.cur_token_type_ is Lexer.COMMENT: + continue + elif self.is_cur_keyword_("name"): + location = self.cur_token_location_ + platformID, platEncID, langID, string = self.parse_stat_name_() + name = self.ast.STATNameStatement( + "stat", platformID, platEncID, langID, string, location=location + ) + names.append(name) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError( + f'Expected "name", got {self.cur_token_}', self.cur_token_location_ + ) + + self.expect_symbol_("}") + return self.ast.STATDesignAxisStatement( + axisTag, axisOrder, names, self.cur_token_location_ + ) + + def parse_STAT_axis_value_(self): + assert self.is_cur_keyword_("AxisValue") + self.expect_symbol_("{") + locations = [] + names = [] + flags = 0 + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + continue + elif self.is_cur_keyword_("name"): + location = self.cur_token_location_ + platformID, platEncID, langID, string = self.parse_stat_name_() + name = self.ast.STATNameStatement( + "stat", platformID, platEncID, langID, string, location=location + ) + names.append(name) + elif self.is_cur_keyword_("location"): + location = self.parse_STAT_location() + locations.append(location) + elif self.is_cur_keyword_("flag"): + flags = self.expect_stat_flags() + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError( + f"Unexpected token {self.cur_token_} " f"in AxisValue", + self.cur_token_location_, + ) + self.expect_symbol_("}") + if not names: + raise FeatureLibError('Expected "Axis Name"', self.cur_token_location_) + if not locations: + raise FeatureLibError('Expected "Axis location"', self.cur_token_location_) + if len(locations) > 1: + for location in locations: + if len(location.values) > 1: + raise FeatureLibError( + "Only one value is allowed in a " + "Format 4 Axis Value Record, but " + f"{len(location.values)} were found.", + self.cur_token_location_, + ) + format4_tags = [] + for location in locations: + tag = location.tag + if tag in format4_tags: + raise FeatureLibError( + f"Axis tag {tag} already " "defined.", self.cur_token_location_ + ) + format4_tags.append(tag) + + return self.ast.STATAxisValueStatement( + names, locations, flags, self.cur_token_location_ + ) + + def parse_STAT_location(self): + values = [] + tag = self.expect_tag_() + if len(tag.strip()) != 4: + raise FeatureLibError( + f"Axis tag {self.cur_token_} must be 4 " "characters", + self.cur_token_location_, + ) + + while self.next_token_ != ";": + if self.next_token_type_ is Lexer.FLOAT: + value = self.expect_float_() + values.append(value) + elif self.next_token_type_ is Lexer.NUMBER: + value = self.expect_number_() + values.append(value) + else: + raise FeatureLibError( + f'Unexpected value "{self.next_token_}". ' + "Expected integer or float.", + self.next_token_location_, + ) + if len(values) == 3: + nominal, min_val, max_val = values + if nominal < min_val or nominal > max_val: + raise FeatureLibError( + f"Default value {nominal} is outside " + f"of specified range " + f"{min_val}-{max_val}.", + self.next_token_location_, + ) + return self.ast.AxisValueLocationStatement(tag, values) + + def parse_table_STAT_(self, table): + statements = table.statements + design_axes = [] + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.cur_token_type_ is Lexer.NAME: + if self.is_cur_keyword_("ElidedFallbackName"): + names = self.parse_STAT_ElidedFallbackName() + statements.append(self.ast.ElidedFallbackName(names)) + elif self.is_cur_keyword_("ElidedFallbackNameID"): + value = self.expect_number_() + statements.append(self.ast.ElidedFallbackNameID(value)) + self.expect_symbol_(";") + elif self.is_cur_keyword_("DesignAxis"): + designAxis = self.parse_STAT_design_axis() + design_axes.append(designAxis.tag) + statements.append(designAxis) + self.expect_symbol_(";") + elif self.is_cur_keyword_("AxisValue"): + axisValueRecord = self.parse_STAT_axis_value_() + for location in axisValueRecord.locations: + if location.tag not in design_axes: + # Tag must be defined in a DesignAxis before it + # can be referenced + raise FeatureLibError( + "DesignAxis not defined for " f"{location.tag}.", + self.cur_token_location_, + ) + statements.append(axisValueRecord) + self.expect_symbol_(";") + else: + raise FeatureLibError( + f"Unexpected token {self.cur_token_}", self.cur_token_location_ + ) + elif self.cur_token_ == ";": + continue + + def parse_base_tag_list_(self): + # Parses BASE table entries. (See `section 9.a `_) + assert self.cur_token_ in ( + "HorizAxis.BaseTagList", + "VertAxis.BaseTagList", + ), self.cur_token_ + bases = [] + while self.next_token_ != ";": + bases.append(self.expect_script_tag_()) + self.expect_symbol_(";") + return bases + + def parse_base_script_list_(self, count): + assert self.cur_token_ in ( + "HorizAxis.BaseScriptList", + "VertAxis.BaseScriptList", + ), self.cur_token_ + scripts = [self.parse_base_script_record_(count)] + while self.next_token_ == ",": + self.expect_symbol_(",") + scripts.append(self.parse_base_script_record_(count)) + self.expect_symbol_(";") + return scripts + + def parse_base_script_record_(self, count): + script_tag = self.expect_script_tag_() + base_tag = self.expect_script_tag_() + coords = [self.expect_number_() for i in range(count)] + return script_tag, base_tag, coords + + def parse_base_minmax_(self): + script_tag = self.expect_script_tag_() + language = self.expect_language_tag_() + min_coord = self.expect_number_() + self.advance_lexer_() + if not (self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == ","): + raise FeatureLibError( + "Expected a comma between min and max coordinates", + self.cur_token_location_, + ) + max_coord = self.expect_number_() + if self.next_token_ == ",": # feature tag... + raise FeatureLibError( + "Feature tags are not yet supported in BASE table", + self.cur_token_location_, + ) + + return script_tag, language, min_coord, max_coord + + def parse_device_(self): + result = None + self.expect_symbol_("<") + self.expect_keyword_("device") + if self.next_token_ == "NULL": + self.expect_keyword_("NULL") + else: + result = [(self.expect_number_(), self.expect_number_())] + while self.next_token_ == ",": + self.expect_symbol_(",") + result.append((self.expect_number_(), self.expect_number_())) + result = tuple(result) # make it hashable + self.expect_symbol_(">") + return result + + def is_next_value_(self): + return ( + self.next_token_type_ is Lexer.NUMBER + or self.next_token_ == "<" + or self.next_token_ == "(" + ) + + def parse_valuerecord_(self, vertical): + if ( + self.next_token_type_ is Lexer.SYMBOL and self.next_token_ == "(" + ) or self.next_token_type_ is Lexer.NUMBER: + number, location = ( + self.expect_number_(variable=True), + self.cur_token_location_, + ) + if vertical: + val = self.ast.ValueRecord( + yAdvance=number, vertical=vertical, location=location + ) + else: + val = self.ast.ValueRecord( + xAdvance=number, vertical=vertical, location=location + ) + return val + self.expect_symbol_("<") + location = self.cur_token_location_ + if self.next_token_type_ is Lexer.NAME: + name = self.expect_name_() + if name == "NULL": + self.expect_symbol_(">") + return self.ast.ValueRecord() + vrd = self.valuerecords_.resolve(name) + if vrd is None: + raise FeatureLibError( + 'Unknown valueRecordDef "%s"' % name, self.cur_token_location_ + ) + value = vrd.value + xPlacement, yPlacement = (value.xPlacement, value.yPlacement) + xAdvance, yAdvance = (value.xAdvance, value.yAdvance) + else: + xPlacement, yPlacement, xAdvance, yAdvance = ( + self.expect_number_(variable=True), + self.expect_number_(variable=True), + self.expect_number_(variable=True), + self.expect_number_(variable=True), + ) + + if self.next_token_ == "<": + xPlaDevice, yPlaDevice, xAdvDevice, yAdvDevice = ( + self.parse_device_(), + self.parse_device_(), + self.parse_device_(), + self.parse_device_(), + ) + allDeltas = sorted( + [ + delta + for size, delta in (xPlaDevice if xPlaDevice else ()) + + (yPlaDevice if yPlaDevice else ()) + + (xAdvDevice if xAdvDevice else ()) + + (yAdvDevice if yAdvDevice else ()) + ] + ) + if allDeltas[0] < -128 or allDeltas[-1] > 127: + raise FeatureLibError( + "Device value out of valid range (-128..127)", + self.cur_token_location_, + ) + else: + xPlaDevice, yPlaDevice, xAdvDevice, yAdvDevice = (None, None, None, None) + + self.expect_symbol_(">") + return self.ast.ValueRecord( + xPlacement, + yPlacement, + xAdvance, + yAdvance, + xPlaDevice, + yPlaDevice, + xAdvDevice, + yAdvDevice, + vertical=vertical, + location=location, + ) + + def parse_valuerecord_definition_(self, vertical): + # Parses a named value record definition. (See section `2.e.v `_) + assert self.is_cur_keyword_("valueRecordDef") + location = self.cur_token_location_ + value = self.parse_valuerecord_(vertical) + name = self.expect_name_() + self.expect_symbol_(";") + vrd = self.ast.ValueRecordDefinition(name, value, location=location) + self.valuerecords_.define(name, vrd) + return vrd + + def parse_languagesystem_(self): + assert self.cur_token_ == "languagesystem" + location = self.cur_token_location_ + script = self.expect_script_tag_() + language = self.expect_language_tag_() + self.expect_symbol_(";") + return self.ast.LanguageSystemStatement(script, language, location=location) + + def parse_feature_block_(self, variation=False): + if variation: + assert self.cur_token_ == "variation" + else: + assert self.cur_token_ == "feature" + location = self.cur_token_location_ + tag = self.expect_tag_() + vertical = tag in {"vkrn", "vpal", "vhal", "valt"} + + stylisticset = None + cv_feature = None + size_feature = False + if tag in self.SS_FEATURE_TAGS: + stylisticset = tag + elif tag in self.CV_FEATURE_TAGS: + cv_feature = tag + elif tag == "size": + size_feature = True + + if variation: + conditionset = self.expect_name_() + + use_extension = False + if self.next_token_ == "useExtension": + self.expect_keyword_("useExtension") + use_extension = True + + if variation: + block = self.ast.VariationBlock( + tag, conditionset, use_extension=use_extension, location=location + ) + else: + block = self.ast.FeatureBlock( + tag, use_extension=use_extension, location=location + ) + self.parse_block_(block, vertical, stylisticset, size_feature, cv_feature) + return block + + def parse_feature_reference_(self): + assert self.cur_token_ == "feature", self.cur_token_ + location = self.cur_token_location_ + featureName = self.expect_tag_() + self.expect_symbol_(";") + return self.ast.FeatureReferenceStatement(featureName, location=location) + + def parse_featureNames_(self, tag): + """Parses a ``featureNames`` statement found in stylistic set features. + See section `8.c `_. + """ + assert self.cur_token_ == "featureNames", self.cur_token_ + block = self.ast.NestedBlock( + tag, self.cur_token_, location=self.cur_token_location_ + ) + self.expect_symbol_("{") + for symtab in self.symbol_tables_: + symtab.enter_scope() + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + block.statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.is_cur_keyword_("name"): + location = self.cur_token_location_ + platformID, platEncID, langID, string = self.parse_name_() + block.statements.append( + self.ast.FeatureNameStatement( + tag, platformID, platEncID, langID, string, location=location + ) + ) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError('Expected "name"', self.cur_token_location_) + self.expect_symbol_("}") + for symtab in self.symbol_tables_: + symtab.exit_scope() + self.expect_symbol_(";") + return block + + def parse_cvParameters_(self, tag): + # Parses a ``cvParameters`` block found in Character Variant features. + # See section `8.d `_. + assert self.cur_token_ == "cvParameters", self.cur_token_ + block = self.ast.NestedBlock( + tag, self.cur_token_, location=self.cur_token_location_ + ) + self.expect_symbol_("{") + for symtab in self.symbol_tables_: + symtab.enter_scope() + + statements = block.statements + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.is_cur_keyword_( + { + "FeatUILabelNameID", + "FeatUITooltipTextNameID", + "SampleTextNameID", + "ParamUILabelNameID", + } + ): + statements.append(self.parse_cvNameIDs_(tag, self.cur_token_)) + elif self.is_cur_keyword_("Character"): + statements.append(self.parse_cvCharacter_(tag)) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError( + "Expected statement: got {} {}".format( + self.cur_token_type_, self.cur_token_ + ), + self.cur_token_location_, + ) + + self.expect_symbol_("}") + for symtab in self.symbol_tables_: + symtab.exit_scope() + self.expect_symbol_(";") + return block + + def parse_cvNameIDs_(self, tag, block_name): + assert self.cur_token_ == block_name, self.cur_token_ + block = self.ast.NestedBlock(tag, block_name, location=self.cur_token_location_) + self.expect_symbol_("{") + for symtab in self.symbol_tables_: + symtab.enter_scope() + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + block.statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.is_cur_keyword_("name"): + location = self.cur_token_location_ + platformID, platEncID, langID, string = self.parse_name_() + block.statements.append( + self.ast.CVParametersNameStatement( + tag, + platformID, + platEncID, + langID, + string, + block_name, + location=location, + ) + ) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError('Expected "name"', self.cur_token_location_) + self.expect_symbol_("}") + for symtab in self.symbol_tables_: + symtab.exit_scope() + self.expect_symbol_(";") + return block + + def parse_cvCharacter_(self, tag): + assert self.cur_token_ == "Character", self.cur_token_ + location, character = self.cur_token_location_, self.expect_any_number_() + self.expect_symbol_(";") + if not (0xFFFFFF >= character >= 0): + raise FeatureLibError( + "Character value must be between " + "{:#x} and {:#x}".format(0, 0xFFFFFF), + location, + ) + return self.ast.CharacterStatement(character, tag, location=location) + + def parse_FontRevision_(self): + # Parses a ``FontRevision`` statement found in the head table. See + # `section 9.c `_. + assert self.cur_token_ == "FontRevision", self.cur_token_ + location, version = self.cur_token_location_, self.expect_float_() + self.expect_symbol_(";") + if version <= 0: + raise FeatureLibError("Font revision numbers must be positive", location) + return self.ast.FontRevisionStatement(version, location=location) + + def parse_conditionset_(self): + name = self.expect_name_() + + conditions = {} + self.expect_symbol_("{") + + while self.next_token_ != "}": + self.advance_lexer_() + if self.cur_token_type_ is not Lexer.NAME: + raise FeatureLibError("Expected an axis name", self.cur_token_location_) + + axis = self.cur_token_ + if axis in conditions: + raise FeatureLibError( + f"Repeated condition for axis {axis}", self.cur_token_location_ + ) + + if self.next_token_type_ is Lexer.FLOAT: + min_value = self.expect_float_() + elif self.next_token_type_ is Lexer.NUMBER: + min_value = self.expect_number_(variable=False) + + if self.next_token_type_ is Lexer.FLOAT: + max_value = self.expect_float_() + elif self.next_token_type_ is Lexer.NUMBER: + max_value = self.expect_number_(variable=False) + self.expect_symbol_(";") + + conditions[axis] = (min_value, max_value) + + self.expect_symbol_("}") + + finalname = self.expect_name_() + if finalname != name: + raise FeatureLibError('Expected "%s"' % name, self.cur_token_location_) + return self.ast.ConditionsetStatement(name, conditions) + + def parse_block_( + self, block, vertical, stylisticset=None, size_feature=False, cv_feature=None + ): + self.expect_symbol_("{") + for symtab in self.symbol_tables_: + symtab.enter_scope() + + statements = block.statements + while self.next_token_ != "}" or self.cur_comments_: + self.advance_lexer_(comments=True) + if self.cur_token_type_ is Lexer.COMMENT: + statements.append( + self.ast.Comment(self.cur_token_, location=self.cur_token_location_) + ) + elif self.cur_token_type_ is Lexer.GLYPHCLASS: + statements.append(self.parse_glyphclass_definition_()) + elif self.is_cur_keyword_("anchorDef"): + statements.append(self.parse_anchordef_()) + elif self.is_cur_keyword_({"enum", "enumerate"}): + statements.append(self.parse_enumerate_(vertical=vertical)) + elif self.is_cur_keyword_("feature"): + statements.append(self.parse_feature_reference_()) + elif self.is_cur_keyword_("ignore"): + statements.append(self.parse_ignore_()) + elif self.is_cur_keyword_("language"): + statements.append(self.parse_language_()) + elif self.is_cur_keyword_("lookup"): + statements.append(self.parse_lookup_(vertical)) + elif self.is_cur_keyword_("lookupflag"): + statements.append(self.parse_lookupflag_()) + elif self.is_cur_keyword_("markClass"): + statements.append(self.parse_markClass_()) + elif self.is_cur_keyword_({"pos", "position"}): + statements.append( + self.parse_position_(enumerated=False, vertical=vertical) + ) + elif self.is_cur_keyword_("script"): + statements.append(self.parse_script_()) + elif self.is_cur_keyword_({"sub", "substitute", "rsub", "reversesub"}): + statements.append(self.parse_substitute_()) + elif self.is_cur_keyword_("subtable"): + statements.append(self.parse_subtable_()) + elif self.is_cur_keyword_("valueRecordDef"): + statements.append(self.parse_valuerecord_definition_(vertical)) + elif stylisticset and self.is_cur_keyword_("featureNames"): + statements.append(self.parse_featureNames_(stylisticset)) + elif cv_feature and self.is_cur_keyword_("cvParameters"): + statements.append(self.parse_cvParameters_(cv_feature)) + elif size_feature and self.is_cur_keyword_("parameters"): + statements.append(self.parse_size_parameters_()) + elif size_feature and self.is_cur_keyword_("sizemenuname"): + statements.append(self.parse_size_menuname_()) + elif ( + self.cur_token_type_ is Lexer.NAME + and self.cur_token_ in self.extensions + ): + statements.append(self.extensions[self.cur_token_](self)) + elif self.cur_token_ == ";": + continue + else: + raise FeatureLibError( + "Expected glyph class definition or statement: got {} {}".format( + self.cur_token_type_, self.cur_token_ + ), + self.cur_token_location_, + ) + + self.expect_symbol_("}") + for symtab in self.symbol_tables_: + symtab.exit_scope() + + name = self.expect_name_() + if name != block.name.strip(): + raise FeatureLibError( + 'Expected "%s"' % block.name.strip(), self.cur_token_location_ + ) + self.expect_symbol_(";") + + def is_cur_keyword_(self, k): + if self.cur_token_type_ is Lexer.NAME: + if isinstance(k, type("")): # basestring is gone in Python3 + return self.cur_token_ == k + else: + return self.cur_token_ in k + return False + + def expect_class_name_(self): + self.advance_lexer_() + if self.cur_token_type_ is not Lexer.GLYPHCLASS: + raise FeatureLibError("Expected @NAME", self.cur_token_location_) + return self.cur_token_ + + def expect_cid_(self): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.CID: + return self.cur_token_ + raise FeatureLibError("Expected a CID", self.cur_token_location_) + + def expect_filename_(self): + self.advance_lexer_() + if self.cur_token_type_ is not Lexer.FILENAME: + raise FeatureLibError("Expected file name", self.cur_token_location_) + return self.cur_token_ + + def expect_glyph_(self): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.NAME: + return self.cur_token_.lstrip("\\") + elif self.cur_token_type_ is Lexer.CID: + return "cid%05d" % self.cur_token_ + raise FeatureLibError("Expected a glyph name or CID", self.cur_token_location_) + + def check_glyph_name_in_glyph_set(self, *names): + """Adds a glyph name (just `start`) or glyph names of a + range (`start` and `end`) which are not in the glyph set + to the "missing list" for future error reporting. + + If no glyph set is present, does nothing. + """ + if self.glyphNames_: + for name in names: + if name in self.glyphNames_: + continue + if name not in self.missing: + self.missing[name] = self.cur_token_location_ + + def expect_markClass_reference_(self): + name = self.expect_class_name_() + mc = self.glyphclasses_.resolve(name) + if mc is None: + raise FeatureLibError( + "Unknown markClass @%s" % name, self.cur_token_location_ + ) + if not isinstance(mc, self.ast.MarkClass): + raise FeatureLibError( + "@%s is not a markClass" % name, self.cur_token_location_ + ) + return mc + + def expect_tag_(self): + self.advance_lexer_() + if self.cur_token_type_ is not Lexer.NAME: + raise FeatureLibError("Expected a tag", self.cur_token_location_) + if len(self.cur_token_) > 4: + raise FeatureLibError( + "Tags cannot be longer than 4 characters", self.cur_token_location_ + ) + return (self.cur_token_ + " ")[:4] + + def expect_script_tag_(self): + tag = self.expect_tag_() + if tag == "dflt": + raise FeatureLibError( + '"dflt" is not a valid script tag; use "DFLT" instead', + self.cur_token_location_, + ) + return tag + + def expect_language_tag_(self): + tag = self.expect_tag_() + if tag == "DFLT": + raise FeatureLibError( + '"DFLT" is not a valid language tag; use "dflt" instead', + self.cur_token_location_, + ) + return tag + + def expect_symbol_(self, symbol): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == symbol: + return symbol + raise FeatureLibError("Expected '%s'" % symbol, self.cur_token_location_) + + def expect_keyword_(self, keyword): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.NAME and self.cur_token_ == keyword: + return self.cur_token_ + raise FeatureLibError('Expected "%s"' % keyword, self.cur_token_location_) + + def expect_name_(self): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.NAME: + return self.cur_token_ + raise FeatureLibError("Expected a name", self.cur_token_location_) + + def expect_number_(self, variable=False): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.NUMBER: + return self.cur_token_ + if variable and self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == "(": + return self.expect_variable_scalar_() + raise FeatureLibError("Expected a number", self.cur_token_location_) + + def expect_variable_scalar_(self): + self.advance_lexer_() # "(" + scalar = VariableScalar() + while True: + if self.cur_token_type_ == Lexer.SYMBOL and self.cur_token_ == ")": + break + location, value = self.expect_master_() + scalar.add_value(location, value) + return scalar + + def expect_master_(self): + location = {} + while True: + if self.cur_token_type_ is not Lexer.NAME: + raise FeatureLibError("Expected an axis name", self.cur_token_location_) + axis = self.cur_token_ + self.advance_lexer_() + if not (self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == "="): + raise FeatureLibError( + "Expected an equals sign", self.cur_token_location_ + ) + value = self.expect_integer_or_float_() + location[axis] = value + if self.next_token_type_ is Lexer.NAME and self.next_token_[0] == ":": + # Lexer has just read the value as a glyph name. We'll correct it later + break + self.advance_lexer_() + if not (self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == ","): + raise FeatureLibError( + "Expected an comma or an equals sign", self.cur_token_location_ + ) + self.advance_lexer_() + self.advance_lexer_() + value = int(self.cur_token_[1:]) + self.advance_lexer_() + return location, value + + def expect_any_number_(self): + self.advance_lexer_() + if self.cur_token_type_ in Lexer.NUMBERS: + return self.cur_token_ + raise FeatureLibError( + "Expected a decimal, hexadecimal or octal number", self.cur_token_location_ + ) + + def expect_float_(self): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.FLOAT: + return self.cur_token_ + raise FeatureLibError( + "Expected a floating-point number", self.cur_token_location_ + ) + + def expect_integer_or_float_(self): + if self.next_token_type_ == Lexer.FLOAT: + return self.expect_float_() + elif self.next_token_type_ is Lexer.NUMBER: + return self.expect_number_() + else: + raise FeatureLibError( + "Expected an integer or floating-point number", self.cur_token_location_ + ) + + def expect_decipoint_(self): + if self.next_token_type_ == Lexer.FLOAT: + return self.expect_float_() + elif self.next_token_type_ is Lexer.NUMBER: + return self.expect_number_() / 10 + else: + raise FeatureLibError( + "Expected an integer or floating-point number", self.cur_token_location_ + ) + + def expect_stat_flags(self): + value = 0 + flags = { + "OlderSiblingFontAttribute": 1, + "ElidableAxisValueName": 2, + } + while self.next_token_ != ";": + if self.next_token_ in flags: + name = self.expect_name_() + value = value | flags[name] + else: + raise FeatureLibError( + f"Unexpected STAT flag {self.cur_token_}", self.cur_token_location_ + ) + return value + + def expect_stat_values_(self): + if self.next_token_type_ == Lexer.FLOAT: + return self.expect_float_() + elif self.next_token_type_ is Lexer.NUMBER: + return self.expect_number_() + else: + raise FeatureLibError( + "Expected an integer or floating-point number", self.cur_token_location_ + ) + + def expect_string_(self): + self.advance_lexer_() + if self.cur_token_type_ is Lexer.STRING: + return self.cur_token_ + raise FeatureLibError("Expected a string", self.cur_token_location_) + + def advance_lexer_(self, comments=False): + if comments and self.cur_comments_: + self.cur_token_type_ = Lexer.COMMENT + self.cur_token_, self.cur_token_location_ = self.cur_comments_.pop(0) + return + else: + self.cur_token_type_, self.cur_token_, self.cur_token_location_ = ( + self.next_token_type_, + self.next_token_, + self.next_token_location_, + ) + while True: + try: + ( + self.next_token_type_, + self.next_token_, + self.next_token_location_, + ) = next(self.lexer_) + except StopIteration: + self.next_token_type_, self.next_token_ = (None, None) + if self.next_token_type_ != Lexer.COMMENT: + break + self.cur_comments_.append((self.next_token_, self.next_token_location_)) + + @staticmethod + def reverse_string_(s): + """'abc' --> 'cba'""" + return "".join(reversed(list(s))) + + def make_cid_range_(self, location, start, limit): + """(location, 999, 1001) --> ["cid00999", "cid01000", "cid01001"]""" + result = list() + if start > limit: + raise FeatureLibError( + "Bad range: start should be less than limit", location + ) + for cid in range(start, limit + 1): + result.append("cid%05d" % cid) + return result + + def make_glyph_range_(self, location, start, limit): + """(location, "a.sc", "d.sc") --> ["a.sc", "b.sc", "c.sc", "d.sc"]""" + result = list() + if len(start) != len(limit): + raise FeatureLibError( + 'Bad range: "%s" and "%s" should have the same length' % (start, limit), + location, + ) + + rev = self.reverse_string_ + prefix = os.path.commonprefix([start, limit]) + suffix = rev(os.path.commonprefix([rev(start), rev(limit)])) + if len(suffix) > 0: + start_range = start[len(prefix) : -len(suffix)] + limit_range = limit[len(prefix) : -len(suffix)] + else: + start_range = start[len(prefix) :] + limit_range = limit[len(prefix) :] + + if start_range >= limit_range: + raise FeatureLibError( + "Start of range must be smaller than its end", location + ) + + uppercase = re.compile(r"^[A-Z]$") + if uppercase.match(start_range) and uppercase.match(limit_range): + for c in range(ord(start_range), ord(limit_range) + 1): + result.append("%s%c%s" % (prefix, c, suffix)) + return result + + lowercase = re.compile(r"^[a-z]$") + if lowercase.match(start_range) and lowercase.match(limit_range): + for c in range(ord(start_range), ord(limit_range) + 1): + result.append("%s%c%s" % (prefix, c, suffix)) + return result + + digits = re.compile(r"^[0-9]{1,3}$") + if digits.match(start_range) and digits.match(limit_range): + for i in range(int(start_range, 10), int(limit_range, 10) + 1): + number = ("000" + str(i))[-len(start_range) :] + result.append("%s%s%s" % (prefix, number, suffix)) + return result + + raise FeatureLibError('Bad range: "%s-%s"' % (start, limit), location) + + +class SymbolTable(object): + def __init__(self): + self.scopes_ = [{}] + + def enter_scope(self): + self.scopes_.append({}) + + def exit_scope(self): + self.scopes_.pop() + + def define(self, name, item): + self.scopes_[-1][name] = item + + def resolve(self, name): + for scope in reversed(self.scopes_): + item = scope.get(name) + if item: + return item + return None diff --git a/.venv/lib/python3.13/site-packages/fontTools/feaLib/variableScalar.py b/.venv/lib/python3.13/site-packages/fontTools/feaLib/variableScalar.py new file mode 100644 index 0000000000000000000000000000000000000000..31f1bd19f2de218c1dc7f063865a03f25018fbb6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/feaLib/variableScalar.py @@ -0,0 +1,118 @@ +from fontTools.varLib.models import VariationModel, normalizeValue, piecewiseLinearMap + + +def Location(loc): + return tuple(sorted(loc.items())) + + +class VariableScalar: + """A scalar with different values at different points in the designspace.""" + + def __init__(self, location_value={}): + self.values = {} + self.axes = {} + for location, value in location_value.items(): + self.add_value(location, value) + + def __repr__(self): + items = [] + for location, value in self.values.items(): + loc = ",".join( + [ + f"{ax}={int(coord) if float(coord).is_integer() else coord}" + for ax, coord in location + ] + ) + items.append("%s:%i" % (loc, value)) + return "(" + (" ".join(items)) + ")" + + @property + def does_vary(self): + values = list(self.values.values()) + return any(v != values[0] for v in values[1:]) + + @property + def axes_dict(self): + if not self.axes: + raise ValueError( + ".axes must be defined on variable scalar before interpolating" + ) + return {ax.axisTag: ax for ax in self.axes} + + def _normalized_location(self, location): + location = self.fix_location(location) + normalized_location = {} + for axtag in location.keys(): + if axtag not in self.axes_dict: + raise ValueError("Unknown axis %s in %s" % (axtag, location)) + axis = self.axes_dict[axtag] + normalized_location[axtag] = normalizeValue( + location[axtag], (axis.minValue, axis.defaultValue, axis.maxValue) + ) + + return Location(normalized_location) + + def fix_location(self, location): + location = dict(location) + for tag, axis in self.axes_dict.items(): + if tag not in location: + location[tag] = axis.defaultValue + return location + + def add_value(self, location, value): + if self.axes: + location = self.fix_location(location) + + self.values[Location(location)] = value + + def fix_all_locations(self): + self.values = { + Location(self.fix_location(l)): v for l, v in self.values.items() + } + + @property + def default(self): + self.fix_all_locations() + key = Location({ax.axisTag: ax.defaultValue for ax in self.axes}) + if key not in self.values: + raise ValueError("Default value could not be found") + # I *guess* we could interpolate one, but I don't know how. + return self.values[key] + + def value_at_location(self, location, model_cache=None, avar=None): + loc = Location(location) + if loc in self.values.keys(): + return self.values[loc] + values = list(self.values.values()) + loc = dict(self._normalized_location(loc)) + return self.model(model_cache, avar).interpolateFromMasters(loc, values) + + def model(self, model_cache=None, avar=None): + if model_cache is not None: + key = tuple(self.values.keys()) + if key in model_cache: + return model_cache[key] + locations = [dict(self._normalized_location(k)) for k in self.values.keys()] + if avar is not None: + mapping = avar.segments + locations = [ + { + k: piecewiseLinearMap(v, mapping[k]) if k in mapping else v + for k, v in location.items() + } + for location in locations + ] + m = VariationModel(locations) + if model_cache is not None: + model_cache[key] = m + return m + + def get_deltas_and_supports(self, model_cache=None, avar=None): + values = list(self.values.values()) + return self.model(model_cache, avar).getDeltasAndSupports(values) + + def add_to_variation_store(self, store_builder, model_cache=None, avar=None): + deltas, supports = self.get_deltas_and_supports(model_cache, avar) + store_builder.setSupports(supports) + index = store_builder.storeDeltas(deltas) + return int(self.default), index diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/__init__.py b/.venv/lib/python3.13/site-packages/fontTools/misc/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..156cb232a7aa80eee1526c7598f72043de10473f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/__init__.py @@ -0,0 +1 @@ +"""Empty __init__.py file to signal Python this directory is a package.""" diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/arrayTools.py b/.venv/lib/python3.13/site-packages/fontTools/misc/arrayTools.py new file mode 100644 index 0000000000000000000000000000000000000000..ced8d87a613c1b43d3d6c6c822e053aae92a08cd --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/arrayTools.py @@ -0,0 +1,424 @@ +"""Routines for calculating bounding boxes, point in rectangle calculations and +so on. +""" + +from fontTools.misc.roundTools import otRound +from fontTools.misc.vector import Vector as _Vector +import math +import warnings + + +def calcBounds(array): + """Calculate the bounding rectangle of a 2D points array. + + Args: + array: A sequence of 2D tuples. + + Returns: + A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``. + """ + if not array: + return 0, 0, 0, 0 + xs = [x for x, y in array] + ys = [y for x, y in array] + return min(xs), min(ys), max(xs), max(ys) + + +def calcIntBounds(array, round=otRound): + """Calculate the integer bounding rectangle of a 2D points array. + + Values are rounded to closest integer towards ``+Infinity`` using the + :func:`fontTools.misc.fixedTools.otRound` function by default, unless + an optional ``round`` function is passed. + + Args: + array: A sequence of 2D tuples. + round: A rounding function of type ``f(x: float) -> int``. + + Returns: + A four-item tuple of integers representing the bounding rectangle: + ``(xMin, yMin, xMax, yMax)``. + """ + return tuple(round(v) for v in calcBounds(array)) + + +def updateBounds(bounds, p, min=min, max=max): + """Add a point to a bounding rectangle. + + Args: + bounds: A bounding rectangle expressed as a tuple + ``(xMin, yMin, xMax, yMax), or None``. + p: A 2D tuple representing a point. + min,max: functions to compute the minimum and maximum. + + Returns: + The updated bounding rectangle ``(xMin, yMin, xMax, yMax)``. + """ + (x, y) = p + if bounds is None: + return x, y, x, y + xMin, yMin, xMax, yMax = bounds + return min(xMin, x), min(yMin, y), max(xMax, x), max(yMax, y) + + +def pointInRect(p, rect): + """Test if a point is inside a bounding rectangle. + + Args: + p: A 2D tuple representing a point. + rect: A bounding rectangle expressed as a tuple + ``(xMin, yMin, xMax, yMax)``. + + Returns: + ``True`` if the point is inside the rectangle, ``False`` otherwise. + """ + (x, y) = p + xMin, yMin, xMax, yMax = rect + return (xMin <= x <= xMax) and (yMin <= y <= yMax) + + +def pointsInRect(array, rect): + """Determine which points are inside a bounding rectangle. + + Args: + array: A sequence of 2D tuples. + rect: A bounding rectangle expressed as a tuple + ``(xMin, yMin, xMax, yMax)``. + + Returns: + A list containing the points inside the rectangle. + """ + if len(array) < 1: + return [] + xMin, yMin, xMax, yMax = rect + return [(xMin <= x <= xMax) and (yMin <= y <= yMax) for x, y in array] + + +def vectorLength(vector): + """Calculate the length of the given vector. + + Args: + vector: A 2D tuple. + + Returns: + The Euclidean length of the vector. + """ + x, y = vector + return math.sqrt(x**2 + y**2) + + +def asInt16(array): + """Round a list of floats to 16-bit signed integers. + + Args: + array: List of float values. + + Returns: + A list of rounded integers. + """ + return [int(math.floor(i + 0.5)) for i in array] + + +def normRect(rect): + """Normalize a bounding box rectangle. + + This function "turns the rectangle the right way up", so that the following + holds:: + + xMin <= xMax and yMin <= yMax + + Args: + rect: A bounding rectangle expressed as a tuple + ``(xMin, yMin, xMax, yMax)``. + + Returns: + A normalized bounding rectangle. + """ + (xMin, yMin, xMax, yMax) = rect + return min(xMin, xMax), min(yMin, yMax), max(xMin, xMax), max(yMin, yMax) + + +def scaleRect(rect, x, y): + """Scale a bounding box rectangle. + + Args: + rect: A bounding rectangle expressed as a tuple + ``(xMin, yMin, xMax, yMax)``. + x: Factor to scale the rectangle along the X axis. + Y: Factor to scale the rectangle along the Y axis. + + Returns: + A scaled bounding rectangle. + """ + (xMin, yMin, xMax, yMax) = rect + return xMin * x, yMin * y, xMax * x, yMax * y + + +def offsetRect(rect, dx, dy): + """Offset a bounding box rectangle. + + Args: + rect: A bounding rectangle expressed as a tuple + ``(xMin, yMin, xMax, yMax)``. + dx: Amount to offset the rectangle along the X axis. + dY: Amount to offset the rectangle along the Y axis. + + Returns: + An offset bounding rectangle. + """ + (xMin, yMin, xMax, yMax) = rect + return xMin + dx, yMin + dy, xMax + dx, yMax + dy + + +def insetRect(rect, dx, dy): + """Inset a bounding box rectangle on all sides. + + Args: + rect: A bounding rectangle expressed as a tuple + ``(xMin, yMin, xMax, yMax)``. + dx: Amount to inset the rectangle along the X axis. + dY: Amount to inset the rectangle along the Y axis. + + Returns: + An inset bounding rectangle. + """ + (xMin, yMin, xMax, yMax) = rect + return xMin + dx, yMin + dy, xMax - dx, yMax - dy + + +def sectRect(rect1, rect2): + """Test for rectangle-rectangle intersection. + + Args: + rect1: First bounding rectangle, expressed as tuples + ``(xMin, yMin, xMax, yMax)``. + rect2: Second bounding rectangle. + + Returns: + A boolean and a rectangle. + If the input rectangles intersect, returns ``True`` and the intersecting + rectangle. Returns ``False`` and ``(0, 0, 0, 0)`` if the input + rectangles don't intersect. + """ + (xMin1, yMin1, xMax1, yMax1) = rect1 + (xMin2, yMin2, xMax2, yMax2) = rect2 + xMin, yMin, xMax, yMax = ( + max(xMin1, xMin2), + max(yMin1, yMin2), + min(xMax1, xMax2), + min(yMax1, yMax2), + ) + if xMin >= xMax or yMin >= yMax: + return False, (0, 0, 0, 0) + return True, (xMin, yMin, xMax, yMax) + + +def unionRect(rect1, rect2): + """Determine union of bounding rectangles. + + Args: + rect1: First bounding rectangle, expressed as tuples + ``(xMin, yMin, xMax, yMax)``. + rect2: Second bounding rectangle. + + Returns: + The smallest rectangle in which both input rectangles are fully + enclosed. + """ + (xMin1, yMin1, xMax1, yMax1) = rect1 + (xMin2, yMin2, xMax2, yMax2) = rect2 + xMin, yMin, xMax, yMax = ( + min(xMin1, xMin2), + min(yMin1, yMin2), + max(xMax1, xMax2), + max(yMax1, yMax2), + ) + return (xMin, yMin, xMax, yMax) + + +def rectCenter(rect): + """Determine rectangle center. + + Args: + rect: Bounding rectangle, expressed as tuples + ``(xMin, yMin, xMax, yMax)``. + + Returns: + A 2D tuple representing the point at the center of the rectangle. + """ + (xMin, yMin, xMax, yMax) = rect + return (xMin + xMax) / 2, (yMin + yMax) / 2 + + +def rectArea(rect): + """Determine rectangle area. + + Args: + rect: Bounding rectangle, expressed as tuples + ``(xMin, yMin, xMax, yMax)``. + + Returns: + The area of the rectangle. + """ + (xMin, yMin, xMax, yMax) = rect + return (yMax - yMin) * (xMax - xMin) + + +def intRect(rect): + """Round a rectangle to integer values. + + Guarantees that the resulting rectangle is NOT smaller than the original. + + Args: + rect: Bounding rectangle, expressed as tuples + ``(xMin, yMin, xMax, yMax)``. + + Returns: + A rounded bounding rectangle. + """ + (xMin, yMin, xMax, yMax) = rect + xMin = int(math.floor(xMin)) + yMin = int(math.floor(yMin)) + xMax = int(math.ceil(xMax)) + yMax = int(math.ceil(yMax)) + return (xMin, yMin, xMax, yMax) + + +def quantizeRect(rect, factor=1): + """ + >>> bounds = (72.3, -218.4, 1201.3, 919.1) + >>> quantizeRect(bounds) + (72, -219, 1202, 920) + >>> quantizeRect(bounds, factor=10) + (70, -220, 1210, 920) + >>> quantizeRect(bounds, factor=100) + (0, -300, 1300, 1000) + """ + if factor < 1: + raise ValueError(f"Expected quantization factor >= 1, found: {factor!r}") + xMin, yMin, xMax, yMax = normRect(rect) + return ( + int(math.floor(xMin / factor) * factor), + int(math.floor(yMin / factor) * factor), + int(math.ceil(xMax / factor) * factor), + int(math.ceil(yMax / factor) * factor), + ) + + +class Vector(_Vector): + def __init__(self, *args, **kwargs): + warnings.warn( + "fontTools.misc.arrayTools.Vector has been deprecated, please use " + "fontTools.misc.vector.Vector instead.", + DeprecationWarning, + ) + + +def pairwise(iterable, reverse=False): + """Iterate over current and next items in iterable. + + Args: + iterable: An iterable + reverse: If true, iterate in reverse order. + + Returns: + A iterable yielding two elements per iteration. + + Example: + + >>> tuple(pairwise([])) + () + >>> tuple(pairwise([], reverse=True)) + () + >>> tuple(pairwise([0])) + ((0, 0),) + >>> tuple(pairwise([0], reverse=True)) + ((0, 0),) + >>> tuple(pairwise([0, 1])) + ((0, 1), (1, 0)) + >>> tuple(pairwise([0, 1], reverse=True)) + ((1, 0), (0, 1)) + >>> tuple(pairwise([0, 1, 2])) + ((0, 1), (1, 2), (2, 0)) + >>> tuple(pairwise([0, 1, 2], reverse=True)) + ((2, 1), (1, 0), (0, 2)) + >>> tuple(pairwise(['a', 'b', 'c', 'd'])) + (('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')) + >>> tuple(pairwise(['a', 'b', 'c', 'd'], reverse=True)) + (('d', 'c'), ('c', 'b'), ('b', 'a'), ('a', 'd')) + """ + if not iterable: + return + if reverse: + it = reversed(iterable) + else: + it = iter(iterable) + first = next(it, None) + a = first + for b in it: + yield (a, b) + a = b + yield (a, first) + + +def _test(): + """ + >>> import math + >>> calcBounds([]) + (0, 0, 0, 0) + >>> calcBounds([(0, 40), (0, 100), (50, 50), (80, 10)]) + (0, 10, 80, 100) + >>> updateBounds((0, 0, 0, 0), (100, 100)) + (0, 0, 100, 100) + >>> pointInRect((50, 50), (0, 0, 100, 100)) + True + >>> pointInRect((0, 0), (0, 0, 100, 100)) + True + >>> pointInRect((100, 100), (0, 0, 100, 100)) + True + >>> not pointInRect((101, 100), (0, 0, 100, 100)) + True + >>> list(pointsInRect([(50, 50), (0, 0), (100, 100), (101, 100)], (0, 0, 100, 100))) + [True, True, True, False] + >>> vectorLength((3, 4)) + 5.0 + >>> vectorLength((1, 1)) == math.sqrt(2) + True + >>> list(asInt16([0, 0.1, 0.5, 0.9])) + [0, 0, 1, 1] + >>> normRect((0, 10, 100, 200)) + (0, 10, 100, 200) + >>> normRect((100, 200, 0, 10)) + (0, 10, 100, 200) + >>> scaleRect((10, 20, 50, 150), 1.5, 2) + (15.0, 40, 75.0, 300) + >>> offsetRect((10, 20, 30, 40), 5, 6) + (15, 26, 35, 46) + >>> insetRect((10, 20, 50, 60), 5, 10) + (15, 30, 45, 50) + >>> insetRect((10, 20, 50, 60), -5, -10) + (5, 10, 55, 70) + >>> intersects, rect = sectRect((0, 10, 20, 30), (0, 40, 20, 50)) + >>> not intersects + True + >>> intersects, rect = sectRect((0, 10, 20, 30), (5, 20, 35, 50)) + >>> intersects + 1 + >>> rect + (5, 20, 20, 30) + >>> unionRect((0, 10, 20, 30), (0, 40, 20, 50)) + (0, 10, 20, 50) + >>> rectCenter((0, 0, 100, 200)) + (50.0, 100.0) + >>> rectCenter((0, 0, 100, 199.0)) + (50.0, 99.5) + >>> intRect((0.9, 2.9, 3.1, 4.1)) + (0, 2, 4, 5) + """ + + +if __name__ == "__main__": + import sys + import doctest + + sys.exit(doctest.testmod().failed) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/bezierTools.c b/.venv/lib/python3.13/site-packages/fontTools/misc/bezierTools.c new file mode 100644 index 0000000000000000000000000000000000000000..5940e7dab9038d3110f7ebed4ce27493a306d7b3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/bezierTools.c @@ -0,0 +1,39731 @@ +/* Generated by Cython 3.2.2 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "name": "fontTools.misc.bezierTools", + "sources": [ + "Lib/fontTools/misc/bezierTools.py" + ] + }, + "module_name": "fontTools.misc.bezierTools" +} +END: Cython Metadata */ + +#ifndef PY_SSIZE_T_CLEAN +#define PY_SSIZE_T_CLEAN +#endif /* PY_SSIZE_T_CLEAN */ +/* InitLimitedAPI */ +#if defined(Py_LIMITED_API) + #if !defined(CYTHON_LIMITED_API) + #define CYTHON_LIMITED_API 1 + #endif +#elif defined(CYTHON_LIMITED_API) + #ifdef _MSC_VER + #pragma message ("Limited API usage is enabled with 'CYTHON_LIMITED_API' but 'Py_LIMITED_API' does not define a Python target version. Consider setting 'Py_LIMITED_API' instead.") + #else + #warning Limited API usage is enabled with 'CYTHON_LIMITED_API' but 'Py_LIMITED_API' does not define a Python target version. Consider setting 'Py_LIMITED_API' instead. + #endif +#endif + +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x03080000 + #error Cython requires Python 3.8+. +#else +#define __PYX_ABI_VERSION "3_2_2" +#define CYTHON_HEX_VERSION 0x030202F0 +#define CYTHON_FUTURE_DIVISION 1 +/* CModulePreamble */ +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(_WIN32) && !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#define __PYX_LIMITED_VERSION_HEX PY_VERSION_HEX +#if defined(GRAALVM_PYTHON) + /* For very preliminary testing purposes. Most variables are set the same as PyPy. + The existence of this section does not imply that anything works or is even tested */ + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 1 + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 0 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 1 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif + #undef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 +#elif defined(PYPY_VERSION) + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #ifndef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 1 + #endif + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #if PY_VERSION_HEX < 0x03090000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING 0 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PYPY_VERSION_NUM >= 0x07030C00) + #endif + #undef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC (PYPY_VERSION_NUM >= 0x07031100) + #endif + #undef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 +#elif defined(CYTHON_LIMITED_API) + #ifdef Py_LIMITED_API + #undef __PYX_LIMITED_VERSION_HEX + #define __PYX_LIMITED_VERSION_HEX Py_LIMITED_API + #endif + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 1 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 1 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #endif + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 0 + #endif + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL (__PYX_LIMITED_VERSION_HEX >= 0x030C0000) + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #undef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING 0 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #endif + #ifndef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND (__PYX_LIMITED_VERSION_HEX >= 0x030A0000) + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif + #ifndef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 1 + #endif + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #ifdef Py_GIL_DISABLED + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 1 + #else + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #endif + #if PY_VERSION_HEX < 0x030A0000 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #elif !defined(CYTHON_USE_TYPE_SLOTS) + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #ifndef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #ifndef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #elif !defined(CYTHON_USE_PYLIST_INTERNALS) + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING || PY_VERSION_HEX >= 0x030B00A2 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 1 + #elif !defined(CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS) + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #elif !defined(CYTHON_FAST_GIL) + #define CYTHON_FAST_GIL (PY_VERSION_HEX < 0x030C00A6) + #endif + #ifndef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 1 + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #ifndef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING (PY_VERSION_HEX >= 0x030d00B1) + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #ifndef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #elif !defined(CYTHON_USE_DICT_VERSIONS) + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX < 0x030C00A5 && !CYTHON_USE_MODULE_STATE) + #endif + #ifndef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 1 + #endif + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 + #endif + #ifndef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS (!CYTHON_COMPILING_IN_CPYTHON_FREETHREADING) + #endif + #if defined(CYTHON_IMMORTAL_CONSTANTS) && PY_VERSION_HEX < 0x030C0000 + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 // definitely won't work + #elif !defined(CYTHON_IMMORTAL_CONSTANTS) + #define CYTHON_IMMORTAL_CONSTANTS (PY_VERSION_HEX >= 0x030C0000 && !CYTHON_USE_MODULE_STATE && CYTHON_COMPILING_IN_CPYTHON_FREETHREADING) + #endif +#endif +#ifndef CYTHON_COMPRESS_STRINGS + #define CYTHON_COMPRESS_STRINGS 1 +#endif +#ifndef CYTHON_FAST_PYCCALL +#define CYTHON_FAST_PYCCALL CYTHON_FAST_PYCALL +#endif +#ifndef CYTHON_VECTORCALL +#if CYTHON_COMPILING_IN_LIMITED_API +#define CYTHON_VECTORCALL (__PYX_LIMITED_VERSION_HEX >= 0x030C0000) +#else +#define CYTHON_VECTORCALL (CYTHON_FAST_PYCCALL) +#endif +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(maybe_unused) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(maybe_unused) + #define CYTHON_UNUSED [[maybe_unused]] + #endif + #endif + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR + #define CYTHON_MAYBE_UNUSED_VAR(x) CYTHON_UNUSED_VAR(x) +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON && !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_USE_CPP_STD_MOVE + #if defined(__cplusplus) && (\ + __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)) + #define CYTHON_USE_CPP_STD_MOVE 1 + #else + #define CYTHON_USE_CPP_STD_MOVE 0 + #endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#include +typedef uintptr_t __pyx_uintptr_t; +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(fallthrough) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif +#ifndef Py_UNREACHABLE + #define Py_UNREACHABLE() assert(0); abort() +#endif +#ifdef __cplusplus + template + struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);}; + #define __PYX_IS_UNSIGNED(type) (__PYX_IS_UNSIGNED_IMPL::value) +#else + #define __PYX_IS_UNSIGNED(type) (((type)-1) > 0) +#endif +#if CYTHON_COMPILING_IN_PYPY == 1 + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX < 0x030A0000) +#else + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX < 0x03090000) +#endif +#define __PYX_REINTERPRET_FUNCION(func_pointer, other_pointer) ((func_pointer)(void(*)(void))(other_pointer)) + +/* CInitCode */ +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +/* PythonCompatibility */ +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#define __Pyx_BUILTIN_MODULE_NAME "builtins" +#define __Pyx_DefaultClassType PyType_Type +#if CYTHON_COMPILING_IN_LIMITED_API + #ifndef CO_OPTIMIZED + static int CO_OPTIMIZED; + #endif + #ifndef CO_NEWLOCALS + static int CO_NEWLOCALS; + #endif + #ifndef CO_VARARGS + static int CO_VARARGS; + #endif + #ifndef CO_VARKEYWORDS + static int CO_VARKEYWORDS; + #endif + #ifndef CO_ASYNC_GENERATOR + static int CO_ASYNC_GENERATOR; + #endif + #ifndef CO_GENERATOR + static int CO_GENERATOR; + #endif + #ifndef CO_COROUTINE + static int CO_COROUTINE; + #endif +#else + #ifndef CO_COROUTINE + #define CO_COROUTINE 0x80 + #endif + #ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x200 + #endif +#endif +static int __Pyx_init_co_variables(void); +#if PY_VERSION_HEX >= 0x030900A4 || defined(Py_IS_TYPE) + #define __Pyx_IS_TYPE(ob, type) Py_IS_TYPE(ob, type) +#else + #define __Pyx_IS_TYPE(ob, type) (((const PyObject*)ob)->ob_type == (type)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_Is) + #define __Pyx_Py_Is(x, y) Py_Is(x, y) +#else + #define __Pyx_Py_Is(x, y) ((x) == (y)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsNone) + #define __Pyx_Py_IsNone(ob) Py_IsNone(ob) +#else + #define __Pyx_Py_IsNone(ob) __Pyx_Py_Is((ob), Py_None) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsTrue) + #define __Pyx_Py_IsTrue(ob) Py_IsTrue(ob) +#else + #define __Pyx_Py_IsTrue(ob) __Pyx_Py_Is((ob), Py_True) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsFalse) + #define __Pyx_Py_IsFalse(ob) Py_IsFalse(ob) +#else + #define __Pyx_Py_IsFalse(ob) __Pyx_Py_Is((ob), Py_False) +#endif +#define __Pyx_NoneAsNull(obj) (__Pyx_Py_IsNone(obj) ? NULL : (obj)) +#if PY_VERSION_HEX >= 0x030900F0 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyObject_GC_IsFinalized(o) PyObject_GC_IsFinalized(o) +#else + #define __Pyx_PyObject_GC_IsFinalized(o) _PyGC_FINALIZED(o) +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef Py_TPFLAGS_SEQUENCE + #define Py_TPFLAGS_SEQUENCE 0 +#endif +#ifndef Py_TPFLAGS_MAPPING + #define Py_TPFLAGS_MAPPING 0 +#endif +#ifndef Py_TPFLAGS_IMMUTABLETYPE + #define Py_TPFLAGS_IMMUTABLETYPE (1UL << 8) +#endif +#ifndef Py_TPFLAGS_DISALLOW_INSTANTIATION + #define Py_TPFLAGS_DISALLOW_INSTANTIATION (1UL << 7) +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#ifndef METH_FASTCALL + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #if PY_VERSION_HEX >= 0x030d00A4 + # define __Pyx_PyCFunctionFast PyCFunctionFast + # define __Pyx_PyCFunctionFastWithKeywords PyCFunctionFastWithKeywords + #else + # define __Pyx_PyCFunctionFast _PyCFunctionFast + # define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords + #endif +#endif +#if CYTHON_METH_FASTCALL + #define __Pyx_METH_FASTCALL METH_FASTCALL + #define __Pyx_PyCFunction_FastCall __Pyx_PyCFunctionFast + #define __Pyx_PyCFunction_FastCallWithKeywords __Pyx_PyCFunctionFastWithKeywords +#else + #define __Pyx_METH_FASTCALL METH_VARARGS + #define __Pyx_PyCFunction_FastCall PyCFunction + #define __Pyx_PyCFunction_FastCallWithKeywords PyCFunctionWithKeywords +#endif +#if CYTHON_VECTORCALL + #define __pyx_vectorcallfunc vectorcallfunc + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET PY_VECTORCALL_ARGUMENTS_OFFSET + #define __Pyx_PyVectorcall_NARGS(n) PyVectorcall_NARGS((size_t)(n)) +#else + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET 0 + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(n)) +#endif +#if PY_VERSION_HEX >= 0x030900B1 +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_CheckExact(func) +#else +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_Check(func) +#endif +#define __Pyx_CyOrPyCFunction_Check(func) PyCFunction_Check(func) +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) (((PyCFunctionObject*)(func))->m_ml->ml_meth) +#elif !CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(func) +#endif +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FLAGS(func) (((PyCFunctionObject*)(func))->m_ml->ml_flags) +static CYTHON_INLINE PyObject* __Pyx_CyOrPyCFunction_GET_SELF(PyObject *func) { + return (__Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_STATIC) ? NULL : ((PyCFunctionObject*)func)->m_self; +} +#endif +static CYTHON_INLINE int __Pyx__IsSameCFunction(PyObject *func, void (*cfunc)(void)) { +#if CYTHON_COMPILING_IN_LIMITED_API + return PyCFunction_Check(func) && PyCFunction_GetFunction(func) == (PyCFunction) cfunc; +#else + return PyCFunction_Check(func) && PyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +#endif +} +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCFunction(func, cfunc) +#if PY_VERSION_HEX < 0x03090000 || (CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000) + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) ((void)m, PyType_FromSpecWithBases(s, b)) + typedef PyObject *(*__Pyx_PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *); +#else + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) PyType_FromModuleAndSpec(m, s, b) + #define __Pyx_PyCMethod PyCMethod +#endif +#ifndef METH_METHOD + #define METH_METHOD 0x200 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) +#elif CYTHON_COMPILING_IN_GRAAL && defined(GRAALPY_VERSION_NUM) && GRAALPY_VERSION_NUM > 0x19000000 + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) GraalPyFrame_SetLineNumber((frame), (lineno)) +#elif CYTHON_COMPILING_IN_GRAAL + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) _PyFrame_SetLineNumber((frame), (lineno)) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyThreadState_Current PyThreadState_Get() +#elif !CYTHON_FAST_THREAD_STATE + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyThreadState_Current PyThreadState_GetUnchecked() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#endif +#if CYTHON_USE_MODULE_STATE +static CYTHON_INLINE void *__Pyx__PyModule_GetState(PyObject *op) +{ + void *result; + result = PyModule_GetState(op); + if (!result) + Py_FatalError("Couldn't find the module state"); + return result; +} +#define __Pyx_PyModule_GetState(o) (__pyx_mstatetype *)__Pyx__PyModule_GetState(o) +#else +#define __Pyx_PyModule_GetState(op) ((void)op,__pyx_mstate_global) +#endif +#define __Pyx_PyObject_GetSlot(obj, name, func_ctype) __Pyx_PyType_GetSlot(Py_TYPE((PyObject *) obj), name, func_ctype) +#define __Pyx_PyObject_TryGetSlot(obj, name, func_ctype) __Pyx_PyType_TryGetSlot(Py_TYPE(obj), name, func_ctype) +#define __Pyx_PyObject_GetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_GetSubSlot(Py_TYPE(obj), sub, name, func_ctype) +#define __Pyx_PyObject_TryGetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_TryGetSubSlot(Py_TYPE(obj), sub, name, func_ctype) +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((type)->name) + #define __Pyx_PyType_TryGetSlot(type, name, func_ctype) __Pyx_PyType_GetSlot(type, name, func_ctype) + #define __Pyx_PyType_GetSubSlot(type, sub, name, func_ctype) (((type)->sub) ? ((type)->sub->name) : NULL) + #define __Pyx_PyType_TryGetSubSlot(type, sub, name, func_ctype) __Pyx_PyType_GetSubSlot(type, sub, name, func_ctype) +#else + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((func_ctype) PyType_GetSlot((type), Py_##name)) + #define __Pyx_PyType_TryGetSlot(type, name, func_ctype)\ + ((__PYX_LIMITED_VERSION_HEX >= 0x030A0000 ||\ + (PyType_GetFlags(type) & Py_TPFLAGS_HEAPTYPE) || __Pyx_get_runtime_version() >= 0x030A0000) ?\ + __Pyx_PyType_GetSlot(type, name, func_ctype) : NULL) + #define __Pyx_PyType_GetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_GetSlot(obj, name, func_ctype) + #define __Pyx_PyType_TryGetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_TryGetSlot(obj, name, func_ctype) +#endif +#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) +#define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStrWithError(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStr(PyObject *dict, PyObject *name) { + PyObject *res = __Pyx_PyDict_GetItemStrWithError(dict, name); + if (res == NULL) PyErr_Clear(); + return res; +} +#elif !CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000 +#define __Pyx_PyDict_GetItemStrWithError PyDict_GetItemWithError +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#else +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict, PyObject *name) { +#if CYTHON_COMPILING_IN_PYPY + return PyDict_GetItem(dict, name); +#else + PyDictEntry *ep; + PyDictObject *mp = (PyDictObject*) dict; + long hash = ((PyStringObject *) name)->ob_shash; + assert(hash != -1); + ep = (mp->ma_lookup)(mp, name, hash); + if (ep == NULL) { + return NULL; + } + return ep->me_value; +#endif +} +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#endif +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags) + #define __Pyx_PyType_HasFeature(type, feature) ((__Pyx_PyType_GetFlags(type) & (feature)) != 0) +#else + #define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp)) + #define __Pyx_PyType_HasFeature(type, feature) PyType_HasFeature(type, feature) +#endif +#define __Pyx_PyObject_GetIterNextFunc(iterator) __Pyx_PyObject_GetSlot(iterator, tp_iternext, iternextfunc) +#if CYTHON_USE_TYPE_SPECS +#define __Pyx_PyHeapTypeObject_GC_Del(obj) {\ + PyTypeObject *type = Py_TYPE((PyObject*)obj);\ + assert(__Pyx_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE));\ + PyObject_GC_Del(obj);\ + Py_DECREF(type);\ +} +#else +#define __Pyx_PyHeapTypeObject_GC_Del(obj) PyObject_GC_Del(obj) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_ReadChar(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((void)u, 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((void)u, (0)) + #define __Pyx_PyUnicode_DATA(u) ((void*)u) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)k, PyUnicode_ReadChar((PyObject*)(d), i)) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GetLength(u)) +#else + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_READY(op) (0) + #else + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #endif + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) ((int)PyUnicode_KIND(u)) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, (Py_UCS4) ch) + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #else + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length)) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #endif + #endif +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #if !defined(PyUnicode_DecodeUnicodeEscape) + #define PyUnicode_DecodeUnicodeEscape(s, size, errors) PyUnicode_Decode(s, size, "unicode_escape", errors) + #endif + #if !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) + #endif + #if !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) + #endif + #if !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) + #endif +#endif +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && PyUnstable_Object_IsUniquelyReferenced(obj)) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#elif CYTHON_COMPILING_IN_CPYTHON + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#else + #define __Pyx_PySequence_ListKeepNew(obj) PySequence_List(obj) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) __Pyx_IS_TYPE(obj, &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +enum __Pyx_ReferenceSharing { + __Pyx_ReferenceSharing_DefinitelyUnique, // We created it so we know it's unshared - no need to check + __Pyx_ReferenceSharing_OwnStrongReference, + __Pyx_ReferenceSharing_FunctionArgument, + __Pyx_ReferenceSharing_SharedReference, // Never trust it to be unshared because it's a global or similar +}; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && PY_VERSION_HEX >= 0x030E0000 +#define __Pyx_IS_UNIQUELY_REFERENCED(o, sharing)\ + (sharing == __Pyx_ReferenceSharing_DefinitelyUnique ? 1 :\ + (sharing == __Pyx_ReferenceSharing_FunctionArgument ? PyUnstable_Object_IsUniqueReferencedTemporary(o) :\ + (sharing == __Pyx_ReferenceSharing_OwnStrongReference ? PyUnstable_Object_IsUniquelyReferenced(o) : 0))) +#elif (CYTHON_COMPILING_IN_CPYTHON && !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING) || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_IS_UNIQUELY_REFERENCED(o, sharing) (((void)sharing), Py_REFCNT(o) == 1) +#else +#define __Pyx_IS_UNIQUELY_REFERENCED(o, sharing) (((void)o), ((void)sharing), 0) +#endif +#if CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + #define __Pyx_PyList_GetItemRef(o, i) PyList_GetItemRef(o, i) + #elif CYTHON_COMPILING_IN_LIMITED_API || !CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PyList_GetItemRef(o, i) (likely((i) >= 0) ? PySequence_GetItem(o, i) : (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) + #else + #define __Pyx_PyList_GetItemRef(o, i) PySequence_ITEM(o, i) + #endif +#elif CYTHON_COMPILING_IN_LIMITED_API || !CYTHON_ASSUME_SAFE_MACROS + #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + #define __Pyx_PyList_GetItemRef(o, i) PyList_GetItemRef(o, i) + #else + #define __Pyx_PyList_GetItemRef(o, i) __Pyx_XNewRef(PyList_GetItem(o, i)) + #endif +#else + #define __Pyx_PyList_GetItemRef(o, i) __Pyx_NewRef(PyList_GET_ITEM(o, i)) +#endif +#if CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS && !CYTHON_COMPILING_IN_LIMITED_API && CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PyList_GetItemRefFast(o, i, unsafe_shared) (__Pyx_IS_UNIQUELY_REFERENCED(o, unsafe_shared) ?\ + __Pyx_NewRef(PyList_GET_ITEM(o, i)) : __Pyx_PyList_GetItemRef(o, i)) +#else + #define __Pyx_PyList_GetItemRefFast(o, i, unsafe_shared) __Pyx_PyList_GetItemRef(o, i) +#endif +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 +#define __Pyx_PyDict_GetItemRef(dict, key, result) PyDict_GetItemRef(dict, key, result) +#elif CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS +static CYTHON_INLINE int __Pyx_PyDict_GetItemRef(PyObject *dict, PyObject *key, PyObject **result) { + *result = PyObject_GetItem(dict, key); + if (*result == NULL) { + if (PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_Clear(); + return 0; + } + return -1; + } + return 1; +} +#else +static CYTHON_INLINE int __Pyx_PyDict_GetItemRef(PyObject *dict, PyObject *key, PyObject **result) { + *result = PyDict_GetItemWithError(dict, key); + if (*result == NULL) { + return PyErr_Occurred() ? -1 : 0; + } + Py_INCREF(*result); + return 1; +} +#endif +#if defined(CYTHON_DEBUG_VISIT_CONST) && CYTHON_DEBUG_VISIT_CONST + #define __Pyx_VISIT_CONST(obj) Py_VISIT(obj) +#else + #define __Pyx_VISIT_CONST(obj) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_ITEM(o, i) PySequence_ITEM(o, i) + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) (PyTuple_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyTuple_GET_ITEM(o, i) PyTuple_GET_ITEM(o, i) + #define __Pyx_PyList_SET_ITEM(o, i, v) (PyList_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyList_GET_ITEM(o, i) PyList_GET_ITEM(o, i) +#else + #define __Pyx_PySequence_ITEM(o, i) PySequence_GetItem(o, i) + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) PyTuple_SetItem(o, i, v) + #define __Pyx_PyTuple_GET_ITEM(o, i) PyTuple_GetItem(o, i) + #define __Pyx_PyList_SET_ITEM(o, i, v) PyList_SetItem(o, i, v) + #define __Pyx_PyList_GET_ITEM(o, i) PyList_GetItem(o, i) +#endif +#if CYTHON_ASSUME_SAFE_SIZE + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_GET_SIZE(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_GET_SIZE(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_GET_SIZE(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_GET_SIZE(o) + #define __Pyx_PyUnicode_GET_LENGTH(o) PyUnicode_GET_LENGTH(o) +#else + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_Size(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_Size(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_Size(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_Size(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_Size(o) + #define __Pyx_PyUnicode_GET_LENGTH(o) PyUnicode_GetLength(o) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_InternFromString) + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) +#endif +#define __Pyx_PyLong_FromHash_t PyLong_FromSsize_t +#define __Pyx_PyLong_AsHash_t __Pyx_PyIndex_AsSsize_t +#if __PYX_LIMITED_VERSION_HEX >= 0x030A0000 + #define __Pyx_PySendResult PySendResult +#else + typedef enum { + PYGEN_RETURN = 0, + PYGEN_ERROR = -1, + PYGEN_NEXT = 1, + } __Pyx_PySendResult; +#endif +#if CYTHON_COMPILING_IN_LIMITED_API || PY_VERSION_HEX < 0x030A00A3 + typedef __Pyx_PySendResult (*__Pyx_pyiter_sendfunc)(PyObject *iter, PyObject *value, PyObject **result); +#else + #define __Pyx_pyiter_sendfunc sendfunc +#endif +#if !CYTHON_USE_AM_SEND +#define __PYX_HAS_PY_AM_SEND 0 +#elif __PYX_LIMITED_VERSION_HEX >= 0x030A0000 +#define __PYX_HAS_PY_AM_SEND 1 +#else +#define __PYX_HAS_PY_AM_SEND 2 // our own backported implementation +#endif +#if __PYX_HAS_PY_AM_SEND < 2 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods +#else + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + __Pyx_pyiter_sendfunc am_send; + } __Pyx_PyAsyncMethodsStruct; + #define __Pyx_SlotTpAsAsync(s) ((PyAsyncMethods*)(s)) +#endif +#if CYTHON_USE_AM_SEND && PY_VERSION_HEX < 0x030A00F0 + #define __Pyx_TPFLAGS_HAVE_AM_SEND (1UL << 21) +#else + #define __Pyx_TPFLAGS_HAVE_AM_SEND (0) +#endif +#if PY_VERSION_HEX >= 0x03090000 +#define __Pyx_PyInterpreterState_Get() PyInterpreterState_Get() +#else +#define __Pyx_PyInterpreterState_Get() PyThreadState_Get()->interp +#endif +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030A0000 +#ifdef __cplusplus +extern "C" +#endif +PyAPI_FUNC(void *) PyMem_Calloc(size_t nelem, size_t elsize); +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static int __Pyx_init_co_variable(PyObject *inspect, const char* name, int *write_to) { + int value; + PyObject *py_value = PyObject_GetAttrString(inspect, name); + if (!py_value) return 0; + value = (int) PyLong_AsLong(py_value); + Py_DECREF(py_value); + *write_to = value; + return value != -1 || !PyErr_Occurred(); +} +static int __Pyx_init_co_variables(void) { + PyObject *inspect; + int result; + inspect = PyImport_ImportModule("inspect"); + result = +#if !defined(CO_OPTIMIZED) + __Pyx_init_co_variable(inspect, "CO_OPTIMIZED", &CO_OPTIMIZED) && +#endif +#if !defined(CO_NEWLOCALS) + __Pyx_init_co_variable(inspect, "CO_NEWLOCALS", &CO_NEWLOCALS) && +#endif +#if !defined(CO_VARARGS) + __Pyx_init_co_variable(inspect, "CO_VARARGS", &CO_VARARGS) && +#endif +#if !defined(CO_VARKEYWORDS) + __Pyx_init_co_variable(inspect, "CO_VARKEYWORDS", &CO_VARKEYWORDS) && +#endif +#if !defined(CO_ASYNC_GENERATOR) + __Pyx_init_co_variable(inspect, "CO_ASYNC_GENERATOR", &CO_ASYNC_GENERATOR) && +#endif +#if !defined(CO_GENERATOR) + __Pyx_init_co_variable(inspect, "CO_GENERATOR", &CO_GENERATOR) && +#endif +#if !defined(CO_COROUTINE) + __Pyx_init_co_variable(inspect, "CO_COROUTINE", &CO_COROUTINE) && +#endif + 1; + Py_DECREF(inspect); + return result ? 0 : -1; +} +#else +static int __Pyx_init_co_variables(void) { + return 0; // It's a limited API-only feature +} +#endif + +/* MathInitCode */ +#if defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS) + #ifndef _USE_MATH_DEFINES + #define _USE_MATH_DEFINES + #endif +#endif +#include +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#ifndef CYTHON_CLINE_IN_TRACEBACK_RUNTIME +#define CYTHON_CLINE_IN_TRACEBACK_RUNTIME 0 +#endif +#ifndef CYTHON_CLINE_IN_TRACEBACK +#define CYTHON_CLINE_IN_TRACEBACK CYTHON_CLINE_IN_TRACEBACK_RUNTIME +#endif +#if CYTHON_CLINE_IN_TRACEBACK +#define __PYX_MARK_ERR_POS(f_index, lineno) { __pyx_filename = __pyx_f[f_index]; (void) __pyx_filename; __pyx_lineno = lineno; (void) __pyx_lineno; __pyx_clineno = __LINE__; (void) __pyx_clineno; } +#else +#define __PYX_MARK_ERR_POS(f_index, lineno) { __pyx_filename = __pyx_f[f_index]; (void) __pyx_filename; __pyx_lineno = lineno; (void) __pyx_lineno; (void) __pyx_clineno; } +#endif +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifdef CYTHON_EXTERN_C + #undef __PYX_EXTERN_C + #define __PYX_EXTERN_C CYTHON_EXTERN_C +#elif defined(__PYX_EXTERN_C) + #ifdef _MSC_VER + #pragma message ("Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead.") + #else + #warning Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead. + #endif +#else + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__fontTools__misc__bezierTools +#define __PYX_HAVE_API__fontTools__misc__bezierTools +/* Early includes */ +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s); +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char*); +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyByteArray_AsString(s) PyByteArray_AS_STRING(s) +#else + #define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AsString(s)) + #define __Pyx_PyByteArray_AsString(s) PyByteArray_AsString(s) +#endif +#define __Pyx_PyObject_AsWritableString(s) ((char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +#define __Pyx_PyUnicode_FromOrdinal(o) PyUnicode_FromOrdinal((int)o) +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +static CYTHON_INLINE PyObject *__Pyx_NewRef(PyObject *obj) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030a0000 || defined(Py_NewRef) + return Py_NewRef(obj); +#else + Py_INCREF(obj); + return obj; +#endif +} +static CYTHON_INLINE PyObject *__Pyx_XNewRef(PyObject *obj) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030a0000 || defined(Py_XNewRef) + return Py_XNewRef(obj); +#else + Py_XINCREF(obj); + return obj; +#endif +} +static CYTHON_INLINE PyObject *__Pyx_Owned_Py_None(int b); +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_Long(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyLong_FromSize_t(size_t); +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*); +#if CYTHON_ASSUME_SAFE_MACROS +#define __Pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#define __Pyx_PyFloat_AS_DOUBLE(x) PyFloat_AS_DOUBLE(x) +#else +#define __Pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#define __Pyx_PyFloat_AS_DOUBLE(x) PyFloat_AsDouble(x) +#endif +#define __Pyx_PyFloat_AsFloat(x) ((float) __Pyx_PyFloat_AsDouble(x)) +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_VERSION_HEX >= 0x030C00A7 + #ifndef _PyLong_SIGN_MASK + #define _PyLong_SIGN_MASK 3 + #endif + #ifndef _PyLong_NON_SIZE_BITS + #define _PyLong_NON_SIZE_BITS 3 + #endif + #define __Pyx_PyLong_Sign(x) (((PyLongObject*)x)->long_value.lv_tag & _PyLong_SIGN_MASK) + #define __Pyx_PyLong_IsNeg(x) ((__Pyx_PyLong_Sign(x) & 2) != 0) + #define __Pyx_PyLong_IsNonNeg(x) (!__Pyx_PyLong_IsNeg(x)) + #define __Pyx_PyLong_IsZero(x) (__Pyx_PyLong_Sign(x) & 1) + #define __Pyx_PyLong_IsPos(x) (__Pyx_PyLong_Sign(x) == 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) (__Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) ((Py_ssize_t) (((PyLongObject*)x)->long_value.lv_tag >> _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_SignedDigitCount(x)\ + ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * __Pyx_PyLong_DigitCount(x)) + #if defined(PyUnstable_Long_IsCompact) && defined(PyUnstable_Long_CompactValue) + #define __Pyx_PyLong_IsCompact(x) PyUnstable_Long_IsCompact((PyLongObject*) x) + #define __Pyx_PyLong_CompactValue(x) PyUnstable_Long_CompactValue((PyLongObject*) x) + #else + #define __Pyx_PyLong_IsCompact(x) (((PyLongObject*)x)->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_CompactValue(x) ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * (Py_ssize_t) __Pyx_PyLong_Digits(x)[0]) + #endif + typedef Py_ssize_t __Pyx_compact_pylong; + typedef size_t __Pyx_compact_upylong; + #else + #define __Pyx_PyLong_IsNeg(x) (Py_SIZE(x) < 0) + #define __Pyx_PyLong_IsNonNeg(x) (Py_SIZE(x) >= 0) + #define __Pyx_PyLong_IsZero(x) (Py_SIZE(x) == 0) + #define __Pyx_PyLong_IsPos(x) (Py_SIZE(x) > 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) ((Py_SIZE(x) == 0) ? 0 : __Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) __Pyx_sst_abs(Py_SIZE(x)) + #define __Pyx_PyLong_SignedDigitCount(x) Py_SIZE(x) + #define __Pyx_PyLong_IsCompact(x) (Py_SIZE(x) == 0 || Py_SIZE(x) == 1 || Py_SIZE(x) == -1) + #define __Pyx_PyLong_CompactValue(x)\ + ((Py_SIZE(x) == 0) ? (sdigit) 0 : ((Py_SIZE(x) < 0) ? -(sdigit)__Pyx_PyLong_Digits(x)[0] : (sdigit)__Pyx_PyLong_Digits(x)[0])) + typedef sdigit __Pyx_compact_pylong; + typedef digit __Pyx_compact_upylong; + #endif + #if PY_VERSION_HEX >= 0x030C00A5 + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->long_value.ob_digit) + #else + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->ob_digit) + #endif +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 + #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#elif __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeASCII(c_str, size, NULL) +#else + #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +/* PretendToInitialize */ +#ifdef __cplusplus +#if __cplusplus > 201103L +#include +#endif +template +static void __Pyx_pretend_to_initialize(T* ptr) { +#if __cplusplus > 201103L + if ((std::is_trivially_default_constructible::value)) +#endif + *ptr = T(); + (void)ptr; +} +#else +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } +#endif + + +#if !CYTHON_USE_MODULE_STATE +static PyObject *__pyx_m = NULL; +#endif +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * const __pyx_cfilenm = __FILE__; +static const char *__pyx_filename; + +/* Header.proto */ +#if !defined(CYTHON_CCOMPLEX) + #if defined(__cplusplus) + #define CYTHON_CCOMPLEX 1 + #elif (defined(_Complex_I) && !defined(_MSC_VER)) || ((defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_COMPLEX__) && !defined(_MSC_VER)) + #define CYTHON_CCOMPLEX 1 + #else + #define CYTHON_CCOMPLEX 0 + #endif +#endif +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #include + #else + #include + #endif +#endif +#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__) + #undef _Complex_I + #define _Complex_I 1.0fj +#endif + +/* #### Code section: filename_table ### */ + +static const char* const __pyx_f[] = { + "Lib/fontTools/misc/bezierTools.py", +}; +/* #### Code section: utility_code_proto_before_types ### */ +/* Atomics.proto (used by UnpackUnboundCMethod) */ +#include +#ifndef CYTHON_ATOMICS + #define CYTHON_ATOMICS 1 +#endif +#define __PYX_CYTHON_ATOMICS_ENABLED() CYTHON_ATOMICS +#define __PYX_GET_CYTHON_COMPILING_IN_CPYTHON_FREETHREADING() CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __pyx_atomic_int_type int +#define __pyx_nonatomic_int_type int +#if CYTHON_ATOMICS && (defined(__STDC_VERSION__) &&\ + (__STDC_VERSION__ >= 201112L) &&\ + !defined(__STDC_NO_ATOMICS__)) + #include +#elif CYTHON_ATOMICS && (defined(__cplusplus) && (\ + (__cplusplus >= 201103L) ||\ + (defined(_MSC_VER) && _MSC_VER >= 1700))) + #include +#endif +#if CYTHON_ATOMICS && (defined(__STDC_VERSION__) &&\ + (__STDC_VERSION__ >= 201112L) &&\ + !defined(__STDC_NO_ATOMICS__) &&\ + ATOMIC_INT_LOCK_FREE == 2) + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type atomic_int + #define __pyx_atomic_ptr_type atomic_uintptr_t + #define __pyx_nonatomic_ptr_type uintptr_t + #define __pyx_atomic_incr_relaxed(value) atomic_fetch_add_explicit(value, 1, memory_order_relaxed) + #define __pyx_atomic_incr_acq_rel(value) atomic_fetch_add_explicit(value, 1, memory_order_acq_rel) + #define __pyx_atomic_decr_acq_rel(value) atomic_fetch_sub_explicit(value, 1, memory_order_acq_rel) + #define __pyx_atomic_sub(value, arg) atomic_fetch_sub(value, arg) + #define __pyx_atomic_int_cmp_exchange(value, expected, desired) atomic_compare_exchange_strong(value, expected, desired) + #define __pyx_atomic_load(value) atomic_load(value) + #define __pyx_atomic_store(value, new_value) atomic_store(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) atomic_load_explicit(value, memory_order_relaxed) + #define __pyx_atomic_pointer_load_acquire(value) atomic_load_explicit(value, memory_order_acquire) + #define __pyx_atomic_pointer_exchange(value, new_value) atomic_exchange(value, (__pyx_nonatomic_ptr_type)new_value) + #define __pyx_atomic_pointer_cmp_exchange(value, expected, desired) atomic_compare_exchange_strong(value, expected, desired) + #if defined(__PYX_DEBUG_ATOMICS) && defined(_MSC_VER) + #pragma message ("Using standard C atomics") + #elif defined(__PYX_DEBUG_ATOMICS) + #warning "Using standard C atomics" + #endif +#elif CYTHON_ATOMICS && (defined(__cplusplus) && (\ + (__cplusplus >= 201103L) ||\ +\ + (defined(_MSC_VER) && _MSC_VER >= 1700)) &&\ + ATOMIC_INT_LOCK_FREE == 2) + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type std::atomic_int + #define __pyx_atomic_ptr_type std::atomic_uintptr_t + #define __pyx_nonatomic_ptr_type uintptr_t + #define __pyx_atomic_incr_relaxed(value) std::atomic_fetch_add_explicit(value, 1, std::memory_order_relaxed) + #define __pyx_atomic_incr_acq_rel(value) std::atomic_fetch_add_explicit(value, 1, std::memory_order_acq_rel) + #define __pyx_atomic_decr_acq_rel(value) std::atomic_fetch_sub_explicit(value, 1, std::memory_order_acq_rel) + #define __pyx_atomic_sub(value, arg) std::atomic_fetch_sub(value, arg) + #define __pyx_atomic_int_cmp_exchange(value, expected, desired) std::atomic_compare_exchange_strong(value, expected, desired) + #define __pyx_atomic_load(value) std::atomic_load(value) + #define __pyx_atomic_store(value, new_value) std::atomic_store(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) std::atomic_load_explicit(value, std::memory_order_relaxed) + #define __pyx_atomic_pointer_load_acquire(value) std::atomic_load_explicit(value, std::memory_order_acquire) + #define __pyx_atomic_pointer_exchange(value, new_value) std::atomic_exchange(value, (__pyx_nonatomic_ptr_type)new_value) + #define __pyx_atomic_pointer_cmp_exchange(value, expected, desired) std::atomic_compare_exchange_strong(value, expected, desired) + #if defined(__PYX_DEBUG_ATOMICS) && defined(_MSC_VER) + #pragma message ("Using standard C++ atomics") + #elif defined(__PYX_DEBUG_ATOMICS) + #warning "Using standard C++ atomics" + #endif +#elif CYTHON_ATOMICS && (__GNUC__ >= 5 || (__GNUC__ == 4 &&\ + (__GNUC_MINOR__ > 1 ||\ + (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ >= 2)))) + #define __pyx_atomic_ptr_type void* + #define __pyx_nonatomic_ptr_type void* + #define __pyx_atomic_incr_relaxed(value) __sync_fetch_and_add(value, 1) + #define __pyx_atomic_incr_acq_rel(value) __sync_fetch_and_add(value, 1) + #define __pyx_atomic_decr_acq_rel(value) __sync_fetch_and_sub(value, 1) + #define __pyx_atomic_sub(value, arg) __sync_fetch_and_sub(value, arg) + static CYTHON_INLINE int __pyx_atomic_int_cmp_exchange(__pyx_atomic_int_type* value, __pyx_nonatomic_int_type* expected, __pyx_nonatomic_int_type desired) { + __pyx_nonatomic_int_type old = __sync_val_compare_and_swap(value, *expected, desired); + int result = old == *expected; + *expected = old; + return result; + } + #define __pyx_atomic_load(value) __sync_fetch_and_add(value, 0) + #define __pyx_atomic_store(value, new_value) __sync_lock_test_and_set(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) __sync_fetch_and_add(value, 0) + #define __pyx_atomic_pointer_load_acquire(value) __sync_fetch_and_add(value, 0) + #define __pyx_atomic_pointer_exchange(value, new_value) __sync_lock_test_and_set(value, (__pyx_atomic_ptr_type)new_value) + static CYTHON_INLINE int __pyx_atomic_pointer_cmp_exchange(__pyx_atomic_ptr_type* value, __pyx_nonatomic_ptr_type* expected, __pyx_nonatomic_ptr_type desired) { + __pyx_nonatomic_ptr_type old = __sync_val_compare_and_swap(value, *expected, desired); + int result = old == *expected; + *expected = old; + return result; + } + #ifdef __PYX_DEBUG_ATOMICS + #warning "Using GNU atomics" + #endif +#elif CYTHON_ATOMICS && defined(_MSC_VER) + #include + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type long + #define __pyx_atomic_ptr_type void* + #undef __pyx_nonatomic_int_type + #define __pyx_nonatomic_int_type long + #define __pyx_nonatomic_ptr_type void* + #pragma intrinsic (_InterlockedExchangeAdd, _InterlockedExchange, _InterlockedCompareExchange, _InterlockedCompareExchangePointer, _InterlockedExchangePointer) + #define __pyx_atomic_incr_relaxed(value) _InterlockedExchangeAdd(value, 1) + #define __pyx_atomic_incr_acq_rel(value) _InterlockedExchangeAdd(value, 1) + #define __pyx_atomic_decr_acq_rel(value) _InterlockedExchangeAdd(value, -1) + #define __pyx_atomic_sub(value, arg) _InterlockedExchangeAdd(value, -arg) + static CYTHON_INLINE int __pyx_atomic_int_cmp_exchange(__pyx_atomic_int_type* value, __pyx_nonatomic_int_type* expected, __pyx_nonatomic_int_type desired) { + __pyx_nonatomic_int_type old = _InterlockedCompareExchange(value, desired, *expected); + int result = old == *expected; + *expected = old; + return result; + } + #define __pyx_atomic_load(value) _InterlockedExchangeAdd(value, 0) + #define __pyx_atomic_store(value, new_value) _InterlockedExchange(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) *(void * volatile *)value + #define __pyx_atomic_pointer_load_acquire(value) _InterlockedCompareExchangePointer(value, 0, 0) + #define __pyx_atomic_pointer_exchange(value, new_value) _InterlockedExchangePointer(value, (__pyx_atomic_ptr_type)new_value) + static CYTHON_INLINE int __pyx_atomic_pointer_cmp_exchange(__pyx_atomic_ptr_type* value, __pyx_nonatomic_ptr_type* expected, __pyx_nonatomic_ptr_type desired) { + __pyx_atomic_ptr_type old = _InterlockedCompareExchangePointer(value, desired, *expected); + int result = old == *expected; + *expected = old; + return result; + } + #ifdef __PYX_DEBUG_ATOMICS + #pragma message ("Using MSVC atomics") + #endif +#else + #undef CYTHON_ATOMICS + #define CYTHON_ATOMICS 0 + #ifdef __PYX_DEBUG_ATOMICS + #warning "Not using atomics" + #endif +#endif + +/* CriticalSectionsDefinition.proto (used by CriticalSections) */ +#if !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __Pyx_PyCriticalSection void* +#define __Pyx_PyCriticalSection2 void* +#define __Pyx_PyCriticalSection_End(cs) +#define __Pyx_PyCriticalSection2_End(cs) +#else +#define __Pyx_PyCriticalSection PyCriticalSection +#define __Pyx_PyCriticalSection2 PyCriticalSection2 +#define __Pyx_PyCriticalSection_End PyCriticalSection_End +#define __Pyx_PyCriticalSection2_End PyCriticalSection2_End +#endif + +/* CriticalSections.proto (used by ParseKeywordsImpl) */ +#if !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __Pyx_PyCriticalSection_Begin(cs, arg) (void)(cs) +#define __Pyx_PyCriticalSection2_Begin(cs, arg1, arg2) (void)(cs) +#else +#define __Pyx_PyCriticalSection_Begin PyCriticalSection_Begin +#define __Pyx_PyCriticalSection2_Begin PyCriticalSection2_Begin +#endif +#if PY_VERSION_HEX < 0x030d0000 || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_BEGIN_CRITICAL_SECTION(o) { +#define __Pyx_END_CRITICAL_SECTION() } +#else +#define __Pyx_BEGIN_CRITICAL_SECTION Py_BEGIN_CRITICAL_SECTION +#define __Pyx_END_CRITICAL_SECTION Py_END_CRITICAL_SECTION +#endif + +/* IncludeStructmemberH.proto (used by FixUpExtensionType) */ +#include + +/* #### Code section: numeric_typedefs ### */ +/* #### Code section: complex_type_declarations ### */ +/* Declarations.proto */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #ifdef __cplusplus + typedef ::std::complex< double > __pyx_t_double_complex; + #else + typedef double _Complex __pyx_t_double_complex; + #endif +#else + typedef struct { double real, imag; } __pyx_t_double_complex; +#endif +static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); + +/* #### Code section: type_declarations ### */ + +/*--- Type declarations ---*/ +struct __pyx_defaults; +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr; +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr; +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC; +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC; +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr; +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t; +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr; +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr; + +/* "fontTools/misc/bezierTools.py":815 + * + * + * def solveQuadratic(a, b, c, sqrt=sqrt): # <<<<<<<<<<<<<< + * """Solve a quadratic equation. + * +*/ +struct __pyx_defaults { + PyObject_HEAD + PyObject *arg0; +}; + + +/* "fontTools/misc/bezierTools.py":546 + * a[isHorizontal], b[isHorizontal], c[isHorizontal] - where + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) # <<<<<<<<<<<<<< + * if not solutions: + * return [(pt1, pt2, pt3)] +*/ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr { + PyObject_HEAD + PyObject *__pyx_genexpr_arg_0; + PyObject *__pyx_v_t; +}; + + +/* "fontTools/misc/bezierTools.py":583 + * a[isHorizontal], b[isHorizontal], c[isHorizontal], d[isHorizontal] - where + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) # <<<<<<<<<<<<<< + * if not solutions: + * return [(pt1, pt2, pt3, pt4)] +*/ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr { + PyObject_HEAD + PyObject *__pyx_genexpr_arg_0; + PyObject *__pyx_v_t; +}; + + +/* "fontTools/misc/bezierTools.py":644 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * pt1=cython.complex, + * pt2=cython.complex, +*/ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC { + PyObject_HEAD + __pyx_t_double_complex __pyx_v_a; + __pyx_t_double_complex __pyx_v_b; + __pyx_t_double_complex __pyx_v_c; + __pyx_t_double_complex __pyx_v_d; + __pyx_t_double_complex __pyx_v_pt1; + __pyx_t_double_complex __pyx_v_pt2; + __pyx_t_double_complex __pyx_v_pt3; + __pyx_t_double_complex __pyx_v_pt4; + PyObject *__pyx_v_ts; +}; + + +/* "fontTools/misc/bezierTools.py":770 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * a=cython.complex, + * b=cython.complex, +*/ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC { + PyObject_HEAD + __pyx_t_double_complex __pyx_v_a; + __pyx_t_double_complex __pyx_v_a1; + __pyx_t_double_complex __pyx_v_b; + __pyx_t_double_complex __pyx_v_b1; + __pyx_t_double_complex __pyx_v_c; + __pyx_t_double_complex __pyx_v_c1; + __pyx_t_double_complex __pyx_v_d; + __pyx_t_double_complex __pyx_v_d1; + double __pyx_v_delta; + double __pyx_v_delta_2; + double __pyx_v_delta_3; + PyObject *__pyx_v_i; + PyObject *__pyx_v_pt1; + PyObject *__pyx_v_pt2; + PyObject *__pyx_v_pt3; + PyObject *__pyx_v_pt4; + double __pyx_v_t1; + double __pyx_v_t1_2; + double __pyx_v_t1_3; + double __pyx_v_t2; + PyObject *__pyx_v_ts; + PyObject *__pyx_t_0; + PyObject *(*__pyx_t_1)(PyObject *); +}; + + +/* "fontTools/misc/bezierTools.py":1252 + * else: + * raise ValueError("Unknown curve degree") + * return sorted(i for i in intersections if 0.0 <= i <= 1) # <<<<<<<<<<<<<< + * + * +*/ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr { + PyObject_HEAD + PyObject *__pyx_genexpr_arg_0; + PyObject *__pyx_v_i; +}; + + +/* "fontTools/misc/bezierTools.py":1313 + * + * + * def _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * curve1, curve2, precision=1e-3, range1=None, range2=None + * ): +*/ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t { + PyObject_HEAD + PyObject *__pyx_v_precision; +}; + + +/* "fontTools/misc/bezierTools.py":1382 + * def _is_linelike(segment): + * maybeline = _alignment_transformation(segment).transformPoints(segment) + * return all(math.isclose(p[1], 0.0) for p in maybeline) # <<<<<<<<<<<<<< + * + * +*/ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr { + PyObject_HEAD + PyObject *__pyx_genexpr_arg_0; + PyObject *__pyx_v_p; +}; + + +/* "fontTools/misc/bezierTools.py":1485 + * return "%g" % obj + * else: + * return "(%s)" % ", ".join(_segmentrepr(x) for x in it) # <<<<<<<<<<<<<< + * + * +*/ +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr { + PyObject_HEAD + PyObject *__pyx_genexpr_arg_0; + PyObject *__pyx_v_x; +}; + +/* #### Code section: utility_code_proto ### */ + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, Py_ssize_t); + void (*DECREF)(void*, PyObject*, Py_ssize_t); + void (*GOTREF)(void*, PyObject*, Py_ssize_t); + void (*GIVEREF)(void*, PyObject*, Py_ssize_t); + void* (*SetupContext)(const char*, Py_ssize_t, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_XINCREF(r) do { if((r) == NULL); else {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) == NULL); else {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) == NULL); else {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) == NULL); else {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContextNogil() + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_Py_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; Py_XDECREF(tmp);\ + } while (0) +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* PyErrExceptionMatches.proto (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* PyThreadStateGet.proto (used by PyErrFetchRestore) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#if PY_VERSION_HEX >= 0x030C00A6 +#define __Pyx_PyErr_Occurred() (__pyx_tstate->current_exception != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->current_exception ? (PyObject*) Py_TYPE(__pyx_tstate->current_exception) : (PyObject*) NULL) +#else +#define __Pyx_PyErr_Occurred() (__pyx_tstate->curexc_type != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->curexc_type) +#endif +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() (PyErr_Occurred() != NULL) +#define __Pyx_PyErr_CurrentExceptionType() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A6 +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* PyObjectGetAttrStr.proto (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* PyObjectGetAttrStrNoError.proto (used by GetBuiltinName) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* TupleAndListFromArray.proto (used by fastcall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n); +#endif +#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n); +#endif + +/* IncludeStringH.proto (used by BytesEquals) */ +#include + +/* BytesEquals.proto (used by UnicodeEquals) */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); + +/* UnicodeEquals.proto (used by fastcall) */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); + +/* fastcall.proto */ +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_ArgRef_VARARGS(args, i) __Pyx_PySequence_ITEM(args, i) +#elif CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_ArgRef_VARARGS(args, i) __Pyx_NewRef(__Pyx_PyTuple_GET_ITEM(args, i)) +#else + #define __Pyx_ArgRef_VARARGS(args, i) __Pyx_XNewRef(PyTuple_GetItem(args, i)) +#endif +#define __Pyx_NumKwargs_VARARGS(kwds) PyDict_Size(kwds) +#define __Pyx_KwValues_VARARGS(args, nargs) NULL +#define __Pyx_GetKwValue_VARARGS(kw, kwvalues, s) __Pyx_PyDict_GetItemStrWithError(kw, s) +#define __Pyx_KwargsAsDict_VARARGS(kw, kwvalues) PyDict_Copy(kw) +#if CYTHON_METH_FASTCALL + #define __Pyx_ArgRef_FASTCALL(args, i) __Pyx_NewRef(args[i]) + #define __Pyx_NumKwargs_FASTCALL(kwds) __Pyx_PyTuple_GET_SIZE(kwds) + #define __Pyx_KwValues_FASTCALL(args, nargs) ((args) + (nargs)) + static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 || CYTHON_COMPILING_IN_LIMITED_API + CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues); + #else + #define __Pyx_KwargsAsDict_FASTCALL(kw, kwvalues) _PyStack_AsDict(kwvalues, kw) + #endif +#else + #define __Pyx_ArgRef_FASTCALL __Pyx_ArgRef_VARARGS + #define __Pyx_NumKwargs_FASTCALL __Pyx_NumKwargs_VARARGS + #define __Pyx_KwValues_FASTCALL __Pyx_KwValues_VARARGS + #define __Pyx_GetKwValue_FASTCALL __Pyx_GetKwValue_VARARGS + #define __Pyx_KwargsAsDict_FASTCALL __Pyx_KwargsAsDict_VARARGS +#endif +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) PyTuple_GetSlice(args, start, stop) +#if CYTHON_METH_FASTCALL || (CYTHON_COMPILING_IN_CPYTHON && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) __Pyx_PyTuple_FromArray(args + start, stop - start) +#else +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) PyTuple_GetSlice(args, start, stop) +#endif + +/* py_dict_items.proto (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d); + +/* CallCFunction.proto (used by CallUnboundCMethod0) */ +#define __Pyx_CallCFunction(cfunc, self, args)\ + ((PyCFunction)(void(*)(void))(cfunc)->func)(self, args) +#define __Pyx_CallCFunctionWithKeywords(cfunc, self, args, kwargs)\ + ((PyCFunctionWithKeywords)(void(*)(void))(cfunc)->func)(self, args, kwargs) +#define __Pyx_CallCFunctionFast(cfunc, self, args, nargs)\ + ((__Pyx_PyCFunctionFast)(void(*)(void))(PyCFunction)(cfunc)->func)(self, args, nargs) +#define __Pyx_CallCFunctionFastWithKeywords(cfunc, self, args, nargs, kwnames)\ + ((__Pyx_PyCFunctionFastWithKeywords)(void(*)(void))(PyCFunction)(cfunc)->func)(self, args, nargs, kwnames) + +/* PyObjectCall.proto (used by PyObjectFastCall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* PyObjectCallMethO.proto (used by PyObjectFastCall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectFastCall.proto (used by PyObjectCallOneArg) */ +#define __Pyx_PyObject_FastCall(func, args, nargs) __Pyx_PyObject_FastCallDict(func, args, (size_t)(nargs), NULL) +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject * const*args, size_t nargs, PyObject *kwargs); + +/* PyObjectCallOneArg.proto (used by CallUnboundCMethod0) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* UnpackUnboundCMethod.proto (used by CallUnboundCMethod0) */ +typedef struct { + PyObject *type; + PyObject **method_name; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && CYTHON_ATOMICS + __pyx_atomic_int_type initialized; +#endif + PyCFunction func; + PyObject *method; + int flag; +} __Pyx_CachedCFunction; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +static CYTHON_INLINE int __Pyx_CachedCFunction_GetAndSetInitializing(__Pyx_CachedCFunction *cfunc) { +#if !CYTHON_ATOMICS + return 1; +#else + __pyx_nonatomic_int_type expected = 0; + if (__pyx_atomic_int_cmp_exchange(&cfunc->initialized, &expected, 1)) { + return 0; + } + return expected; +#endif +} +static CYTHON_INLINE void __Pyx_CachedCFunction_SetFinishedInitializing(__Pyx_CachedCFunction *cfunc) { +#if CYTHON_ATOMICS + __pyx_atomic_store(&cfunc->initialized, 2); +#endif +} +#else +#define __Pyx_CachedCFunction_GetAndSetInitializing(cfunc) 2 +#define __Pyx_CachedCFunction_SetFinishedInitializing(cfunc) +#endif + +/* CallUnboundCMethod0.proto */ +CYTHON_UNUSED +static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self); +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self); +#else +#define __Pyx_CallUnboundCMethod0(cfunc, self) __Pyx__CallUnboundCMethod0(cfunc, self) +#endif + +/* py_dict_values.proto (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Values(PyObject* d); + +/* OwnedDictNext.proto (used by ParseKeywordsImpl) */ +#if CYTHON_AVOID_BORROWED_REFS +static int __Pyx_PyDict_NextRef(PyObject *p, PyObject **ppos, PyObject **pkey, PyObject **pvalue); +#else +CYTHON_INLINE +static int __Pyx_PyDict_NextRef(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue); +#endif + +/* RaiseDoubleKeywords.proto (used by ParseKeywordsImpl) */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywordsImpl.export */ +static int __Pyx_ParseKeywordsTuple( + PyObject *kwds, + PyObject * const *kwvalues, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs +); +static int __Pyx_ParseKeywordDictToDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name +); +static int __Pyx_ParseKeywordDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs +); + +/* CallUnboundCMethod2.proto */ +CYTHON_UNUSED +static PyObject* __Pyx__CallUnboundCMethod2(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg1, PyObject* arg2); +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject *__Pyx_CallUnboundCMethod2(__Pyx_CachedCFunction *cfunc, PyObject *self, PyObject *arg1, PyObject *arg2); +#else +#define __Pyx_CallUnboundCMethod2(cfunc, self, arg1, arg2) __Pyx__CallUnboundCMethod2(cfunc, self, arg1, arg2) +#endif + +/* ParseKeywords.proto */ +static CYTHON_INLINE int __Pyx_ParseKeywords( + PyObject *kwds, PyObject *const *kwvalues, PyObject ** const argnames[], + PyObject *kwds2, PyObject *values[], + Py_ssize_t num_pos_args, Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs +); + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* PyDictVersioning.proto (used by GetModuleGlobalName) */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __Pyx_XNewRef(__pyx_dict_cached_value);\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* GetModuleGlobalName.proto */ +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) do {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_mstate_global->__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +#define __Pyx_GetModuleGlobalNameUncached(var, name) do {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif + +/* PyLongBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static CYTHON_INLINE PyObject* __Pyx_PyLong_MultiplyCObj(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyLong_MultiplyCObj(op1, op2, intval, inplace, zerodivision_check)\ + (inplace ? PyNumber_InPlaceMultiply(op1, op2) : PyNumber_Multiply(op1, op2)) +#endif + +/* RaiseTooManyValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +/* RaiseNeedMoreValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +/* IterFinish.proto */ +static CYTHON_INLINE int __Pyx_IterFinish(void); + +/* UnpackItemEndCheck.proto */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); + +/* PyLongBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static CYTHON_INLINE PyObject* __Pyx_PyLong_TrueDivideObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyLong_TrueDivideObjC(op1, op2, intval, inplace, zerodivision_check)\ + (inplace ? PyNumber_InPlaceTrueDivide(op1, op2) : PyNumber_TrueDivide(op1, op2)) +#endif + +/* IncludeStdlibH.proto */ +#include + +/* PyLongCompare.proto */ +static CYTHON_INLINE int __Pyx_PyLong_BoolNeObjC(PyObject *op1, PyObject *op2, long intval, long inplace); + +/* ListAppend.proto */ +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) { + PyListObject* L = (PyListObject*) list; + Py_ssize_t len = Py_SIZE(list); + if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) { + Py_INCREF(x); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + L->ob_item[len] = x; + #else + PyList_SET_ITEM(list, len, x); + #endif + __Pyx_SET_SIZE(list, len + 1); + return 0; + } + return PyList_Append(list, x); +} +#else +#define __Pyx_PyList_Append(L,x) PyList_Append(L,x) +#endif + +/* ListCompAppend.proto */ +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) { + PyListObject* L = (PyListObject*) list; + Py_ssize_t len = Py_SIZE(list); + if (likely(L->allocated > len)) { + Py_INCREF(x); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + L->ob_item[len] = x; + #else + PyList_SET_ITEM(list, len, x); + #endif + __Pyx_SET_SIZE(list, len + 1); + return 0; + } + return PyList_Append(list, x); +} +#else +#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x) +#endif + +/* GetItemInt.proto */ +#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck, has_gil, unsafe_shared)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck, unsafe_shared) :\ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ + __Pyx_GetItemInt_Generic(o, to_py_func(i)))) +#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck, has_gil, unsafe_shared)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck, unsafe_shared) :\ + (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck, int unsafe_shared); +#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck, has_gil, unsafe_shared)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck, unsafe_shared) :\ + (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck, int unsafe_shared); +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, + int is_list, int wraparound, int boundscheck, int unsafe_shared); + +/* ObjectGetItem.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject *key); +#else +#define __Pyx_PyObject_GetItem(obj, key) PyObject_GetItem(obj, key) +#endif + +/* PyLongCompare.proto */ +static CYTHON_INLINE int __Pyx_PyLong_BoolEqObjC(PyObject *op1, PyObject *op2, long intval, long inplace); + +/* RaiseUnboundLocalError.proto */ +static void __Pyx_RaiseUnboundLocalError(const char *varname); + +/* GetException.proto (used by pep479) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* pep479.proto */ +static void __Pyx_Generator_Replace_StopIteration(int in_async_gen); + +/* SliceObject.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice( + PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop, + PyObject** py_start, PyObject** py_stop, PyObject** py_slice, + int has_cstart, int has_cstop, int wraparound); + +/* ListExtend.proto */ +static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) { +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d00a2 + return PyList_Extend(L, v); +#elif CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 + PyObject* none = _PyList_Extend((PyListObject*)L, v); + if (unlikely(!none)) + return -1; + Py_DECREF(none); + return 0; +#else + return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v); +#endif +} + +/* SetItemInt.proto */ +#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck, has_gil, unsafe_shared)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck, unsafe_shared) :\ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) :\ + __Pyx_SetItemInt_Generic(o, to_py_func(i), v))) +static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v); +static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, + int is_list, int wraparound, int boundscheck, int unsafe_shared); + +/* dict_setdefault.proto (used by FetchCommonType) */ +static CYTHON_INLINE PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value); + +/* LimitedApiGetTypeDict.proto (used by SetItemOnTypeDict) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_GetTypeDict(PyTypeObject *tp); +#endif + +/* SetItemOnTypeDict.proto (used by FixUpExtensionType) */ +static int __Pyx__SetItemOnTypeDict(PyTypeObject *tp, PyObject *k, PyObject *v); +#define __Pyx_SetItemOnTypeDict(tp, k, v) __Pyx__SetItemOnTypeDict((PyTypeObject*)tp, k, v) + +/* FixUpExtensionType.proto (used by FetchCommonType) */ +static CYTHON_INLINE int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type); + +/* AddModuleRef.proto (used by FetchSharedCythonModule) */ +#if ((CYTHON_COMPILING_IN_CPYTHON_FREETHREADING ) ||\ + __PYX_LIMITED_VERSION_HEX < 0x030d0000) + static PyObject *__Pyx_PyImport_AddModuleRef(const char *name); +#else + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#endif + +/* FetchSharedCythonModule.proto (used by FetchCommonType) */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void); + +/* FetchCommonType.proto (used by CommonTypesMetaclass) */ +static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases); + +/* CommonTypesMetaclass.proto (used by CoroutineBase) */ +static int __pyx_CommonTypesMetaclass_init(PyObject *module); +#define __Pyx_CommonTypesMetaclass_USED + +/* RaiseException.export */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* GetTopmostException.proto (used by SaveResetException) */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); +#endif + +/* SaveResetException.proto (used by CoroutineBase) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +#else +#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) +#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) +#endif + +/* SwapException.proto (used by CoroutineBase) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSwap(type, value, tb) __Pyx__ExceptionSwap(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* CallTypeTraverse.proto (used by CoroutineBase) */ +#if !CYTHON_USE_TYPE_SPECS || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x03090000) +#define __Pyx_call_type_traverse(o, always_call, visit, arg) 0 +#else +static int __Pyx_call_type_traverse(PyObject *o, int always_call, visitproc visit, void *arg); +#endif + +/* IterNextPlain.proto (used by CoroutineBase) */ +static CYTHON_INLINE PyObject *__Pyx_PyIter_Next_Plain(PyObject *iterator); +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 +static PyObject *__Pyx_GetBuiltinNext_LimitedAPI(void); +#endif + +/* PyObjectCall2Args.proto (used by PyObjectCallMethod1) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + +/* PyObjectGetMethod.proto (used by PyObjectCallMethod1) */ +#if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))) +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); +#endif + +/* PyObjectCallMethod1.proto (used by CoroutineBase) */ +static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg); + +/* PyObjectCallNoArg.proto (used by CoroutineBase) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); + +/* ReturnWithStopIteration.proto (used by CoroutineBase) */ +static CYTHON_INLINE void __Pyx_ReturnWithStopIteration(PyObject* value, int async, int iternext); + +/* CoroutineBase.proto (used by Generator) */ +struct __pyx_CoroutineObject; +typedef PyObject *(*__pyx_coroutine_body_t)(struct __pyx_CoroutineObject *, PyThreadState *, PyObject *); +#if CYTHON_USE_EXC_INFO_STACK +#define __Pyx_ExcInfoStruct _PyErr_StackItem +#else +typedef struct { + PyObject *exc_type; + PyObject *exc_value; + PyObject *exc_traceback; +} __Pyx_ExcInfoStruct; +#endif +typedef struct __pyx_CoroutineObject { + PyObject_HEAD + __pyx_coroutine_body_t body; + PyObject *closure; + __Pyx_ExcInfoStruct gi_exc_state; +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *gi_weakreflist; +#endif + PyObject *classobj; + PyObject *yieldfrom; + __Pyx_pyiter_sendfunc yieldfrom_am_send; + PyObject *gi_name; + PyObject *gi_qualname; + PyObject *gi_modulename; + PyObject *gi_code; + PyObject *gi_frame; +#if CYTHON_USE_SYS_MONITORING && (CYTHON_PROFILE || CYTHON_TRACE) + PyMonitoringState __pyx_pymonitoring_state[__Pyx_MonitoringEventTypes_CyGen_count]; + uint64_t __pyx_pymonitoring_version; +#endif + int resume_label; + char is_running; +} __pyx_CoroutineObject; +static __pyx_CoroutineObject *__Pyx__Coroutine_New( + PyTypeObject *type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name); +static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit( + __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name); +static CYTHON_INLINE void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *self); +static int __Pyx_Coroutine_clear(PyObject *self); +static __Pyx_PySendResult __Pyx_Coroutine_AmSend(PyObject *self, PyObject *value, PyObject **retval); +static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value); +static __Pyx_PySendResult __Pyx_Coroutine_Close(PyObject *self, PyObject **retval); +static PyObject *__Pyx_Coroutine_Throw(PyObject *gen, PyObject *args); +#if CYTHON_USE_EXC_INFO_STACK +#define __Pyx_Coroutine_SwapException(self) +#define __Pyx_Coroutine_ResetAndClearException(self) __Pyx_Coroutine_ExceptionClear(&(self)->gi_exc_state) +#else +#define __Pyx_Coroutine_SwapException(self) {\ + __Pyx_ExceptionSwap(&(self)->gi_exc_state.exc_type, &(self)->gi_exc_state.exc_value, &(self)->gi_exc_state.exc_traceback);\ + __Pyx_Coroutine_ResetFrameBackpointer(&(self)->gi_exc_state);\ + } +#define __Pyx_Coroutine_ResetAndClearException(self) {\ + __Pyx_ExceptionReset((self)->gi_exc_state.exc_type, (self)->gi_exc_state.exc_value, (self)->gi_exc_state.exc_traceback);\ + (self)->gi_exc_state.exc_type = (self)->gi_exc_state.exc_value = (self)->gi_exc_state.exc_traceback = NULL;\ + } +#endif +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyGen_FetchStopIterationValue(pvalue)\ + __Pyx_PyGen__FetchStopIterationValue(__pyx_tstate, pvalue) +#else +#define __Pyx_PyGen_FetchStopIterationValue(pvalue)\ + __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, pvalue) +#endif +static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *tstate, PyObject **pvalue); +static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state); +static char __Pyx_Coroutine_test_and_set_is_running(__pyx_CoroutineObject *gen); +static void __Pyx_Coroutine_unset_is_running(__pyx_CoroutineObject *gen); +static char __Pyx_Coroutine_get_is_running(__pyx_CoroutineObject *gen); +static PyObject *__Pyx_Coroutine_get_is_running_getter(PyObject *gen, void *closure); +#if __PYX_HAS_PY_AM_SEND == 2 +static void __Pyx_SetBackportTypeAmSend(PyTypeObject *type, __Pyx_PyAsyncMethodsStruct *static_amsend_methods, __Pyx_pyiter_sendfunc am_send); +#endif +static PyObject *__Pyx_Coroutine_fail_reduce_ex(PyObject *self, PyObject *arg); + +/* Generator.proto (used by GeneratorYieldFrom) */ +#define __Pyx_Generator_USED +#define __Pyx_Generator_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_mstate_global->__pyx_GeneratorType) +#define __Pyx_Generator_New(body, code, closure, name, qualname, module_name)\ + __Pyx__Coroutine_New(__pyx_mstate_global->__pyx_GeneratorType, body, code, closure, name, qualname, module_name) +static PyObject *__Pyx_Generator_Next(PyObject *self); +static int __pyx_Generator_init(PyObject *module); +static CYTHON_INLINE PyObject *__Pyx_Generator_GetInlinedResult(PyObject *self); + +/* GeneratorYieldFrom.proto */ +static CYTHON_INLINE __Pyx_PySendResult __Pyx_Generator_Yield_From(__pyx_CoroutineObject *gen, PyObject *source, PyObject **retval); + +/* append.proto */ +static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x); + +/* PyRange_Check.proto */ +#if CYTHON_COMPILING_IN_PYPY && !defined(PyRange_Check) + #define PyRange_Check(obj) __Pyx_TypeCheck((obj), &PyRange_Type) +#endif + +/* PyLongBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static CYTHON_INLINE PyObject* __Pyx_PyLong_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyLong_AddObjC(op1, op2, intval, inplace, zerodivision_check)\ + (inplace ? PyNumber_InPlaceAdd(op1, op2) : PyNumber_Add(op1, op2)) +#endif + +/* py_abs.proto */ +#if CYTHON_USE_PYLONG_INTERNALS +static PyObject *__Pyx_PyLong_AbsNeg(PyObject *num); +#define __Pyx_PyNumber_Absolute(x)\ + ((likely(PyLong_CheckExact(x))) ?\ + (likely(__Pyx_PyLong_IsNonNeg(x)) ? __Pyx_NewRef(x) : __Pyx_PyLong_AbsNeg(x)) :\ + PyNumber_Absolute(x)) +#else +#define __Pyx_PyNumber_Absolute(x) PyNumber_Absolute(x) +#endif + +/* PyFloatBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyFloat_TrueDivideObjC(PyObject *op1, PyObject *op2, double floatval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyFloat_TrueDivideObjC(op1, op2, floatval, inplace, zerodivision_check)\ + (inplace ? PyNumber_InPlaceTrueDivide(op1, op2) : PyNumber_TrueDivide(op1, op2)) +#endif + +/* pybytes_as_double.proto (used by pynumber_float) */ +static double __Pyx_SlowPyString_AsDouble(PyObject *obj); +static double __Pyx__PyBytes_AsDouble(PyObject *obj, const char* start, Py_ssize_t length); +static CYTHON_INLINE double __Pyx_PyBytes_AsDouble(PyObject *obj) { + char* as_c_string; + Py_ssize_t size; +#if CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE + as_c_string = PyBytes_AS_STRING(obj); + size = PyBytes_GET_SIZE(obj); +#else + if (PyBytes_AsStringAndSize(obj, &as_c_string, &size) < 0) { + return (double)-1; + } +#endif + return __Pyx__PyBytes_AsDouble(obj, as_c_string, size); +} +static CYTHON_INLINE double __Pyx_PyByteArray_AsDouble(PyObject *obj) { + char* as_c_string; + Py_ssize_t size; +#if CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE + as_c_string = PyByteArray_AS_STRING(obj); + size = PyByteArray_GET_SIZE(obj); +#else + as_c_string = PyByteArray_AsString(obj); + if (as_c_string == NULL) { + return (double)-1; + } + size = PyByteArray_Size(obj); +#endif + return __Pyx__PyBytes_AsDouble(obj, as_c_string, size); +} + +/* pyunicode_as_double.proto (used by pynumber_float) */ +#if !CYTHON_COMPILING_IN_PYPY && CYTHON_ASSUME_SAFE_MACROS +static const char* __Pyx__PyUnicode_AsDouble_Copy(const void* data, const int kind, char* buffer, Py_ssize_t start, Py_ssize_t end) { + int last_was_punctuation; + Py_ssize_t i; + last_was_punctuation = 1; + for (i=start; i <= end; i++) { + Py_UCS4 chr = PyUnicode_READ(kind, data, i); + int is_punctuation = (chr == '_') | (chr == '.'); + *buffer = (char)chr; + buffer += (chr != '_'); + if (unlikely(chr > 127)) goto parse_failure; + if (unlikely(last_was_punctuation & is_punctuation)) goto parse_failure; + last_was_punctuation = is_punctuation; + } + if (unlikely(last_was_punctuation)) goto parse_failure; + *buffer = '\0'; + return buffer; +parse_failure: + return NULL; +} +static double __Pyx__PyUnicode_AsDouble_inf_nan(const void* data, int kind, Py_ssize_t start, Py_ssize_t length) { + int matches = 1; + Py_UCS4 chr; + Py_UCS4 sign = PyUnicode_READ(kind, data, start); + int is_signed = (sign == '-') | (sign == '+'); + start += is_signed; + length -= is_signed; + switch (PyUnicode_READ(kind, data, start)) { + #ifdef Py_NAN + case 'n': + case 'N': + if (unlikely(length != 3)) goto parse_failure; + chr = PyUnicode_READ(kind, data, start+1); + matches &= (chr == 'a') | (chr == 'A'); + chr = PyUnicode_READ(kind, data, start+2); + matches &= (chr == 'n') | (chr == 'N'); + if (unlikely(!matches)) goto parse_failure; + return (sign == '-') ? -Py_NAN : Py_NAN; + #endif + case 'i': + case 'I': + if (unlikely(length < 3)) goto parse_failure; + chr = PyUnicode_READ(kind, data, start+1); + matches &= (chr == 'n') | (chr == 'N'); + chr = PyUnicode_READ(kind, data, start+2); + matches &= (chr == 'f') | (chr == 'F'); + if (likely(length == 3 && matches)) + return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL; + if (unlikely(length != 8)) goto parse_failure; + chr = PyUnicode_READ(kind, data, start+3); + matches &= (chr == 'i') | (chr == 'I'); + chr = PyUnicode_READ(kind, data, start+4); + matches &= (chr == 'n') | (chr == 'N'); + chr = PyUnicode_READ(kind, data, start+5); + matches &= (chr == 'i') | (chr == 'I'); + chr = PyUnicode_READ(kind, data, start+6); + matches &= (chr == 't') | (chr == 'T'); + chr = PyUnicode_READ(kind, data, start+7); + matches &= (chr == 'y') | (chr == 'Y'); + if (unlikely(!matches)) goto parse_failure; + return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL; + case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + break; + default: + goto parse_failure; + } + return 0.0; +parse_failure: + return -1.0; +} +static double __Pyx_PyUnicode_AsDouble_WithSpaces(PyObject *obj) { + double value; + const char *last; + char *end; + Py_ssize_t start, length = PyUnicode_GET_LENGTH(obj); + const int kind = PyUnicode_KIND(obj); + const void* data = PyUnicode_DATA(obj); + start = 0; + while (Py_UNICODE_ISSPACE(PyUnicode_READ(kind, data, start))) + start++; + while (start < length - 1 && Py_UNICODE_ISSPACE(PyUnicode_READ(kind, data, length - 1))) + length--; + length -= start; + if (unlikely(length <= 0)) goto fallback; + value = __Pyx__PyUnicode_AsDouble_inf_nan(data, kind, start, length); + if (unlikely(value == -1.0)) goto fallback; + if (value != 0.0) return value; + if (length < 40) { + char number[40]; + last = __Pyx__PyUnicode_AsDouble_Copy(data, kind, number, start, start + length); + if (unlikely(!last)) goto fallback; + value = PyOS_string_to_double(number, &end, NULL); + } else { + char *number = (char*) PyMem_Malloc((length + 1) * sizeof(char)); + if (unlikely(!number)) goto fallback; + last = __Pyx__PyUnicode_AsDouble_Copy(data, kind, number, start, start + length); + if (unlikely(!last)) { + PyMem_Free(number); + goto fallback; + } + value = PyOS_string_to_double(number, &end, NULL); + PyMem_Free(number); + } + if (likely(end == last) || (value == (double)-1 && PyErr_Occurred())) { + return value; + } +fallback: + return __Pyx_SlowPyString_AsDouble(obj); +} +#endif +static CYTHON_INLINE double __Pyx_PyUnicode_AsDouble(PyObject *obj) { +#if !CYTHON_COMPILING_IN_PYPY && CYTHON_ASSUME_SAFE_MACROS + if (unlikely(__Pyx_PyUnicode_READY(obj) == -1)) + return (double)-1; + if (likely(PyUnicode_IS_ASCII(obj))) { + const char *s; + Py_ssize_t length; + s = PyUnicode_AsUTF8AndSize(obj, &length); + return __Pyx__PyBytes_AsDouble(obj, s, length); + } + return __Pyx_PyUnicode_AsDouble_WithSpaces(obj); +#else + return __Pyx_SlowPyString_AsDouble(obj); +#endif +} + +/* pynumber_float.proto */ +static CYTHON_INLINE PyObject* __Pyx__PyNumber_Float(PyObject* obj); +#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : __Pyx__PyNumber_Float(x)) + +/* PyFloatBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static int __Pyx_PyFloat_BoolEqObjC(PyObject *op1, PyObject *op2, double floatval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyFloat_BoolEqObjC(op1, op2, floatval, inplace, zerodivision_check)\ + __Pyx_PyObject_IsTrueAndDecref(PyObject_RichCompare(op1, op2, Py_EQ)) + #endif + +/* pow2.proto */ +#define __Pyx_PyNumber_Power2(a, b) PyNumber_Power(a, b, Py_None) + +/* PyLongBinop.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static CYTHON_INLINE PyObject* __Pyx_PyLong_SubtractCObj(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); +#else +#define __Pyx_PyLong_SubtractCObj(op1, op2, intval, inplace, zerodivision_check)\ + (inplace ? PyNumber_InPlaceSubtract(op1, op2) : PyNumber_Subtract(op1, op2)) +#endif + +/* PyValueError_Check.proto */ +#define __Pyx_PyExc_ValueError_Check(obj) __Pyx_TypeCheck(obj, PyExc_ValueError) + +/* PyObjectVectorCallKwBuilder.proto */ +CYTHON_UNUSED static int __Pyx_VectorcallBuilder_AddArg_Check(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n); +#if CYTHON_VECTORCALL +#if PY_VERSION_HEX >= 0x03090000 +#define __Pyx_Object_Vectorcall_CallFromBuilder PyObject_Vectorcall +#else +#define __Pyx_Object_Vectorcall_CallFromBuilder _PyObject_Vectorcall +#endif +#define __Pyx_MakeVectorcallBuilderKwds(n) PyTuple_New(n) +static int __Pyx_VectorcallBuilder_AddArg(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n); +static int __Pyx_VectorcallBuilder_AddArgStr(const char *key, PyObject *value, PyObject *builder, PyObject **args, int n); +#else +#define __Pyx_Object_Vectorcall_CallFromBuilder __Pyx_PyObject_FastCallDict +#define __Pyx_MakeVectorcallBuilderKwds(n) __Pyx_PyDict_NewPresized(n) +#define __Pyx_VectorcallBuilder_AddArg(key, value, builder, args, n) PyDict_SetItem(builder, key, value) +#define __Pyx_VectorcallBuilder_AddArgStr(key, value, builder, args, n) PyDict_SetItemString(builder, key, value) +#endif + +/* PyObjectFastCallMethod.proto */ +#if CYTHON_VECTORCALL && PY_VERSION_HEX >= 0x03090000 +#define __Pyx_PyObject_FastCallMethod(name, args, nargsf) PyObject_VectorcallMethod(name, args, nargsf, NULL) +#else +static PyObject *__Pyx_PyObject_FastCallMethod(PyObject *name, PyObject *const *args, size_t nargsf); +#endif + +/* RaiseClosureNameError.proto */ +static void __Pyx_RaiseClosureNameError(const char *varname); + +/* PyMethodNew.proto (used by CythonFunctionShared) */ +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ); + +/* PyVectorcallFastCallDict.proto (used by CythonFunctionShared) */ +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw); +#endif + +/* CythonFunctionShared.proto (used by CythonFunction) */ +#define __Pyx_CyFunction_USED +#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 +#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 +#define __Pyx_CYFUNCTION_CCLASS 0x04 +#define __Pyx_CYFUNCTION_COROUTINE 0x08 +#define __Pyx_CyFunction_GetClosure(f)\ + (((__pyx_CyFunctionObject *) (f))->func_closure) +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_CyFunction_GetClassObj(f)\ + (((__pyx_CyFunctionObject *) (f))->func_classobj) +#else + #define __Pyx_CyFunction_GetClassObj(f)\ + ((PyObject*) ((PyCMethodObject *) (f))->mm_class) +#endif +#define __Pyx_CyFunction_SetClassObj(f, classobj)\ + __Pyx__CyFunction_SetClassObj((__pyx_CyFunctionObject *) (f), (classobj)) +#define __Pyx_CyFunction_Defaults(type, f)\ + ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) +#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ + ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) +typedef struct { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject_HEAD + PyObject *func; +#elif PY_VERSION_HEX < 0x030900B1 + PyCFunctionObject func; +#else + PyCMethodObject func; +#endif +#if CYTHON_COMPILING_IN_LIMITED_API && CYTHON_METH_FASTCALL + __pyx_vectorcallfunc func_vectorcall; +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_weakreflist; +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_dict; +#endif + PyObject *func_name; + PyObject *func_qualname; + PyObject *func_doc; + PyObject *func_globals; + PyObject *func_code; + PyObject *func_closure; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_classobj; +#endif + PyObject *defaults; + int flags; + PyObject *defaults_tuple; + PyObject *defaults_kwdict; + PyObject *(*defaults_getter)(PyObject *); + PyObject *func_annotations; + PyObject *func_is_coroutine; +} __pyx_CyFunctionObject; +#undef __Pyx_CyOrPyCFunction_Check +#define __Pyx_CyFunction_Check(obj) __Pyx_TypeCheck(obj, __pyx_mstate_global->__pyx_CyFunctionType) +#define __Pyx_CyOrPyCFunction_Check(obj) __Pyx_TypeCheck2(obj, __pyx_mstate_global->__pyx_CyFunctionType, &PyCFunction_Type) +#define __Pyx_CyFunction_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_mstate_global->__pyx_CyFunctionType) +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void (*cfunc)(void)); +#undef __Pyx_IsSameCFunction +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCyOrCFunction(func, cfunc) +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj); +static CYTHON_INLINE PyObject *__Pyx_CyFunction_InitDefaults(PyObject *func, + PyTypeObject *defaults_type); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, + PyObject *tuple); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, + PyObject *dict); +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, + PyObject *dict); +static int __pyx_CyFunction_init(PyObject *module); +#if CYTHON_METH_FASTCALL +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +#if CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall) +#else +#define __Pyx_CyFunction_func_vectorcall(f) (((PyCFunctionObject*)f)->vectorcall) +#endif +#endif + +/* CythonFunction.proto */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); + +/* pyfrozenset_new.proto (used by PySetContains) */ +static CYTHON_INLINE PyObject* __Pyx_PyFrozenSet_New(PyObject* it); + +/* PySetContains.proto */ +static CYTHON_INLINE int __Pyx_PySet_ContainsTF(PyObject* key, PyObject* set, int eq); + +/* PyTypeError_Check.proto */ +#define __Pyx_PyExc_TypeError_Check(obj) __Pyx_TypeCheck(obj, PyExc_TypeError) + +/* AllocateExtensionType.proto */ +static PyObject *__Pyx_AllocateExtensionType(PyTypeObject *t, int is_final); + +/* CheckTypeForFreelists.proto */ +#if CYTHON_USE_FREELISTS +#if CYTHON_USE_TYPE_SPECS +#define __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(t, expected_tp, expected_size) ((int) ((t) == (expected_tp))) +#define __PYX_CHECK_TYPE_FOR_FREELIST_FLAGS Py_TPFLAGS_IS_ABSTRACT +#else +#define __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(t, expected_tp, expected_size) ((int) ((t)->tp_basicsize == (expected_size))) +#define __PYX_CHECK_TYPE_FOR_FREELIST_FLAGS (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE) +#endif +#define __PYX_CHECK_TYPE_FOR_FREELISTS(t, expected_tp, expected_size)\ + (__PYX_CHECK_FINAL_TYPE_FOR_FREELISTS((t), (expected_tp), (expected_size)) &\ + (int) (!__Pyx_PyType_HasFeature((t), __PYX_CHECK_TYPE_FOR_FREELIST_FLAGS))) +#endif + +/* PyObjectCallMethod0.proto (used by PyType_Ready) */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name); + +/* ValidateBasesTuple.proto (used by PyType_Ready) */ +#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS +static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases); +#endif + +/* PyType_Ready.proto */ +CYTHON_UNUSED static int __Pyx_PyType_Ready(PyTypeObject *t); + +/* HasAttr.proto (used by ImportImpl) */ +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 +#define __Pyx_HasAttr(o, n) PyObject_HasAttrWithError(o, n) +#else +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *, PyObject *); +#endif + +/* ImportImpl.export */ +static PyObject *__Pyx__Import(PyObject *name, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject *qualname, PyObject *moddict, int level); + +/* Import.proto */ +static CYTHON_INLINE PyObject *__Pyx_Import(PyObject *name, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject *qualname, int level); + +/* ImportFrom.proto */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); + +/* ListPack.proto */ +static PyObject *__Pyx_PyList_Pack(Py_ssize_t n, ...); + +/* CLineInTraceback.proto (used by AddTraceback) */ +#if CYTHON_CLINE_IN_TRACEBACK && CYTHON_CLINE_IN_TRACEBACK_RUNTIME +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#else +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#endif + +/* CodeObjectCache.proto (used by AddTraceback) */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject __Pyx_CachedCodeObjectType; +#else +typedef PyCodeObject __Pyx_CachedCodeObjectType; +#endif +typedef struct { + __Pyx_CachedCodeObjectType* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_atomic_int_type accessor_count; + #endif +}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static __Pyx_CachedCodeObjectType *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, __Pyx_CachedCodeObjectType* code_object); + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* RealImag.proto */ +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #define __Pyx_CREAL(z) ((z).real()) + #define __Pyx_CIMAG(z) ((z).imag()) + #else + #define __Pyx_CREAL(z) (__real__(z)) + #define __Pyx_CIMAG(z) (__imag__(z)) + #endif +#else + #define __Pyx_CREAL(z) ((z).real) + #define __Pyx_CIMAG(z) ((z).imag) +#endif +#if defined(__cplusplus) && CYTHON_CCOMPLEX\ + && (defined(_WIN32) || defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )) || __cplusplus >= 201103) + #define __Pyx_SET_CREAL(z,x) ((z).real(x)) + #define __Pyx_SET_CIMAG(z,y) ((z).imag(y)) +#else + #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x) + #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y) +#endif + +/* Arithmetic.proto */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #define __Pyx_c_eq_double(a, b) ((a)==(b)) + #define __Pyx_c_sum_double(a, b) ((a)+(b)) + #define __Pyx_c_diff_double(a, b) ((a)-(b)) + #define __Pyx_c_prod_double(a, b) ((a)*(b)) + #define __Pyx_c_quot_double(a, b) ((a)/(b)) + #define __Pyx_c_neg_double(a) (-(a)) + #ifdef __cplusplus + #define __Pyx_c_is_zero_double(z) ((z)==(double)0) + #define __Pyx_c_conj_double(z) (::std::conj(z)) + #if 1 + #define __Pyx_c_abs_double(z) (::std::abs(z)) + #define __Pyx_c_pow_double(a, b) (::std::pow(a, b)) + #endif + #else + #define __Pyx_c_is_zero_double(z) ((z)==0) + #define __Pyx_c_conj_double(z) (conj(z)) + #if 1 + #define __Pyx_c_abs_double(z) (cabs(z)) + #define __Pyx_c_pow_double(a, b) (cpow(a, b)) + #endif + #endif +#else + static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex); + static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex); + #if 1 + static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex, __pyx_t_double_complex); + #endif +#endif + +/* FromPy.proto */ +static __pyx_t_double_complex __Pyx_PyComplex_As___pyx_t_double_complex(PyObject*); + +/* ToPy.proto */ +#define __pyx_PyComplex_FromComplex(z)\ + PyComplex_FromDoubles((double)__Pyx_CREAL(z),\ + (double)__Pyx_CIMAG(z)) + +/* GCCDiagnostics.proto */ +#if !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define __Pyx_HAS_GCC_DIAGNOSTIC +#endif + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyLong_From_long(long value); + +/* FormatTypeName.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%U" +#define __Pyx_DECREF_TypeName(obj) Py_XDECREF(obj) +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 +#define __Pyx_PyType_GetFullyQualifiedName PyType_GetFullyQualifiedName +#else +static __Pyx_TypeName __Pyx_PyType_GetFullyQualifiedName(PyTypeObject* tp); +#endif +#else // !LIMITED_API +typedef const char *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%.200s" +#define __Pyx_PyType_GetFullyQualifiedName(tp) ((tp)->tp_name) +#define __Pyx_DECREF_TypeName(obj) +#endif + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyLong_As_long(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyLong_As_int(PyObject *); + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) __Pyx_IsAnySubtype2(Py_TYPE(obj), (PyTypeObject *)type1, (PyTypeObject *)type2) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) (PyObject_TypeCheck(obj, (PyTypeObject *)type1) || PyObject_TypeCheck(obj, (PyTypeObject *)type2)) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2) { + return PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2); +} +#endif +#define __Pyx_PyErr_ExceptionMatches2(err1, err2) __Pyx_PyErr_GivenExceptionMatches2(__Pyx_PyErr_CurrentExceptionType(), err1, err2) +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) +#ifdef PyExceptionInstance_Check + #define __Pyx_PyBaseException_Check(obj) PyExceptionInstance_Check(obj) +#else + #define __Pyx_PyBaseException_Check(obj) __Pyx_TypeCheck(obj, PyExc_BaseException) +#endif + +/* GetRuntimeVersion.proto */ +#if __PYX_LIMITED_VERSION_HEX < 0x030b0000 +static unsigned long __Pyx_cached_runtime_version = 0; +static void __Pyx_init_runtime_version(void); +#else +#define __Pyx_init_runtime_version() +#endif +static unsigned long __Pyx_get_runtime_version(void); + +/* CheckBinaryVersion.proto */ +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer); + +/* DecompressString.proto */ +static PyObject *__Pyx_DecompressString(const char *s, Py_ssize_t length, int algo); + +/* MultiPhaseInitModuleState.proto */ +#if CYTHON_PEP489_MULTI_PHASE_INIT && CYTHON_USE_MODULE_STATE +static PyObject *__Pyx_State_FindModule(void*); +static int __Pyx_State_AddModule(PyObject* module, void*); +static int __Pyx_State_RemoveModule(void*); +#elif CYTHON_USE_MODULE_STATE +#define __Pyx_State_FindModule PyState_FindModule +#define __Pyx_State_AddModule PyState_AddModule +#define __Pyx_State_RemoveModule PyState_RemoveModule +#endif + +/* #### Code section: module_declarations ### */ +/* CythonABIVersion.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API + #if CYTHON_METH_FASTCALL + #define __PYX_FASTCALL_ABI_SUFFIX "_fastcall" + #else + #define __PYX_FASTCALL_ABI_SUFFIX + #endif + #define __PYX_LIMITED_ABI_SUFFIX "limited" __PYX_FASTCALL_ABI_SUFFIX __PYX_AM_SEND_ABI_SUFFIX +#else + #define __PYX_LIMITED_ABI_SUFFIX +#endif +#if __PYX_HAS_PY_AM_SEND == 1 + #define __PYX_AM_SEND_ABI_SUFFIX +#elif __PYX_HAS_PY_AM_SEND == 2 + #define __PYX_AM_SEND_ABI_SUFFIX "amsendbackport" +#else + #define __PYX_AM_SEND_ABI_SUFFIX "noamsend" +#endif +#ifndef __PYX_MONITORING_ABI_SUFFIX + #define __PYX_MONITORING_ABI_SUFFIX +#endif +#if CYTHON_USE_TP_FINALIZE + #define __PYX_TP_FINALIZE_ABI_SUFFIX +#else + #define __PYX_TP_FINALIZE_ABI_SUFFIX "nofinalize" +#endif +#if CYTHON_USE_FREELISTS || !defined(__Pyx_AsyncGen_USED) + #define __PYX_FREELISTS_ABI_SUFFIX +#else + #define __PYX_FREELISTS_ABI_SUFFIX "nofreelists" +#endif +#define CYTHON_ABI __PYX_ABI_VERSION __PYX_LIMITED_ABI_SUFFIX __PYX_MONITORING_ABI_SUFFIX __PYX_TP_FINALIZE_ABI_SUFFIX __PYX_FREELISTS_ABI_SUFFIX __PYX_AM_SEND_ABI_SUFFIX +#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI +#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "." + + +/* Module declarations from "cython" */ + +/* Module declarations from "fontTools.misc.bezierTools" */ +static CYTHON_INLINE double __pyx_f_9fontTools_4misc_11bezierTools__dot(__pyx_t_double_complex, __pyx_t_double_complex); /*proto*/ +static CYTHON_INLINE double __pyx_f_9fontTools_4misc_11bezierTools__intSecAtan(double); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_4misc_11bezierTools_calcCubicParametersC(__pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_4misc_11bezierTools_calcCubicPointsC(__pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex, __pyx_t_double_complex); /*proto*/ +/* #### Code section: typeinfo ### */ +/* #### Code section: before_global_var ### */ +#define __Pyx_MODULE_NAME "fontTools.misc.bezierTools" +extern int __pyx_module_is_main_fontTools__misc__bezierTools; +int __pyx_module_is_main_fontTools__misc__bezierTools = 0; + +/* Implementation of "fontTools.misc.bezierTools" */ +/* #### Code section: global_var ### */ +static PyObject *__pyx_builtin_round; +static PyObject *__pyx_builtin_print; +/* #### Code section: string_decls ### */ +static const char __pyx_k_fontTools_misc_bezierTools_py_to[] = "fontTools.misc.bezierTools.py -- tools for working with Bezier path segments.\n"; +/* #### Code section: decls ### */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_calcCubicArcLength(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4, PyObject *__pyx_v_tolerance); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_2_split_cubic_into_two(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_p0, PyObject *__pyx_v_p1, PyObject *__pyx_v_p2, PyObject *__pyx_v_p3); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_4_calcCubicArcLengthCRecurse(CYTHON_UNUSED PyObject *__pyx_self, double __pyx_v_mult, __pyx_t_double_complex __pyx_v_p0, __pyx_t_double_complex __pyx_v_p1, __pyx_t_double_complex __pyx_v_p2, __pyx_t_double_complex __pyx_v_p3); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_6calcCubicArcLengthC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4, double __pyx_v_tolerance); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_8calcQuadraticArcLength(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_10calcQuadraticArcLengthC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_12approximateQuadraticArcLength(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_14approximateQuadraticArcLengthC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_16calcQuadraticBounds(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_18approximateCubicArcLength(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_20approximateCubicArcLengthC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_22calcCubicBounds(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_24splitLine(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_where, PyObject *__pyx_v_isHorizontal); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_14splitQuadratic_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_26splitQuadratic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_where, PyObject *__pyx_v_isHorizontal); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_10splitCubic_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_28splitCubic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4, PyObject *__pyx_v_where, PyObject *__pyx_v_isHorizontal); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_30splitQuadraticAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_ts); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_32splitCubicAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4, PyObject *__pyx_v_ts); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_34splitCubicAtTC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4, PyObject *__pyx_v_ts); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_37splitCubicIntoTwoAtTC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4, double __pyx_v_t); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_39_splitQuadraticAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_ts); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_41_splitCubicAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_ts); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_43_splitCubicAtTC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_a, __pyx_t_double_complex __pyx_v_b, __pyx_t_double_complex __pyx_v_c, __pyx_t_double_complex __pyx_v_d, PyObject *__pyx_v_ts); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_96__defaults__(CYTHON_UNUSED PyObject *__pyx_self); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_46solveQuadratic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_sqrt); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_48solveCubic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_50calcQuadraticParameters(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_52calcCubicParameters(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_54calcQuadraticPoints(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_56calcCubicPoints(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_58linePointAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_t); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_60quadraticPointAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_t); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_62cubicPointAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4, PyObject *__pyx_v_t); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_64cubicPointAtTC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4, double __pyx_v_t); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_66segmentPointAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_seg, PyObject *__pyx_v_t); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_68_line_t_of_pt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_s, PyObject *__pyx_v_e, PyObject *__pyx_v_pt); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_70_both_points_are_on_same_side_of_origin(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_origin); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_72lineLineIntersections(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_s1, PyObject *__pyx_v_e1, PyObject *__pyx_v_s2, PyObject *__pyx_v_e2); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_74_alignment_transformation(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_segment); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_27_curve_line_intersections_t_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_76_curve_line_intersections_t(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve, PyObject *__pyx_v_line); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_78curveLineIntersections(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve, PyObject *__pyx_v_line); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_80_curve_bounds(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_c); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_82_split_segment_at_t(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_c, PyObject *__pyx_v_t); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_r); /* proto */ +static PyObject *__pyx_lambda_funcdef_lambda3(PyObject *__pyx_self, PyObject *__pyx_v_ts); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_84_curve_curve_intersections_t(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve1, PyObject *__pyx_v_curve2, PyObject *__pyx_v_precision, PyObject *__pyx_v_range1, PyObject *__pyx_v_range2); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_12_is_linelike_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_86_is_linelike(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_segment); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_88curveCurveIntersections(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve1, PyObject *__pyx_v_curve2); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_90segmentSegmentIntersections(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_seg1, PyObject *__pyx_v_seg2); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_12_segmentrepr_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_92_segmentrepr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_obj); /* proto */ +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_94printSegments(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_segments); /* proto */ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_defaults(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +/* #### Code section: late_includes ### */ +/* #### Code section: module_state ### */ +/* SmallCodeConfig */ +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif + +typedef struct { + PyObject *__pyx_d; + PyObject *__pyx_b; + PyObject *__pyx_cython_runtime; + PyObject *__pyx_empty_tuple; + PyObject *__pyx_empty_bytes; + PyObject *__pyx_empty_unicode; + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_defaults; + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr; + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr; + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC; + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC; + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr; + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t; + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr; + PyObject *__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr; + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_defaults; + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr; + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr; + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC; + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC; + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr; + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t; + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr; + PyTypeObject *__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr; + __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_items; + __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_pop; + __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_values; + PyObject *__pyx_slice[2]; + PyObject *__pyx_tuple[4]; + PyObject *__pyx_codeobj_tab[54]; + PyObject *__pyx_string_tab[387]; + PyObject *__pyx_number_tab[21]; +/* #### Code section: module_state_contents ### */ +/* CommonTypesMetaclass.module_state_decls */ +PyTypeObject *__pyx_CommonTypesMetaclassType; + +/* IterNextPlain.module_state_decls */ +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 +PyObject *__Pyx_GetBuiltinNext_LimitedAPI_cache; +#endif + +/* Generator.module_state_decls */ +PyTypeObject *__pyx_GeneratorType; + +/* CachedMethodType.module_state_decls */ +#if CYTHON_COMPILING_IN_LIMITED_API +PyObject *__Pyx_CachedMethodType; +#endif + +/* CythonFunctionShared.module_state_decls */ +PyTypeObject *__pyx_CyFunctionType; + + +#if CYTHON_USE_FREELISTS +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr[8]; +int __pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr; +#endif + +#if CYTHON_USE_FREELISTS +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr[8]; +int __pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr; +#endif + +#if CYTHON_USE_FREELISTS +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC[8]; +int __pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC; +#endif + +#if CYTHON_USE_FREELISTS +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC[8]; +int __pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC; +#endif + +#if CYTHON_USE_FREELISTS +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr[8]; +int __pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr; +#endif + +#if CYTHON_USE_FREELISTS +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t[8]; +int __pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t; +#endif + +#if CYTHON_USE_FREELISTS +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr[8]; +int __pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr; +#endif + +#if CYTHON_USE_FREELISTS +struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr[8]; +int __pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr; +#endif +/* CodeObjectCache.module_state_decls */ +struct __Pyx_CodeObjectCache __pyx_code_cache; + +/* #### Code section: module_state_end ### */ +} __pyx_mstatetype; + +#if CYTHON_USE_MODULE_STATE +#ifdef __cplusplus +namespace { +extern struct PyModuleDef __pyx_moduledef; +} /* anonymous namespace */ +#else +static struct PyModuleDef __pyx_moduledef; +#endif + +#define __pyx_mstate_global (__Pyx_PyModule_GetState(__Pyx_State_FindModule(&__pyx_moduledef))) + +#define __pyx_m (__Pyx_State_FindModule(&__pyx_moduledef)) +#else +static __pyx_mstatetype __pyx_mstate_global_static = +#ifdef __cplusplus + {}; +#else + {0}; +#endif +static __pyx_mstatetype * const __pyx_mstate_global = &__pyx_mstate_global_static; +#endif +/* #### Code section: constant_name_defines ### */ +#define __pyx_kp_u_ __pyx_string_tab[0] +#define __pyx_kp_u_Approximates_the_arc_length_for __pyx_string_tab[1] +#define __pyx_kp_u_Calculates_the_arc_length_for_a __pyx_string_tab[2] +#define __pyx_kp_u_Calculates_the_bounding_rectangl __pyx_string_tab[3] +#define __pyx_kp_u_Calculates_the_bounding_rectangl_2 __pyx_string_tab[4] +#define __pyx_kp_u_Couldn_t_work_out_which_intersec __pyx_string_tab[5] +#define __pyx_kp_u_Finds_intersections_between_a_cu __pyx_string_tab[6] +#define __pyx_kp_u_Finds_intersections_between_a_cu_2 __pyx_string_tab[7] +#define __pyx_kp_u_Finds_intersections_between_two __pyx_string_tab[8] +#define __pyx_kp_u_Finds_intersections_between_two_2 __pyx_string_tab[9] +#define __pyx_kp_u_Lib_fontTools_misc_bezierTools_p __pyx_string_tab[10] +#define __pyx_kp_u_Solve_a_cubic_equation_Solves_a __pyx_string_tab[11] +#define __pyx_kp_u_Split_a_cubic_Bezier_curve_at_a __pyx_string_tab[12] +#define __pyx_kp_u_Split_a_cubic_Bezier_curve_at_on __pyx_string_tab[13] +#define __pyx_kp_u_Split_a_line_at_a_given_coordina __pyx_string_tab[14] +#define __pyx_kp_u_Split_a_quadratic_Bezier_curve_a __pyx_string_tab[15] +#define __pyx_kp_u_Split_a_quadratic_Bezier_curve_a_2 __pyx_string_tab[16] +#define __pyx_kp_u_Unknown_curve_degree __pyx_string_tab[17] +#define __pyx_kp_u__2 __pyx_string_tab[18] +#define __pyx_kp_u__3 __pyx_string_tab[19] +#define __pyx_kp_u_approximateCubicArcLength_line_3 __pyx_string_tab[20] +#define __pyx_kp_u_calcCubicBounds_line_412 __pyx_string_tab[21] +#define __pyx_kp_u_calcQuadraticArcLength_line_151 __pyx_string_tab[22] +#define __pyx_kp_u_calcQuadraticBounds_line_298 __pyx_string_tab[23] +#define __pyx_kp_u_curveCurveIntersections_line_138 __pyx_string_tab[24] +#define __pyx_kp_u_curveLineIntersections_line_1255 __pyx_string_tab[25] +#define __pyx_kp_u_disable __pyx_string_tab[26] +#define __pyx_kp_u_enable __pyx_string_tab[27] +#define __pyx_kp_u_g __pyx_string_tab[28] +#define __pyx_kp_u_gc __pyx_string_tab[29] +#define __pyx_kp_u_isenabled __pyx_string_tab[30] +#define __pyx_kp_u_lineLineIntersections_line_1154 __pyx_string_tab[31] +#define __pyx_kp_u_s_2 __pyx_string_tab[32] +#define __pyx_kp_u_segmentSegmentIntersections_line __pyx_string_tab[33] +#define __pyx_kp_u_segmentrepr_1_2_3_2_3_4_0_1_2 __pyx_string_tab[34] +#define __pyx_kp_u_segmentrepr_line_1475 __pyx_string_tab[35] +#define __pyx_kp_u_solveCubic_line_848 __pyx_string_tab[36] +#define __pyx_kp_u_splitCubicAtT_line_613 __pyx_string_tab[37] +#define __pyx_kp_u_splitCubic_line_552 __pyx_string_tab[38] +#define __pyx_kp_u_splitLine_line_450 __pyx_string_tab[39] +#define __pyx_kp_u_splitQuadraticAtT_line_589 __pyx_string_tab[40] +#define __pyx_kp_u_splitQuadratic_line_507 __pyx_string_tab[41] +#define __pyx_n_u_1_t __pyx_string_tab[42] +#define __pyx_n_u_1_t_2 __pyx_string_tab[43] +#define __pyx_n_u_2_t_1_t __pyx_string_tab[44] +#define __pyx_n_u_COMPILED __pyx_string_tab[45] +#define __pyx_n_u_DD __pyx_string_tab[46] +#define __pyx_n_u_EPSILON __pyx_string_tab[47] +#define __pyx_n_u_Identity __pyx_string_tab[48] +#define __pyx_n_u_Intersection __pyx_string_tab[49] +#define __pyx_n_u_Len __pyx_string_tab[50] +#define __pyx_n_u_Pyx_PyDict_NextRef __pyx_string_tab[51] +#define __pyx_n_u_Q __pyx_string_tab[52] +#define __pyx_n_u_Q3 __pyx_string_tab[53] +#define __pyx_n_u_R __pyx_string_tab[54] +#define __pyx_n_u_R2 __pyx_string_tab[55] +#define __pyx_n_u_R2_Q3 __pyx_string_tab[56] +#define __pyx_n_u__6 __pyx_string_tab[57] +#define __pyx_n_u_a __pyx_string_tab[58] +#define __pyx_n_u_a1 __pyx_string_tab[59] +#define __pyx_n_u_a1_3 __pyx_string_tab[60] +#define __pyx_n_u_a1x __pyx_string_tab[61] +#define __pyx_n_u_a1y __pyx_string_tab[62] +#define __pyx_n_u_a2 __pyx_string_tab[63] +#define __pyx_n_u_a3 __pyx_string_tab[64] +#define __pyx_n_u_acos __pyx_string_tab[65] +#define __pyx_n_u_aligned_curve __pyx_string_tab[66] +#define __pyx_n_u_alignment_transformation __pyx_string_tab[67] +#define __pyx_n_u_all __pyx_string_tab[68] +#define __pyx_n_u_angle __pyx_string_tab[69] +#define __pyx_n_u_append __pyx_string_tab[70] +#define __pyx_n_u_approximateCubicArcLength __pyx_string_tab[71] +#define __pyx_n_u_approximateCubicArcLengthC __pyx_string_tab[72] +#define __pyx_n_u_approximateQuadraticArcLength __pyx_string_tab[73] +#define __pyx_n_u_approximateQuadraticArcLengthC __pyx_string_tab[74] +#define __pyx_n_u_arch __pyx_string_tab[75] +#define __pyx_n_u_asinh __pyx_string_tab[76] +#define __pyx_n_u_asyncio_coroutines __pyx_string_tab[77] +#define __pyx_n_u_atan2 __pyx_string_tab[78] +#define __pyx_n_u_ax __pyx_string_tab[79] +#define __pyx_n_u_ax2 __pyx_string_tab[80] +#define __pyx_n_u_ax3 __pyx_string_tab[81] +#define __pyx_n_u_ay __pyx_string_tab[82] +#define __pyx_n_u_ay2 __pyx_string_tab[83] +#define __pyx_n_u_ay3 __pyx_string_tab[84] +#define __pyx_n_u_b __pyx_string_tab[85] +#define __pyx_n_u_b1 __pyx_string_tab[86] +#define __pyx_n_u_b1x __pyx_string_tab[87] +#define __pyx_n_u_b1y __pyx_string_tab[88] +#define __pyx_n_u_both_points_are_on_same_side_of __pyx_string_tab[89] +#define __pyx_n_u_bounds1 __pyx_string_tab[90] +#define __pyx_n_u_bounds2 __pyx_string_tab[91] +#define __pyx_n_u_box __pyx_string_tab[92] +#define __pyx_n_u_bx __pyx_string_tab[93] +#define __pyx_n_u_bx2 __pyx_string_tab[94] +#define __pyx_n_u_by __pyx_string_tab[95] +#define __pyx_n_u_by2 __pyx_string_tab[96] +#define __pyx_n_u_c __pyx_string_tab[97] +#define __pyx_n_u_c1 __pyx_string_tab[98] +#define __pyx_n_u_c11 __pyx_string_tab[99] +#define __pyx_n_u_c11_range __pyx_string_tab[100] +#define __pyx_n_u_c12 __pyx_string_tab[101] +#define __pyx_n_u_c12_range __pyx_string_tab[102] +#define __pyx_n_u_c1x __pyx_string_tab[103] +#define __pyx_n_u_c1y __pyx_string_tab[104] +#define __pyx_n_u_c21 __pyx_string_tab[105] +#define __pyx_n_u_c21_range __pyx_string_tab[106] +#define __pyx_n_u_c22 __pyx_string_tab[107] +#define __pyx_n_u_c22_range __pyx_string_tab[108] +#define __pyx_n_u_calcBounds __pyx_string_tab[109] +#define __pyx_n_u_calcCubicArcLength __pyx_string_tab[110] +#define __pyx_n_u_calcCubicArcLengthC __pyx_string_tab[111] +#define __pyx_n_u_calcCubicArcLengthCRecurse __pyx_string_tab[112] +#define __pyx_n_u_calcCubicBounds __pyx_string_tab[113] +#define __pyx_n_u_calcCubicParameters __pyx_string_tab[114] +#define __pyx_n_u_calcCubicPoints __pyx_string_tab[115] +#define __pyx_n_u_calcQuadraticArcLength __pyx_string_tab[116] +#define __pyx_n_u_calcQuadraticArcLengthC __pyx_string_tab[117] +#define __pyx_n_u_calcQuadraticBounds __pyx_string_tab[118] +#define __pyx_n_u_calcQuadraticParameters __pyx_string_tab[119] +#define __pyx_n_u_calcQuadraticPoints __pyx_string_tab[120] +#define __pyx_n_u_class_getitem __pyx_string_tab[121] +#define __pyx_n_u_cline_in_traceback __pyx_string_tab[122] +#define __pyx_n_u_close __pyx_string_tab[123] +#define __pyx_n_u_collections __pyx_string_tab[124] +#define __pyx_n_u_cos __pyx_string_tab[125] +#define __pyx_n_u_cubicPointAtT __pyx_string_tab[126] +#define __pyx_n_u_cubicPointAtTC __pyx_string_tab[127] +#define __pyx_n_u_curve __pyx_string_tab[128] +#define __pyx_n_u_curve1 __pyx_string_tab[129] +#define __pyx_n_u_curve2 __pyx_string_tab[130] +#define __pyx_n_u_curveCurveIntersections __pyx_string_tab[131] +#define __pyx_n_u_curveLineIntersections __pyx_string_tab[132] +#define __pyx_n_u_curve_bounds __pyx_string_tab[133] +#define __pyx_n_u_curve_curve_intersections_t __pyx_string_tab[134] +#define __pyx_n_u_curve_curve_intersections_t_loc __pyx_string_tab[135] +#define __pyx_n_u_curve_curve_intersections_t_loc_2 __pyx_string_tab[136] +#define __pyx_n_u_curve_line_intersections_t __pyx_string_tab[137] +#define __pyx_n_u_curve_line_intersections_t_loca __pyx_string_tab[138] +#define __pyx_n_u_cx __pyx_string_tab[139] +#define __pyx_n_u_cy __pyx_string_tab[140] +#define __pyx_n_u_d __pyx_string_tab[141] +#define __pyx_n_u_d0 __pyx_string_tab[142] +#define __pyx_n_u_d1 __pyx_string_tab[143] +#define __pyx_n_u_d1x __pyx_string_tab[144] +#define __pyx_n_u_d1y __pyx_string_tab[145] +#define __pyx_n_u_delta __pyx_string_tab[146] +#define __pyx_n_u_delta_2 __pyx_string_tab[147] +#define __pyx_n_u_delta_3 __pyx_string_tab[148] +#define __pyx_n_u_deriv3 __pyx_string_tab[149] +#define __pyx_n_u_doctest __pyx_string_tab[150] +#define __pyx_n_u_dx __pyx_string_tab[151] +#define __pyx_n_u_dy __pyx_string_tab[152] +#define __pyx_n_u_e __pyx_string_tab[153] +#define __pyx_n_u_e1 __pyx_string_tab[154] +#define __pyx_n_u_e1x __pyx_string_tab[155] +#define __pyx_n_u_e1y __pyx_string_tab[156] +#define __pyx_n_u_e2 __pyx_string_tab[157] +#define __pyx_n_u_e2x __pyx_string_tab[158] +#define __pyx_n_u_e2y __pyx_string_tab[159] +#define __pyx_n_u_end __pyx_string_tab[160] +#define __pyx_n_u_epsilon __pyx_string_tab[161] +#define __pyx_n_u_epsilonDigits __pyx_string_tab[162] +#define __pyx_n_u_ex __pyx_string_tab[163] +#define __pyx_n_u_exit __pyx_string_tab[164] +#define __pyx_n_u_ey __pyx_string_tab[165] +#define __pyx_n_u_failed __pyx_string_tab[166] +#define __pyx_n_u_fontTools_misc_arrayTools __pyx_string_tab[167] +#define __pyx_n_u_fontTools_misc_bezierTools __pyx_string_tab[168] +#define __pyx_n_u_fontTools_misc_transform __pyx_string_tab[169] +#define __pyx_n_u_found __pyx_string_tab[170] +#define __pyx_n_u_func __pyx_string_tab[171] +#define __pyx_n_u_genexpr __pyx_string_tab[172] +#define __pyx_n_u_hits __pyx_string_tab[173] +#define __pyx_n_u_i __pyx_string_tab[174] +#define __pyx_n_u_insert __pyx_string_tab[175] +#define __pyx_n_u_intersection_ts __pyx_string_tab[176] +#define __pyx_n_u_intersections __pyx_string_tab[177] +#define __pyx_n_u_intersects __pyx_string_tab[178] +#define __pyx_n_u_isHorizontal __pyx_string_tab[179] +#define __pyx_n_u_is_coroutine __pyx_string_tab[180] +#define __pyx_n_u_is_linelike __pyx_string_tab[181] +#define __pyx_n_u_is_linelike_locals_genexpr __pyx_string_tab[182] +#define __pyx_n_u_isclose __pyx_string_tab[183] +#define __pyx_n_u_it __pyx_string_tab[184] +#define __pyx_n_u_items __pyx_string_tab[185] +#define __pyx_n_u_key __pyx_string_tab[186] +#define __pyx_n_u_lambda __pyx_string_tab[187] +#define __pyx_n_u_line __pyx_string_tab[188] +#define __pyx_n_u_line1 __pyx_string_tab[189] +#define __pyx_n_u_line2 __pyx_string_tab[190] +#define __pyx_n_u_lineLineIntersections __pyx_string_tab[191] +#define __pyx_n_u_linePointAtT __pyx_string_tab[192] +#define __pyx_n_u_line_t __pyx_string_tab[193] +#define __pyx_n_u_line_t_of_pt __pyx_string_tab[194] +#define __pyx_n_u_main __pyx_string_tab[195] +#define __pyx_n_u_math __pyx_string_tab[196] +#define __pyx_n_u_maybeline __pyx_string_tab[197] +#define __pyx_n_u_mid __pyx_string_tab[198] +#define __pyx_n_u_midPt __pyx_string_tab[199] +#define __pyx_n_u_midpoint __pyx_string_tab[200] +#define __pyx_n_u_module __pyx_string_tab[201] +#define __pyx_n_u_mult __pyx_string_tab[202] +#define __pyx_n_u_n __pyx_string_tab[203] +#define __pyx_n_u_name __pyx_string_tab[204] +#define __pyx_n_u_namedtuple __pyx_string_tab[205] +#define __pyx_n_u_next __pyx_string_tab[206] +#define __pyx_n_u_obj __pyx_string_tab[207] +#define __pyx_n_u_off1 __pyx_string_tab[208] +#define __pyx_n_u_off2 __pyx_string_tab[209] +#define __pyx_n_u_one __pyx_string_tab[210] +#define __pyx_n_u_origDist __pyx_string_tab[211] +#define __pyx_n_u_origin __pyx_string_tab[212] +#define __pyx_n_u_p __pyx_string_tab[213] +#define __pyx_n_u_p0 __pyx_string_tab[214] +#define __pyx_n_u_p1 __pyx_string_tab[215] +#define __pyx_n_u_p2 __pyx_string_tab[216] +#define __pyx_n_u_p3 __pyx_string_tab[217] +#define __pyx_n_u_pi __pyx_string_tab[218] +#define __pyx_n_u_pointAtT __pyx_string_tab[219] +#define __pyx_n_u_pointFinder __pyx_string_tab[220] +#define __pyx_n_u_points __pyx_string_tab[221] +#define __pyx_n_u_pop __pyx_string_tab[222] +#define __pyx_n_u_precision __pyx_string_tab[223] +#define __pyx_n_u_print __pyx_string_tab[224] +#define __pyx_n_u_printSegments __pyx_string_tab[225] +#define __pyx_n_u_pt __pyx_string_tab[226] +#define __pyx_n_u_pt1 __pyx_string_tab[227] +#define __pyx_n_u_pt1x __pyx_string_tab[228] +#define __pyx_n_u_pt1y __pyx_string_tab[229] +#define __pyx_n_u_pt2 __pyx_string_tab[230] +#define __pyx_n_u_pt2x __pyx_string_tab[231] +#define __pyx_n_u_pt2y __pyx_string_tab[232] +#define __pyx_n_u_pt3 __pyx_string_tab[233] +#define __pyx_n_u_pt4 __pyx_string_tab[234] +#define __pyx_n_u_px __pyx_string_tab[235] +#define __pyx_n_u_py __pyx_string_tab[236] +#define __pyx_n_u_quadraticPointAtT __pyx_string_tab[237] +#define __pyx_n_u_qualname __pyx_string_tab[238] +#define __pyx_n_u_r __pyx_string_tab[239] +#define __pyx_n_u_rDD __pyx_string_tab[240] +#define __pyx_n_u_rQ2 __pyx_string_tab[241] +#define __pyx_n_u_range1 __pyx_string_tab[242] +#define __pyx_n_u_range2 __pyx_string_tab[243] +#define __pyx_n_u_rectArea __pyx_string_tab[244] +#define __pyx_n_u_roots __pyx_string_tab[245] +#define __pyx_n_u_rotate __pyx_string_tab[246] +#define __pyx_n_u_round __pyx_string_tab[247] +#define __pyx_n_u_s __pyx_string_tab[248] +#define __pyx_n_u_s1 __pyx_string_tab[249] +#define __pyx_n_u_s1x __pyx_string_tab[250] +#define __pyx_n_u_s1y __pyx_string_tab[251] +#define __pyx_n_u_s2 __pyx_string_tab[252] +#define __pyx_n_u_s2x __pyx_string_tab[253] +#define __pyx_n_u_s2y __pyx_string_tab[254] +#define __pyx_n_u_scale __pyx_string_tab[255] +#define __pyx_n_u_sectRect __pyx_string_tab[256] +#define __pyx_n_u_seen __pyx_string_tab[257] +#define __pyx_n_u_seg __pyx_string_tab[258] +#define __pyx_n_u_seg1 __pyx_string_tab[259] +#define __pyx_n_u_seg2 __pyx_string_tab[260] +#define __pyx_n_u_segment __pyx_string_tab[261] +#define __pyx_n_u_segmentPointAtT __pyx_string_tab[262] +#define __pyx_n_u_segmentSegmentIntersections __pyx_string_tab[263] +#define __pyx_n_u_segmentrepr __pyx_string_tab[264] +#define __pyx_n_u_segmentrepr_locals_genexpr __pyx_string_tab[265] +#define __pyx_n_u_segments __pyx_string_tab[266] +#define __pyx_n_u_send __pyx_string_tab[267] +#define __pyx_n_u_set_name __pyx_string_tab[268] +#define __pyx_n_u_setdefault __pyx_string_tab[269] +#define __pyx_n_u_slope12 __pyx_string_tab[270] +#define __pyx_n_u_slope34 __pyx_string_tab[271] +#define __pyx_n_u_solutions __pyx_string_tab[272] +#define __pyx_n_u_solveCubic __pyx_string_tab[273] +#define __pyx_n_u_solveQuadratic __pyx_string_tab[274] +#define __pyx_n_u_split __pyx_string_tab[275] +#define __pyx_n_u_splitCubic __pyx_string_tab[276] +#define __pyx_n_u_splitCubicAtT __pyx_string_tab[277] +#define __pyx_n_u_splitCubicAtTC __pyx_string_tab[278] +#define __pyx_n_u_splitCubicAtTC_2 __pyx_string_tab[279] +#define __pyx_n_u_splitCubicAtT_2 __pyx_string_tab[280] +#define __pyx_n_u_splitCubicIntoTwoAtTC __pyx_string_tab[281] +#define __pyx_n_u_splitCubic_locals_genexpr __pyx_string_tab[282] +#define __pyx_n_u_splitLine __pyx_string_tab[283] +#define __pyx_n_u_splitQuadratic __pyx_string_tab[284] +#define __pyx_n_u_splitQuadraticAtT __pyx_string_tab[285] +#define __pyx_n_u_splitQuadraticAtT_2 __pyx_string_tab[286] +#define __pyx_n_u_splitQuadratic_locals_genexpr __pyx_string_tab[287] +#define __pyx_n_u_split_cubic_into_two __pyx_string_tab[288] +#define __pyx_n_u_split_segment_at_t __pyx_string_tab[289] +#define __pyx_n_u_sqrt __pyx_string_tab[290] +#define __pyx_n_u_start __pyx_string_tab[291] +#define __pyx_n_u_swapped __pyx_string_tab[292] +#define __pyx_n_u_sx __pyx_string_tab[293] +#define __pyx_n_u_sy __pyx_string_tab[294] +#define __pyx_n_u_sys __pyx_string_tab[295] +#define __pyx_n_u_t __pyx_string_tab[296] +#define __pyx_n_u_t1 __pyx_string_tab[297] +#define __pyx_n_u_t1_2 __pyx_string_tab[298] +#define __pyx_n_u_t1_3 __pyx_string_tab[299] +#define __pyx_n_u_t2 __pyx_string_tab[300] +#define __pyx_n_u_test __pyx_string_tab[301] +#define __pyx_n_u_testmod __pyx_string_tab[302] +#define __pyx_n_u_theta __pyx_string_tab[303] +#define __pyx_n_u_throw __pyx_string_tab[304] +#define __pyx_n_u_tolerance __pyx_string_tab[305] +#define __pyx_n_u_transformPoints __pyx_string_tab[306] +#define __pyx_n_u_translate __pyx_string_tab[307] +#define __pyx_n_u_ts __pyx_string_tab[308] +#define __pyx_n_u_two __pyx_string_tab[309] +#define __pyx_n_u_unique_key __pyx_string_tab[310] +#define __pyx_n_u_unique_values __pyx_string_tab[311] +#define __pyx_n_u_v0 __pyx_string_tab[312] +#define __pyx_n_u_v1 __pyx_string_tab[313] +#define __pyx_n_u_v2 __pyx_string_tab[314] +#define __pyx_n_u_v3 __pyx_string_tab[315] +#define __pyx_n_u_v4 __pyx_string_tab[316] +#define __pyx_n_u_value __pyx_string_tab[317] +#define __pyx_n_u_values __pyx_string_tab[318] +#define __pyx_n_u_where __pyx_string_tab[319] +#define __pyx_n_u_x __pyx_string_tab[320] +#define __pyx_n_u_x0 __pyx_string_tab[321] +#define __pyx_n_u_x1 __pyx_string_tab[322] +#define __pyx_n_u_x2 __pyx_string_tab[323] +#define __pyx_n_u_x3 __pyx_string_tab[324] +#define __pyx_n_u_x4 __pyx_string_tab[325] +#define __pyx_n_u_xDiff __pyx_string_tab[326] +#define __pyx_n_u_xRoots __pyx_string_tab[327] +#define __pyx_n_u_y __pyx_string_tab[328] +#define __pyx_n_u_y1 __pyx_string_tab[329] +#define __pyx_n_u_y2 __pyx_string_tab[330] +#define __pyx_n_u_y3 __pyx_string_tab[331] +#define __pyx_n_u_y4 __pyx_string_tab[332] +#define __pyx_n_u_yDiff __pyx_string_tab[333] +#define __pyx_n_u_yRoots __pyx_string_tab[334] +#define __pyx_kp_b_iso88591_0_2Q_2Rq_U_A_r_2Rq_r_b_Bb_7_Bb __pyx_string_tab[335] +#define __pyx_kp_b_iso88591_1 __pyx_string_tab[336] +#define __pyx_kp_b_iso88591_1A_at6_1_q_F_4vRq_1L_AU_Qe3auD __pyx_string_tab[337] +#define __pyx_kp_b_iso88591_1_Ql_1 __pyx_string_tab[338] +#define __pyx_kp_b_iso88591_1_a_r_wb_gRvWBfA __pyx_string_tab[339] +#define __pyx_kp_b_iso88591_2B_1_1 __pyx_string_tab[340] +#define __pyx_kp_b_iso88591_2Q_2Rq_U_A_7_E_4r_3gRr_4r_b_2U __pyx_string_tab[341] +#define __pyx_kp_b_iso88591_2Q_2Rq_U_A_r_b_1A_Cwb_Cq_2U_Cr __pyx_string_tab[342] +#define __pyx_kp_b_iso88591_2S_2Rs_Cq_2Rs_Bc_2Rs_3b_Bb_1A_2 __pyx_string_tab[343] +#define __pyx_kp_b_iso88591_2_Q_r_wb_gRvWBa __pyx_string_tab[344] +#define __pyx_kp_b_iso88591_3as_A_Qc_4r_AS_b_1Cr_uBe2XS_RuB __pyx_string_tab[345] +#define __pyx_kp_b_iso88591_3b_S_b_Ba_c_3b_2T_1_c_4r_d_HA_d __pyx_string_tab[346] +#define __pyx_kp_b_iso88591_4r_Rq_avU_uA __pyx_string_tab[347] +#define __pyx_kp_b_iso88591_6_rQR __pyx_string_tab[348] +#define __pyx_kp_b_iso88591_6_s_T_AU_uA_1O1A_2Q_aq_t1_r_e5 __pyx_string_tab[349] +#define __pyx_kp_b_iso88591_7_F_6 __pyx_string_tab[350] +#define __pyx_kp_b_iso88591_AS_Cr_3b_1Cr_c_S_Cr_AS __pyx_string_tab[351] +#define __pyx_kp_b_iso88591_AT_5_A_2Q_Ba_Ba_Ba_AT_4r_RuBa_A __pyx_string_tab[352] +#define __pyx_kp_b_iso88591_A_t3aq_2Qaq __pyx_string_tab[353] +#define __pyx_kp_b_iso88591_B_A_2T_5Rt2_PPRRS_AT_5_A_Bd_6b __pyx_string_tab[354] +#define __pyx_kp_b_iso88591_F_s_Qe5_a_1N_A_aq_t1_r_e1_Qc_D __pyx_string_tab[355] +#define __pyx_kp_b_iso88591_G1A_1_D_as_3b_Qd_Qc_5_87_1F_AQe __pyx_string_tab[356] +#define __pyx_kp_b_iso88591_H_b_b_S_r_A_r_a_s_c_1_r_D_2Rr_S __pyx_string_tab[357] +#define __pyx_kp_b_iso88591_L_s_3b_Qc_A_Qa_2Q_2Q_2Q_Bc_4r_R __pyx_string_tab[358] +#define __pyx_kp_b_iso88591_M_m1A_m1A_t1_q_t1_q_HAYa_t1_q_x __pyx_string_tab[359] +#define __pyx_kp_b_iso88591_Q_Q_Q_Q_Rt2Q_Rt2Q_Rt2T_1_Rt2T_1 __pyx_string_tab[360] +#define __pyx_kp_b_iso88591_Q_Q_Q_Q_RuBa_RuBa_Rt2T_1_Rt2T_1 __pyx_string_tab[361] +#define __pyx_kp_b_iso88591_Q_Q_Q_Rt2Q_Rt2Q_Bc_1_Bc_1_1D_d __pyx_string_tab[362] +#define __pyx_kp_b_iso88591_Q_Q_Q_RuBa_RuBa_Bc_1_Bc_1_1D_d __pyx_string_tab[363] +#define __pyx_kp_b_iso88591_Q_Q_Q_s_3b_Bhd_Qc_4r_s_3b_Bc_Rq __pyx_string_tab[364] +#define __pyx_kp_b_iso88591_Qa_gQc_gQa_q_Q_Q_Q_Q_U_3at2Q_Rq __pyx_string_tab[365] +#define __pyx_kp_b_iso88591_Qa_q_gQc_gQa_Q_Q_Q_U_3at2Q_Rq_R __pyx_string_tab[366] +#define __pyx_kp_b_iso88591_Qas_F_4s_1Cr_q_Qas_F_4s_1Cr_q_5 __pyx_string_tab[367] +#define __pyx_kp_b_iso88591_Qe3C1A_s_7_Q_3d_1_aq_Qat1AQ_AWC __pyx_string_tab[368] +#define __pyx_kp_b_iso88591_Rq_Rq_2Q_A_Cq_vS_s_4r_t1Cq_s_Rq __pyx_string_tab[369] +#define __pyx_kp_b_iso88591_S_1Cr_S_1Cr __pyx_string_tab[370] +#define __pyx_kp_b_iso88591_T_t6_V4v_e5PQ_Rq_Rq_Rq_Rq_Qb_E __pyx_string_tab[371] +#define __pyx_kp_b_iso88591_T_t6_V_5_Q_Rq_Rq_A_t3a_WAQc_1_t __pyx_string_tab[372] +#define __pyx_kp_b_iso88591_T_uBa_wb_E_a __pyx_string_tab[373] +#define __pyx_kp_b_iso88591__4 __pyx_string_tab[374] +#define __pyx_kp_b_iso88591__5 __pyx_string_tab[375] +#define __pyx_kp_b_iso88591_a_2 __pyx_string_tab[376] +#define __pyx_kp_b_iso88591_a_s_6_3aq_gV1_s_6_1_3avRq_31F_2 __pyx_string_tab[377] +#define __pyx_kp_b_iso88591_q __pyx_string_tab[378] +#define __pyx_kp_b_iso88591_q_q_q_q_HAU_t4xq_U_d_hauTU_q_HA __pyx_string_tab[379] +#define __pyx_kp_b_iso88591_s_3b_3as_A_A_AQb_Rr_2T_2Rq_3c_a __pyx_string_tab[380] +#define __pyx_kp_b_iso88591_s_3c_4q_q_3a_r_L_s_3c_Q_AS_1_Bc __pyx_string_tab[381] +#define __pyx_kp_b_iso88591_s_3c_A_AS_1_b_AQ __pyx_string_tab[382] +#define __pyx_kp_b_iso88591_s_5_1_2U_AU_Q_q_AU_Q_Be1_AQ __pyx_string_tab[383] +#define __pyx_kp_b_iso88591_s_7_Q_a_AWCq_a_j_A_b_a_6_WA_T_C __pyx_string_tab[384] +#define __pyx_kp_b_iso88591_s_Qe5_Qc_D __pyx_string_tab[385] +#define __pyx_kp_b_iso88591_s_T_AU_uA_N_3c_D_e1Baq_6_r_3d_1 __pyx_string_tab[386] +#define __pyx_float_0_0 __pyx_number_tab[0] +#define __pyx_float_0_5 __pyx_number_tab[1] +#define __pyx_float_1_0 __pyx_number_tab[2] +#define __pyx_float_neg_2_0 __pyx_number_tab[3] +#define __pyx_float_2_0 __pyx_number_tab[4] +#define __pyx_float_3_0 __pyx_number_tab[5] +#define __pyx_float_4_0 __pyx_number_tab[6] +#define __pyx_float_9_0 __pyx_number_tab[7] +#define __pyx_float_1eneg_3 __pyx_number_tab[8] +#define __pyx_float_1eneg_9 __pyx_number_tab[9] +#define __pyx_float_27_0 __pyx_number_tab[10] +#define __pyx_float_54_0 __pyx_number_tab[11] +#define __pyx_float_0_005 __pyx_number_tab[12] +#define __pyx_float_0_125 __pyx_number_tab[13] +#define __pyx_float_1eneg_10 __pyx_number_tab[14] +#define __pyx_int_0 __pyx_number_tab[15] +#define __pyx_int_neg_1 __pyx_number_tab[16] +#define __pyx_int_1 __pyx_number_tab[17] +#define __pyx_int_2 __pyx_number_tab[18] +#define __pyx_int_3 __pyx_number_tab[19] +#define __pyx_int_6 __pyx_number_tab[20] +/* #### Code section: module_state_clear ### */ +#if CYTHON_USE_MODULE_STATE +static CYTHON_SMALL_CODE int __pyx_m_clear(PyObject *m) { + __pyx_mstatetype *clear_module_state = __Pyx_PyModule_GetState(m); + if (!clear_module_state) return 0; + Py_CLEAR(clear_module_state->__pyx_d); + Py_CLEAR(clear_module_state->__pyx_b); + Py_CLEAR(clear_module_state->__pyx_cython_runtime); + Py_CLEAR(clear_module_state->__pyx_empty_tuple); + Py_CLEAR(clear_module_state->__pyx_empty_bytes); + Py_CLEAR(clear_module_state->__pyx_empty_unicode); + #if CYTHON_PEP489_MULTI_PHASE_INIT + __Pyx_State_RemoveModule(NULL); + #endif + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_defaults); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_defaults); + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr); + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr); + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC); + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC); + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr); + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t); + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr); + Py_CLEAR(clear_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr); + Py_CLEAR(clear_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr); + for (int i=0; i<2; ++i) { Py_CLEAR(clear_module_state->__pyx_slice[i]); } + for (int i=0; i<4; ++i) { Py_CLEAR(clear_module_state->__pyx_tuple[i]); } + for (int i=0; i<54; ++i) { Py_CLEAR(clear_module_state->__pyx_codeobj_tab[i]); } + for (int i=0; i<387; ++i) { Py_CLEAR(clear_module_state->__pyx_string_tab[i]); } + for (int i=0; i<21; ++i) { Py_CLEAR(clear_module_state->__pyx_number_tab[i]); } +/* #### Code section: module_state_clear_contents ### */ +/* CommonTypesMetaclass.module_state_clear */ +Py_CLEAR(clear_module_state->__pyx_CommonTypesMetaclassType); + +/* Generator.module_state_clear */ +Py_CLEAR(clear_module_state->__pyx_GeneratorType); + +/* CythonFunctionShared.module_state_clear */ +Py_CLEAR(clear_module_state->__pyx_CyFunctionType); + +/* #### Code section: module_state_clear_end ### */ +return 0; +} +#endif +/* #### Code section: module_state_traverse ### */ +#if CYTHON_USE_MODULE_STATE +static CYTHON_SMALL_CODE int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { + __pyx_mstatetype *traverse_module_state = __Pyx_PyModule_GetState(m); + if (!traverse_module_state) return 0; + Py_VISIT(traverse_module_state->__pyx_d); + Py_VISIT(traverse_module_state->__pyx_b); + Py_VISIT(traverse_module_state->__pyx_cython_runtime); + __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_tuple); + __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_bytes); + __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_unicode); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_defaults); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_defaults); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr); + Py_VISIT(traverse_module_state->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr); + Py_VISIT(traverse_module_state->__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr); + for (int i=0; i<2; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_slice[i]); } + for (int i=0; i<4; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_tuple[i]); } + for (int i=0; i<54; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_codeobj_tab[i]); } + for (int i=0; i<387; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_string_tab[i]); } + for (int i=0; i<21; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_number_tab[i]); } +/* #### Code section: module_state_traverse_contents ### */ +/* CommonTypesMetaclass.module_state_traverse */ +Py_VISIT(traverse_module_state->__pyx_CommonTypesMetaclassType); + +/* Generator.module_state_traverse */ +Py_VISIT(traverse_module_state->__pyx_GeneratorType); + +/* CythonFunctionShared.module_state_traverse */ +Py_VISIT(traverse_module_state->__pyx_CyFunctionType); + +/* #### Code section: module_state_traverse_end ### */ +return 0; +} +#endif +/* #### Code section: module_code ### */ + +/* "fontTools/misc/bezierTools.py":56 + * + * + * def calcCubicArcLength(pt1, pt2, pt3, pt4, tolerance=0.005): # <<<<<<<<<<<<<< + * """Calculates the arc length for a cubic Bezier segment. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_1calcCubicArcLength(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_calcCubicArcLength, "calcCubicArcLength(pt1, pt2, pt3, pt4, tolerance=0.005)\n\nCalculates the arc length for a cubic Bezier segment.\n\nWhereas :func:`approximateCubicArcLength` approximates the length, this\nfunction calculates it by \"measuring\", recursively dividing the curve\nuntil the divided segments are shorter than ``tolerance``.\n\nArgs:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n tolerance: Controls the precision of the calcuation.\n\nReturns:\n Arc length value."); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_1calcCubicArcLength = {"calcCubicArcLength", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_1calcCubicArcLength, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_calcCubicArcLength}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_1calcCubicArcLength(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_pt4 = 0; + PyObject *__pyx_v_tolerance = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcCubicArcLength (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,&__pyx_mstate_global->__pyx_n_u_pt4,&__pyx_mstate_global->__pyx_n_u_tolerance,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 56, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 5: + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 56, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 56, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 56, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 56, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 56, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "calcCubicArcLength", 0) < (0)) __PYX_ERR(0, 56, __pyx_L3_error) + if (!values[4]) values[4] = __Pyx_NewRef(((PyObject *)((PyObject*)__pyx_mstate_global->__pyx_float_0_005))); + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("calcCubicArcLength", 0, 4, 5, i); __PYX_ERR(0, 56, __pyx_L3_error) } + } + } else { + switch (__pyx_nargs) { + case 5: + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 56, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 56, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 56, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 56, __pyx_L3_error) + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 56, __pyx_L3_error) + break; + default: goto __pyx_L5_argtuple_error; + } + if (!values[4]) values[4] = __Pyx_NewRef(((PyObject *)((PyObject*)__pyx_mstate_global->__pyx_float_0_005))); + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_pt4 = values[3]; + __pyx_v_tolerance = values[4]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcCubicArcLength", 0, 4, 5, __pyx_nargs); __PYX_ERR(0, 56, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicArcLength", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_calcCubicArcLength(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4, __pyx_v_tolerance); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_calcCubicArcLength(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4, PyObject *__pyx_v_tolerance) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + size_t __pyx_t_9; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcCubicArcLength", 0); + + /* "fontTools/misc/bezierTools.py":70 + * Arc length value. + * """ + * return calcCubicArcLengthC( # <<<<<<<<<<<<<< + * complex(*pt1), complex(*pt2), complex(*pt3), complex(*pt4), tolerance + * ) +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_calcCubicArcLengthC); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/misc/bezierTools.py":71 + * """ + * return calcCubicArcLengthC( + * complex(*pt1), complex(*pt2), complex(*pt3), complex(*pt4), tolerance # <<<<<<<<<<<<<< + * ) + * +*/ + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_pt1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_pt2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_pt3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_pt4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_8 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_9 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_9 = 0; + } + #endif + { + PyObject *__pyx_callargs[6] = {__pyx_t_2, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_t_8, __pyx_v_tolerance}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_9, (6-__pyx_t_9) | (__pyx_t_9*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":56 + * + * + * def calcCubicArcLength(pt1, pt2, pt3, pt4, tolerance=0.005): # <<<<<<<<<<<<<< + * """Calculates the arc length for a cubic Bezier segment. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicArcLength", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":75 + * + * + * def _split_cubic_into_two(p0, p1, p2, p3): # <<<<<<<<<<<<<< + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_3_split_cubic_into_two(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_2_split_cubic_into_two, "_split_cubic_into_two(p0, p1, p2, p3)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_3_split_cubic_into_two = {"_split_cubic_into_two", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_3_split_cubic_into_two, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_2_split_cubic_into_two}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_3_split_cubic_into_two(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_p0 = 0; + PyObject *__pyx_v_p1 = 0; + PyObject *__pyx_v_p2 = 0; + PyObject *__pyx_v_p3 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_split_cubic_into_two (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_p0,&__pyx_mstate_global->__pyx_n_u_p1,&__pyx_mstate_global->__pyx_n_u_p2,&__pyx_mstate_global->__pyx_n_u_p3,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 75, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 75, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 75, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 75, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 75, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_split_cubic_into_two", 0) < (0)) __PYX_ERR(0, 75, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_split_cubic_into_two", 1, 4, 4, i); __PYX_ERR(0, 75, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 75, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 75, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 75, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 75, __pyx_L3_error) + } + __pyx_v_p0 = values[0]; + __pyx_v_p1 = values[1]; + __pyx_v_p2 = values[2]; + __pyx_v_p3 = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_split_cubic_into_two", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 75, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._split_cubic_into_two", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_2_split_cubic_into_two(__pyx_self, __pyx_v_p0, __pyx_v_p1, __pyx_v_p2, __pyx_v_p3); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_2_split_cubic_into_two(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_p0, PyObject *__pyx_v_p1, PyObject *__pyx_v_p2, PyObject *__pyx_v_p3) { + PyObject *__pyx_v_mid = NULL; + PyObject *__pyx_v_deriv3 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_split_cubic_into_two", 0); + + /* "fontTools/misc/bezierTools.py":76 + * + * def _split_cubic_into_two(p0, p1, p2, p3): + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 # <<<<<<<<<<<<<< + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + * return ( +*/ + __pyx_t_1 = PyNumber_Add(__pyx_v_p1, __pyx_v_p2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyLong_MultiplyCObj(__pyx_mstate_global->__pyx_int_3, __pyx_t_1, 3, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_v_p0, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_p3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_mstate_global->__pyx_float_0_125); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_mid = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":77 + * def _split_cubic_into_two(p0, p1, p2, p3): + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 # <<<<<<<<<<<<<< + * return ( + * (p0, (p0 + p1) * 0.5, mid - deriv3, mid), +*/ + __pyx_t_1 = PyNumber_Add(__pyx_v_p3, __pyx_v_p2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_v_p1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_p0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_mstate_global->__pyx_float_0_125); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_deriv3 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":78 + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + * return ( # <<<<<<<<<<<<<< + * (p0, (p0 + p1) * 0.5, mid - deriv3, mid), + * (mid, mid + deriv3, (p2 + p3) * 0.5, p3), +*/ + __Pyx_XDECREF(__pyx_r); + + /* "fontTools/misc/bezierTools.py":79 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + * return ( + * (p0, (p0 + p1) * 0.5, mid - deriv3, mid), # <<<<<<<<<<<<<< + * (mid, mid + deriv3, (p2 + p3) * 0.5, p3), + * ) +*/ + __pyx_t_2 = PyNumber_Add(__pyx_v_p0, __pyx_v_p1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_mstate_global->__pyx_float_0_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Subtract(__pyx_v_mid, __pyx_v_deriv3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyTuple_New(4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_p0); + __Pyx_GIVEREF(__pyx_v_p0); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_p0) != (0)) __PYX_ERR(0, 79, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1) != (0)) __PYX_ERR(0, 79, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2) != (0)) __PYX_ERR(0, 79, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_mid); + __Pyx_GIVEREF(__pyx_v_mid); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 3, __pyx_v_mid) != (0)) __PYX_ERR(0, 79, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":80 + * return ( + * (p0, (p0 + p1) * 0.5, mid - deriv3, mid), + * (mid, mid + deriv3, (p2 + p3) * 0.5, p3), # <<<<<<<<<<<<<< + * ) + * +*/ + __pyx_t_2 = PyNumber_Add(__pyx_v_mid, __pyx_v_deriv3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Add(__pyx_v_p2, __pyx_v_p3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = PyNumber_Multiply(__pyx_t_1, __pyx_mstate_global->__pyx_float_0_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_mid); + __Pyx_GIVEREF(__pyx_v_mid); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_mid) != (0)) __PYX_ERR(0, 80, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2) != (0)) __PYX_ERR(0, 80, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_t_4) != (0)) __PYX_ERR(0, 80, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_p3); + __Pyx_GIVEREF(__pyx_v_p3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_p3) != (0)) __PYX_ERR(0, 80, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":79 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 + * return ( + * (p0, (p0 + p1) * 0.5, mid - deriv3, mid), # <<<<<<<<<<<<<< + * (mid, mid + deriv3, (p2 + p3) * 0.5, p3), + * ) +*/ + __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3) != (0)) __PYX_ERR(0, 79, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1) != (0)) __PYX_ERR(0, 79, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_t_1 = 0; + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":75 + * + * + * def _split_cubic_into_two(p0, p1, p2, p3): # <<<<<<<<<<<<<< + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("fontTools.misc.bezierTools._split_cubic_into_two", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_mid); + __Pyx_XDECREF(__pyx_v_deriv3); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":84 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * p0=cython.complex, +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_5_calcCubicArcLengthCRecurse(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_4_calcCubicArcLengthCRecurse, "_calcCubicArcLengthCRecurse(double mult, double complex p0, double complex p1, double complex p2, double complex p3)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_5_calcCubicArcLengthCRecurse = {"_calcCubicArcLengthCRecurse", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_5_calcCubicArcLengthCRecurse, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_4_calcCubicArcLengthCRecurse}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_5_calcCubicArcLengthCRecurse(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + double __pyx_v_mult; + __pyx_t_double_complex __pyx_v_p0; + __pyx_t_double_complex __pyx_v_p1; + __pyx_t_double_complex __pyx_v_p2; + __pyx_t_double_complex __pyx_v_p3; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_calcCubicArcLengthCRecurse (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_mult,&__pyx_mstate_global->__pyx_n_u_p0,&__pyx_mstate_global->__pyx_n_u_p1,&__pyx_mstate_global->__pyx_n_u_p2,&__pyx_mstate_global->__pyx_n_u_p3,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 84, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 5: + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 84, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 84, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 84, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 84, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 84, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_calcCubicArcLengthCRecurse", 0) < (0)) __PYX_ERR(0, 84, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 5; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_calcCubicArcLengthCRecurse", 1, 5, 5, i); __PYX_ERR(0, 84, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 5)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 84, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 84, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 84, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 84, __pyx_L3_error) + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 84, __pyx_L3_error) + } + __pyx_v_mult = __Pyx_PyFloat_AsDouble(values[0]); if (unlikely((__pyx_v_mult == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 92, __pyx_L3_error) + __pyx_v_p0 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 92, __pyx_L3_error) + __pyx_v_p1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 92, __pyx_L3_error) + __pyx_v_p2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[3]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 92, __pyx_L3_error) + __pyx_v_p3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[4]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 92, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_calcCubicArcLengthCRecurse", 1, 5, 5, __pyx_nargs); __PYX_ERR(0, 84, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._calcCubicArcLengthCRecurse", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_4_calcCubicArcLengthCRecurse(__pyx_self, __pyx_v_mult, __pyx_v_p0, __pyx_v_p1, __pyx_v_p2, __pyx_v_p3); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_4_calcCubicArcLengthCRecurse(CYTHON_UNUSED PyObject *__pyx_self, double __pyx_v_mult, __pyx_t_double_complex __pyx_v_p0, __pyx_t_double_complex __pyx_v_p1, __pyx_t_double_complex __pyx_v_p2, __pyx_t_double_complex __pyx_v_p3) { + double __pyx_v_arch; + double __pyx_v_box; + PyObject *__pyx_v_one = NULL; + PyObject *__pyx_v_two = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + size_t __pyx_t_9; + PyObject *(*__pyx_t_10)(PyObject *); + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_calcCubicArcLengthCRecurse", 0); + + /* "fontTools/misc/bezierTools.py":93 + * @cython.locals(mult=cython.double, arch=cython.double, box=cython.double) + * def _calcCubicArcLengthCRecurse(mult, p0, p1, p2, p3): + * arch = abs(p0 - p3) # <<<<<<<<<<<<<< + * box = abs(p0 - p1) + abs(p1 - p2) + abs(p2 - p3) + * if arch * mult + EPSILON >= box: +*/ + __pyx_v_arch = __Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_p0, __pyx_v_p3)); + + /* "fontTools/misc/bezierTools.py":94 + * def _calcCubicArcLengthCRecurse(mult, p0, p1, p2, p3): + * arch = abs(p0 - p3) + * box = abs(p0 - p1) + abs(p1 - p2) + abs(p2 - p3) # <<<<<<<<<<<<<< + * if arch * mult + EPSILON >= box: + * return (arch + box) * 0.5 +*/ + __pyx_v_box = ((__Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_p0, __pyx_v_p1)) + __Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_p1, __pyx_v_p2))) + __Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_p2, __pyx_v_p3))); + + /* "fontTools/misc/bezierTools.py":95 + * arch = abs(p0 - p3) + * box = abs(p0 - p1) + abs(p1 - p2) + abs(p2 - p3) + * if arch * mult + EPSILON >= box: # <<<<<<<<<<<<<< + * return (arch + box) * 0.5 + * else: +*/ + __pyx_t_1 = PyFloat_FromDouble((__pyx_v_arch * __pyx_v_mult)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 95, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_EPSILON); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 95, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Add(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 95, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyFloat_FromDouble(__pyx_v_box); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 95, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_t_2, Py_GE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 95, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 95, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":96 + * box = abs(p0 - p1) + abs(p1 - p2) + abs(p2 - p3) + * if arch * mult + EPSILON >= box: + * return (arch + box) * 0.5 # <<<<<<<<<<<<<< + * else: + * one, two = _split_cubic_into_two(p0, p1, p2, p3) +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyFloat_FromDouble(((__pyx_v_arch + __pyx_v_box) * 0.5)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 96, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":95 + * arch = abs(p0 - p3) + * box = abs(p0 - p1) + abs(p1 - p2) + abs(p2 - p3) + * if arch * mult + EPSILON >= box: # <<<<<<<<<<<<<< + * return (arch + box) * 0.5 + * else: +*/ + } + + /* "fontTools/misc/bezierTools.py":98 + * return (arch + box) * 0.5 + * else: + * one, two = _split_cubic_into_two(p0, p1, p2, p3) # <<<<<<<<<<<<<< + * return _calcCubicArcLengthCRecurse(mult, *one) + _calcCubicArcLengthCRecurse( + * mult, *two +*/ + /*else*/ { + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_split_cubic_into_two); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = __pyx_PyComplex_FromComplex(__pyx_v_p0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __pyx_PyComplex_FromComplex(__pyx_v_p1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __pyx_PyComplex_FromComplex(__pyx_v_p2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __pyx_PyComplex_FromComplex(__pyx_v_p3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_9 = 0; + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_2, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_t_8}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_9, (5-__pyx_t_9) | (__pyx_t_9*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 98, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_3); + __pyx_t_8 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_8); + } else { + __pyx_t_3 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_3); + __pyx_t_8 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_8); + } + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_8 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_7 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_10 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_7); + index = 0; __pyx_t_3 = __pyx_t_10(__pyx_t_7); if (unlikely(!__pyx_t_3)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 1; __pyx_t_8 = __pyx_t_10(__pyx_t_7); if (unlikely(!__pyx_t_8)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_8); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_7), 2) < (0)) __PYX_ERR(0, 98, __pyx_L1_error) + __pyx_t_10 = NULL; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L5_unpacking_done; + __pyx_L4_unpacking_failed:; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_10 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 98, __pyx_L1_error) + __pyx_L5_unpacking_done:; + } + __pyx_v_one = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_two = __pyx_t_8; + __pyx_t_8 = 0; + + /* "fontTools/misc/bezierTools.py":99 + * else: + * one, two = _split_cubic_into_two(p0, p1, p2, p3) + * return _calcCubicArcLengthCRecurse(mult, *one) + _calcCubicArcLengthCRecurse( # <<<<<<<<<<<<<< + * mult, *two + * ) +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_calcCubicArcLengthCRecurse); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_8 = PyFloat_FromDouble(__pyx_v_mult); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_8); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_8) != (0)) __PYX_ERR(0, 99, __pyx_L1_error); + __pyx_t_8 = 0; + __pyx_t_8 = __Pyx_PySequence_Tuple(__pyx_v_one); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_7 = PyNumber_Add(__pyx_t_3, __pyx_t_8); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_7, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_calcCubicArcLengthCRecurse); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + + /* "fontTools/misc/bezierTools.py":100 + * one, two = _split_cubic_into_two(p0, p1, p2, p3) + * return _calcCubicArcLengthCRecurse(mult, *one) + _calcCubicArcLengthCRecurse( + * mult, *two # <<<<<<<<<<<<<< + * ) + * +*/ + __pyx_t_1 = PyFloat_FromDouble(__pyx_v_mult); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 100, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/misc/bezierTools.py":99 + * else: + * one, two = _split_cubic_into_two(p0, p1, p2, p3) + * return _calcCubicArcLengthCRecurse(mult, *one) + _calcCubicArcLengthCRecurse( # <<<<<<<<<<<<<< + * mult, *two + * ) +*/ + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 99, __pyx_L1_error); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":100 + * one, two = _split_cubic_into_two(p0, p1, p2, p3) + * return _calcCubicArcLengthCRecurse(mult, *one) + _calcCubicArcLengthCRecurse( + * mult, *two # <<<<<<<<<<<<<< + * ) + * +*/ + __pyx_t_1 = __Pyx_PySequence_Tuple(__pyx_v_two); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/misc/bezierTools.py":99 + * else: + * one, two = _split_cubic_into_two(p0, p1, p2, p3) + * return _calcCubicArcLengthCRecurse(mult, *one) + _calcCubicArcLengthCRecurse( # <<<<<<<<<<<<<< + * mult, *two + * ) +*/ + __pyx_t_6 = PyNumber_Add(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyNumber_Add(__pyx_t_8, __pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; + } + + /* "fontTools/misc/bezierTools.py":84 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * p0=cython.complex, +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("fontTools.misc.bezierTools._calcCubicArcLengthCRecurse", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_one); + __Pyx_XDECREF(__pyx_v_two); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":104 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_7calcCubicArcLengthC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_6calcCubicArcLengthC, "calcCubicArcLengthC(double complex pt1, double complex pt2, double complex pt3, double complex pt4, double tolerance=0.005)\n\nCalculates the arc length for a cubic Bezier segment.\n\nArgs:\n pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers.\n tolerance: Controls the precision of the calcuation.\n\nReturns:\n Arc length value."); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_7calcCubicArcLengthC = {"calcCubicArcLengthC", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_7calcCubicArcLengthC, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_6calcCubicArcLengthC}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_7calcCubicArcLengthC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_pt1; + __pyx_t_double_complex __pyx_v_pt2; + __pyx_t_double_complex __pyx_v_pt3; + __pyx_t_double_complex __pyx_v_pt4; + double __pyx_v_tolerance; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcCubicArcLengthC (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,&__pyx_mstate_global->__pyx_n_u_pt4,&__pyx_mstate_global->__pyx_n_u_tolerance,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 104, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 5: + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 104, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 104, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 104, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 104, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 104, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "calcCubicArcLengthC", 0) < (0)) __PYX_ERR(0, 104, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("calcCubicArcLengthC", 0, 4, 5, i); __PYX_ERR(0, 104, __pyx_L3_error) } + } + } else { + switch (__pyx_nargs) { + case 5: + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 104, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 104, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 104, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 104, __pyx_L3_error) + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 104, __pyx_L3_error) + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_pt1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L3_error) + __pyx_v_pt2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L3_error) + __pyx_v_pt3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L3_error) + __pyx_v_pt4 = __Pyx_PyComplex_As___pyx_t_double_complex(values[3]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L3_error) + if (values[4]) { + __pyx_v_tolerance = __Pyx_PyFloat_AsDouble(values[4]); if (unlikely((__pyx_v_tolerance == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L3_error) + } else { + __pyx_v_tolerance = ((double)((double)0.005)); + } + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcCubicArcLengthC", 0, 4, 5, __pyx_nargs); __PYX_ERR(0, 104, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicArcLengthC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_6calcCubicArcLengthC(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4, __pyx_v_tolerance); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_6calcCubicArcLengthC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4, double __pyx_v_tolerance) { + double __pyx_v_mult; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + size_t __pyx_t_9; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcCubicArcLengthC", 0); + + /* "fontTools/misc/bezierTools.py":125 + * Arc length value. + * """ + * mult = 1.0 + 1.5 * tolerance # The 1.5 is a empirical hack; no math # <<<<<<<<<<<<<< + * return _calcCubicArcLengthCRecurse(mult, pt1, pt2, pt3, pt4) + * +*/ + __pyx_v_mult = (1.0 + (1.5 * __pyx_v_tolerance)); + + /* "fontTools/misc/bezierTools.py":126 + * """ + * mult = 1.0 + 1.5 * tolerance # The 1.5 is a empirical hack; no math + * return _calcCubicArcLengthCRecurse(mult, pt1, pt2, pt3, pt4) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_calcCubicArcLengthCRecurse); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyFloat_FromDouble(__pyx_v_mult); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __pyx_PyComplex_FromComplex(__pyx_v_pt1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __pyx_PyComplex_FromComplex(__pyx_v_pt2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __pyx_PyComplex_FromComplex(__pyx_v_pt3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __pyx_PyComplex_FromComplex(__pyx_v_pt4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_9 = 0; + } + #endif + { + PyObject *__pyx_callargs[6] = {__pyx_t_2, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_t_8}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_9, (6-__pyx_t_9) | (__pyx_t_9*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":104 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicArcLengthC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":133 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.returns(cython.double) +*/ + +static CYTHON_INLINE double __pyx_f_9fontTools_4misc_11bezierTools__dot(__pyx_t_double_complex __pyx_v_v1, __pyx_t_double_complex __pyx_v_v2) { + double __pyx_r; + + /* "fontTools/misc/bezierTools.py":138 + * @cython.locals(v1=cython.complex, v2=cython.complex) + * def _dot(v1, v2): + * return (v1 * v2.conjugate()).real # <<<<<<<<<<<<<< + * + * +*/ + __pyx_r = __Pyx_CREAL(__Pyx_c_prod_double(__pyx_v_v1, __Pyx_c_conj_double(__pyx_v_v2))); + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":133 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.returns(cython.double) +*/ + + /* function exit code */ + __pyx_L0:; + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":141 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.returns(cython.double) +*/ + +static CYTHON_INLINE double __pyx_f_9fontTools_4misc_11bezierTools__intSecAtan(double __pyx_v_x) { + double __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + size_t __pyx_t_6; + double __pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_intSecAtan", 0); + + /* "fontTools/misc/bezierTools.py":148 + * # In : sympy.integrate(sp.sec(sp.atan(x))) + * # Out: x*sqrt(x**2 + 1)/2 + asinh(x)/2 + * return x * math.sqrt(x**2 + 1) / 2 + math.asinh(x) / 2 # <<<<<<<<<<<<<< + * + * +*/ + __pyx_t_1 = PyFloat_FromDouble(__pyx_v_x); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_sqrt); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyFloat_FromDouble((pow(__pyx_v_x, 2.0) + 1.0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_6 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5); + assert(__pyx_t_3); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_5, __pyx__function); + __pyx_t_6 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_t_4}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_5, __pyx_callargs+__pyx_t_6, (2-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __pyx_t_5 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyLong_TrueDivideObjC(__pyx_t_5, __pyx_mstate_global->__pyx_int_2, 2, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_1 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_asinh); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyFloat_FromDouble(__pyx_v_x); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_6 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_1); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_6 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_t_4}; + __pyx_t_5 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_6, (2-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + } + __pyx_t_3 = __Pyx_PyLong_TrueDivideObjC(__pyx_t_5, __pyx_mstate_global->__pyx_int_2, 2, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = PyNumber_Add(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = __Pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_r = __pyx_t_7; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":141 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.returns(cython.double) +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools._intSecAtan", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":151 + * + * + * def calcQuadraticArcLength(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the arc length for a quadratic Bezier segment. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_9calcQuadraticArcLength(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_8calcQuadraticArcLength, "calcQuadraticArcLength(pt1, pt2, pt3)\n\nCalculates the arc length for a quadratic Bezier segment.\n\nArgs:\n pt1: Start point of the Bezier as 2D tuple.\n pt2: Handle point of the Bezier as 2D tuple.\n pt3: End point of the Bezier as 2D tuple.\n\nReturns:\n Arc length value.\n\nExample::\n\n >>> calcQuadraticArcLength((0, 0), (0, 0), (0, 0)) # empty segment\n 0.0\n >>> calcQuadraticArcLength((0, 0), (50, 0), (80, 0)) # collinear points\n 80.0\n >>> calcQuadraticArcLength((0, 0), (0, 50), (0, 80)) # collinear points vertical\n 80.0\n >>> calcQuadraticArcLength((0, 0), (50, 20), (100, 40)) # collinear points\n 107.70329614269008\n >>> calcQuadraticArcLength((0, 0), (0, 100), (100, 0))\n 154.02976155645263\n >>> calcQuadraticArcLength((0, 0), (0, 50), (100, 0))\n 120.21581243984076\n >>> calcQuadraticArcLength((0, 0), (50, -10), (80, 50))\n 102.53273816445825\n >>> calcQuadraticArcLength((0, 0), (40, 0), (-40, 0)) # collinear points, control point outside\n 66.66666666666667\n >>> calcQuadraticArcLength((0, 0), (40, 0), (0, 0)) # collinear points, looping back\n 40.0"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_9calcQuadraticArcLength = {"calcQuadraticArcLength", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_9calcQuadraticArcLength, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_8calcQuadraticArcLength}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_9calcQuadraticArcLength(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcQuadraticArcLength (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 151, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 151, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 151, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 151, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "calcQuadraticArcLength", 0) < (0)) __PYX_ERR(0, 151, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 3; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("calcQuadraticArcLength", 1, 3, 3, i); __PYX_ERR(0, 151, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 151, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 151, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 151, __pyx_L3_error) + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcQuadraticArcLength", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 151, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticArcLength", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_8calcQuadraticArcLength(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_8calcQuadraticArcLength(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + size_t __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcQuadraticArcLength", 0); + + /* "fontTools/misc/bezierTools.py":183 + * 40.0 + * """ + * return calcQuadraticArcLengthC(complex(*pt1), complex(*pt2), complex(*pt3)) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_calcQuadraticArcLengthC); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_pt1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_pt2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_pt3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_8 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_8 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_2, __pyx_t_5, __pyx_t_6, __pyx_t_7}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_8, (4-__pyx_t_8) | (__pyx_t_8*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 183, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":151 + * + * + * def calcQuadraticArcLength(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the arc length for a quadratic Bezier segment. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticArcLength", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":186 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_11calcQuadraticArcLengthC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_10calcQuadraticArcLengthC, "calcQuadraticArcLengthC(double complex pt1, double complex pt2, double complex pt3)\n\nCalculates the arc length for a quadratic Bezier segment.\n\nArgs:\n pt1: Start point of the Bezier as a complex number.\n pt2: Handle point of the Bezier as a complex number.\n pt3: End point of the Bezier as a complex number.\n\nReturns:\n Arc length value."); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_11calcQuadraticArcLengthC = {"calcQuadraticArcLengthC", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_11calcQuadraticArcLengthC, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_10calcQuadraticArcLengthC}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_11calcQuadraticArcLengthC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_pt1; + __pyx_t_double_complex __pyx_v_pt2; + __pyx_t_double_complex __pyx_v_pt3; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcQuadraticArcLengthC (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 186, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 186, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 186, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 186, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "calcQuadraticArcLengthC", 0) < (0)) __PYX_ERR(0, 186, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 3; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("calcQuadraticArcLengthC", 1, 3, 3, i); __PYX_ERR(0, 186, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 186, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 186, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 186, __pyx_L3_error) + } + __pyx_v_pt1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 205, __pyx_L3_error) + __pyx_v_pt2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 205, __pyx_L3_error) + __pyx_v_pt3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 205, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcQuadraticArcLengthC", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 186, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticArcLengthC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_10calcQuadraticArcLengthC(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_10calcQuadraticArcLengthC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3) { + double __pyx_v_scale; + double __pyx_v_origDist; + double __pyx_v_a; + double __pyx_v_b; + double __pyx_v_x0; + double __pyx_v_x1; + double __pyx_v_Len; + __pyx_t_double_complex __pyx_v_d0; + __pyx_t_double_complex __pyx_v_d1; + __pyx_t_double_complex __pyx_v_d; + __pyx_t_double_complex __pyx_v_n; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + double __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + double __pyx_t_6; + double __pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcQuadraticArcLengthC", 0); + + /* "fontTools/misc/bezierTools.py":218 + * # Analytical solution to the length of a quadratic bezier. + * # Documentation: https://github.com/fonttools/fonttools/issues/3055 + * d0 = pt2 - pt1 # <<<<<<<<<<<<<< + * d1 = pt3 - pt2 + * d = d1 - d0 +*/ + __pyx_v_d0 = __Pyx_c_diff_double(__pyx_v_pt2, __pyx_v_pt1); + + /* "fontTools/misc/bezierTools.py":219 + * # Documentation: https://github.com/fonttools/fonttools/issues/3055 + * d0 = pt2 - pt1 + * d1 = pt3 - pt2 # <<<<<<<<<<<<<< + * d = d1 - d0 + * n = d * 1j +*/ + __pyx_v_d1 = __Pyx_c_diff_double(__pyx_v_pt3, __pyx_v_pt2); + + /* "fontTools/misc/bezierTools.py":220 + * d0 = pt2 - pt1 + * d1 = pt3 - pt2 + * d = d1 - d0 # <<<<<<<<<<<<<< + * n = d * 1j + * scale = abs(n) +*/ + __pyx_v_d = __Pyx_c_diff_double(__pyx_v_d1, __pyx_v_d0); + + /* "fontTools/misc/bezierTools.py":221 + * d1 = pt3 - pt2 + * d = d1 - d0 + * n = d * 1j # <<<<<<<<<<<<<< + * scale = abs(n) + * if scale == 0.0: +*/ + __pyx_v_n = __Pyx_c_prod_double(__pyx_v_d, __pyx_t_double_complex_from_parts(0, 1.0)); + + /* "fontTools/misc/bezierTools.py":222 + * d = d1 - d0 + * n = d * 1j + * scale = abs(n) # <<<<<<<<<<<<<< + * if scale == 0.0: + * return abs(pt3 - pt1) +*/ + __pyx_v_scale = __Pyx_c_abs_double(__pyx_v_n); + + /* "fontTools/misc/bezierTools.py":223 + * n = d * 1j + * scale = abs(n) + * if scale == 0.0: # <<<<<<<<<<<<<< + * return abs(pt3 - pt1) + * origDist = _dot(n, d0) +*/ + __pyx_t_1 = (__pyx_v_scale == 0.0); + if (__pyx_t_1) { + + /* "fontTools/misc/bezierTools.py":224 + * scale = abs(n) + * if scale == 0.0: + * return abs(pt3 - pt1) # <<<<<<<<<<<<<< + * origDist = _dot(n, d0) + * if abs(origDist) < epsilon: +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyFloat_FromDouble(__Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_pt3, __pyx_v_pt1))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 224, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":223 + * n = d * 1j + * scale = abs(n) + * if scale == 0.0: # <<<<<<<<<<<<<< + * return abs(pt3 - pt1) + * origDist = _dot(n, d0) +*/ + } + + /* "fontTools/misc/bezierTools.py":225 + * if scale == 0.0: + * return abs(pt3 - pt1) + * origDist = _dot(n, d0) # <<<<<<<<<<<<<< + * if abs(origDist) < epsilon: + * if _dot(d0, d1) >= 0: +*/ + __pyx_t_3 = __pyx_f_9fontTools_4misc_11bezierTools__dot(__pyx_v_n, __pyx_v_d0); if (unlikely(__pyx_t_3 == ((double)-1) && PyErr_Occurred())) __PYX_ERR(0, 225, __pyx_L1_error) + __pyx_v_origDist = __pyx_t_3; + + /* "fontTools/misc/bezierTools.py":226 + * return abs(pt3 - pt1) + * origDist = _dot(n, d0) + * if abs(origDist) < epsilon: # <<<<<<<<<<<<<< + * if _dot(d0, d1) >= 0: + * return abs(pt3 - pt1) +*/ + __pyx_t_3 = fabs(__pyx_v_origDist); + __pyx_t_2 = PyFloat_FromDouble(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 226, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_epsilon); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 226, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PyObject_RichCompare(__pyx_t_2, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 226, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 226, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (__pyx_t_1) { + + /* "fontTools/misc/bezierTools.py":227 + * origDist = _dot(n, d0) + * if abs(origDist) < epsilon: + * if _dot(d0, d1) >= 0: # <<<<<<<<<<<<<< + * return abs(pt3 - pt1) + * a, b = abs(d0), abs(d1) +*/ + __pyx_t_3 = __pyx_f_9fontTools_4misc_11bezierTools__dot(__pyx_v_d0, __pyx_v_d1); if (unlikely(__pyx_t_3 == ((double)-1) && PyErr_Occurred())) __PYX_ERR(0, 227, __pyx_L1_error) + __pyx_t_1 = (__pyx_t_3 >= 0.0); + if (__pyx_t_1) { + + /* "fontTools/misc/bezierTools.py":228 + * if abs(origDist) < epsilon: + * if _dot(d0, d1) >= 0: + * return abs(pt3 - pt1) # <<<<<<<<<<<<<< + * a, b = abs(d0), abs(d1) + * return (a * a + b * b) / (a + b) +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_5 = PyFloat_FromDouble(__Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_pt3, __pyx_v_pt1))); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":227 + * origDist = _dot(n, d0) + * if abs(origDist) < epsilon: + * if _dot(d0, d1) >= 0: # <<<<<<<<<<<<<< + * return abs(pt3 - pt1) + * a, b = abs(d0), abs(d1) +*/ + } + + /* "fontTools/misc/bezierTools.py":229 + * if _dot(d0, d1) >= 0: + * return abs(pt3 - pt1) + * a, b = abs(d0), abs(d1) # <<<<<<<<<<<<<< + * return (a * a + b * b) / (a + b) + * x0 = _dot(d, d0) / origDist +*/ + __pyx_t_3 = __Pyx_c_abs_double(__pyx_v_d0); + __pyx_t_6 = __Pyx_c_abs_double(__pyx_v_d1); + __pyx_v_a = __pyx_t_3; + __pyx_v_b = __pyx_t_6; + + /* "fontTools/misc/bezierTools.py":230 + * return abs(pt3 - pt1) + * a, b = abs(d0), abs(d1) + * return (a * a + b * b) / (a + b) # <<<<<<<<<<<<<< + * x0 = _dot(d, d0) / origDist + * x1 = _dot(d, d1) / origDist +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_6 = ((__pyx_v_a * __pyx_v_a) + (__pyx_v_b * __pyx_v_b)); + __pyx_t_3 = (__pyx_v_a + __pyx_v_b); + if (unlikely(__pyx_t_3 == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 230, __pyx_L1_error) + } + __pyx_t_5 = PyFloat_FromDouble((__pyx_t_6 / __pyx_t_3)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 230, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":226 + * return abs(pt3 - pt1) + * origDist = _dot(n, d0) + * if abs(origDist) < epsilon: # <<<<<<<<<<<<<< + * if _dot(d0, d1) >= 0: + * return abs(pt3 - pt1) +*/ + } + + /* "fontTools/misc/bezierTools.py":231 + * a, b = abs(d0), abs(d1) + * return (a * a + b * b) / (a + b) + * x0 = _dot(d, d0) / origDist # <<<<<<<<<<<<<< + * x1 = _dot(d, d1) / origDist + * Len = abs(2 * (_intSecAtan(x1) - _intSecAtan(x0)) * origDist / (scale * (x1 - x0))) +*/ + __pyx_t_3 = __pyx_f_9fontTools_4misc_11bezierTools__dot(__pyx_v_d, __pyx_v_d0); if (unlikely(__pyx_t_3 == ((double)-1) && PyErr_Occurred())) __PYX_ERR(0, 231, __pyx_L1_error) + if (unlikely(__pyx_v_origDist == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 231, __pyx_L1_error) + } + __pyx_v_x0 = (__pyx_t_3 / __pyx_v_origDist); + + /* "fontTools/misc/bezierTools.py":232 + * return (a * a + b * b) / (a + b) + * x0 = _dot(d, d0) / origDist + * x1 = _dot(d, d1) / origDist # <<<<<<<<<<<<<< + * Len = abs(2 * (_intSecAtan(x1) - _intSecAtan(x0)) * origDist / (scale * (x1 - x0))) + * return Len +*/ + __pyx_t_3 = __pyx_f_9fontTools_4misc_11bezierTools__dot(__pyx_v_d, __pyx_v_d1); if (unlikely(__pyx_t_3 == ((double)-1) && PyErr_Occurred())) __PYX_ERR(0, 232, __pyx_L1_error) + if (unlikely(__pyx_v_origDist == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 232, __pyx_L1_error) + } + __pyx_v_x1 = (__pyx_t_3 / __pyx_v_origDist); + + /* "fontTools/misc/bezierTools.py":233 + * x0 = _dot(d, d0) / origDist + * x1 = _dot(d, d1) / origDist + * Len = abs(2 * (_intSecAtan(x1) - _intSecAtan(x0)) * origDist / (scale * (x1 - x0))) # <<<<<<<<<<<<<< + * return Len + * +*/ + __pyx_t_3 = __pyx_f_9fontTools_4misc_11bezierTools__intSecAtan(__pyx_v_x1); if (unlikely(__pyx_t_3 == ((double)-1) && PyErr_Occurred())) __PYX_ERR(0, 233, __pyx_L1_error) + __pyx_t_6 = __pyx_f_9fontTools_4misc_11bezierTools__intSecAtan(__pyx_v_x0); if (unlikely(__pyx_t_6 == ((double)-1) && PyErr_Occurred())) __PYX_ERR(0, 233, __pyx_L1_error) + __pyx_t_7 = ((2.0 * (__pyx_t_3 - __pyx_t_6)) * __pyx_v_origDist); + __pyx_t_6 = (__pyx_v_scale * (__pyx_v_x1 - __pyx_v_x0)); + if (unlikely(__pyx_t_6 == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 233, __pyx_L1_error) + } + __pyx_t_3 = fabs((__pyx_t_7 / __pyx_t_6)); + __pyx_v_Len = __pyx_t_3; + + /* "fontTools/misc/bezierTools.py":234 + * x1 = _dot(d, d1) / origDist + * Len = abs(2 * (_intSecAtan(x1) - _intSecAtan(x0)) * origDist / (scale * (x1 - x0))) + * return Len # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_5 = PyFloat_FromDouble(__pyx_v_Len); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 234, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":186 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticArcLengthC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":237 + * + * + * def approximateQuadraticArcLength(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the arc length for a quadratic Bezier segment. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_13approximateQuadraticArcLength(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_12approximateQuadraticArcLength, "approximateQuadraticArcLength(pt1, pt2, pt3)\n\nCalculates the arc length for a quadratic Bezier segment.\n\nUses Gauss-Legendre quadrature for a branch-free approximation.\nSee :func:`calcQuadraticArcLength` for a slower but more accurate result.\n\nArgs:\n pt1: Start point of the Bezier as 2D tuple.\n pt2: Handle point of the Bezier as 2D tuple.\n pt3: End point of the Bezier as 2D tuple.\n\nReturns:\n Approximate arc length value."); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_13approximateQuadraticArcLength = {"approximateQuadraticArcLength", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_13approximateQuadraticArcLength, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_12approximateQuadraticArcLength}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_13approximateQuadraticArcLength(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("approximateQuadraticArcLength (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 237, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 237, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 237, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 237, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "approximateQuadraticArcLength", 0) < (0)) __PYX_ERR(0, 237, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 3; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("approximateQuadraticArcLength", 1, 3, 3, i); __PYX_ERR(0, 237, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 237, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 237, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 237, __pyx_L3_error) + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("approximateQuadraticArcLength", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 237, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.approximateQuadraticArcLength", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_12approximateQuadraticArcLength(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_12approximateQuadraticArcLength(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + size_t __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("approximateQuadraticArcLength", 0); + + /* "fontTools/misc/bezierTools.py":251 + * Approximate arc length value. + * """ + * return approximateQuadraticArcLengthC(complex(*pt1), complex(*pt2), complex(*pt3)) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_approximateQuadraticArcLengthC); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_pt1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_pt2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_pt3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_8 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_8 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_2, __pyx_t_5, __pyx_t_6, __pyx_t_7}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_8, (4-__pyx_t_8) | (__pyx_t_8*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":237 + * + * + * def approximateQuadraticArcLength(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the arc length for a quadratic Bezier segment. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("fontTools.misc.bezierTools.approximateQuadraticArcLength", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":254 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_15approximateQuadraticArcLengthC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_14approximateQuadraticArcLengthC, "approximateQuadraticArcLengthC(double complex pt1, double complex pt2, double complex pt3)\n\nCalculates the arc length for a quadratic Bezier segment.\n\nUses Gauss-Legendre quadrature for a branch-free approximation.\nSee :func:`calcQuadraticArcLength` for a slower but more accurate result.\n\nArgs:\n pt1: Start point of the Bezier as a complex number.\n pt2: Handle point of the Bezier as a complex number.\n pt3: End point of the Bezier as a complex number.\n\nReturns:\n Approximate arc length value."); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_15approximateQuadraticArcLengthC = {"approximateQuadraticArcLengthC", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_15approximateQuadraticArcLengthC, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_14approximateQuadraticArcLengthC}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_15approximateQuadraticArcLengthC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_pt1; + __pyx_t_double_complex __pyx_v_pt2; + __pyx_t_double_complex __pyx_v_pt3; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("approximateQuadraticArcLengthC (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 254, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 254, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 254, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 254, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "approximateQuadraticArcLengthC", 0) < (0)) __PYX_ERR(0, 254, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 3; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("approximateQuadraticArcLengthC", 1, 3, 3, i); __PYX_ERR(0, 254, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 254, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 254, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 254, __pyx_L3_error) + } + __pyx_v_pt1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 265, __pyx_L3_error) + __pyx_v_pt2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 265, __pyx_L3_error) + __pyx_v_pt3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 265, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("approximateQuadraticArcLengthC", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 254, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.approximateQuadraticArcLengthC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_14approximateQuadraticArcLengthC(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_14approximateQuadraticArcLengthC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3) { + double __pyx_v_v0; + double __pyx_v_v1; + double __pyx_v_v2; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("approximateQuadraticArcLengthC", 0); + + /* "fontTools/misc/bezierTools.py":287 + * # abs(BezierCurveC[2].diff(t).subs({t:T})) for T in sorted(.5, .5sqrt(3/5)/2), + * # weighted 5/18, 8/18, 5/18 respectively. + * v0 = abs( # <<<<<<<<<<<<<< + * -0.492943519233745 * pt1 + 0.430331482911935 * pt2 + 0.0626120363218102 * pt3 + * ) +*/ + __pyx_v_v0 = __Pyx_c_abs_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(-0.492943519233745, 0), __pyx_v_pt1), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.430331482911935, 0), __pyx_v_pt2)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.0626120363218102, 0), __pyx_v_pt3))); + + /* "fontTools/misc/bezierTools.py":290 + * -0.492943519233745 * pt1 + 0.430331482911935 * pt2 + 0.0626120363218102 * pt3 + * ) + * v1 = abs(pt3 - pt1) * 0.4444444444444444 # <<<<<<<<<<<<<< + * v2 = abs( + * -0.0626120363218102 * pt1 - 0.430331482911935 * pt2 + 0.492943519233745 * pt3 +*/ + __pyx_v_v1 = (__Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_pt3, __pyx_v_pt1)) * 0.4444444444444444); + + /* "fontTools/misc/bezierTools.py":291 + * ) + * v1 = abs(pt3 - pt1) * 0.4444444444444444 + * v2 = abs( # <<<<<<<<<<<<<< + * -0.0626120363218102 * pt1 - 0.430331482911935 * pt2 + 0.492943519233745 * pt3 + * ) +*/ + __pyx_v_v2 = __Pyx_c_abs_double(__Pyx_c_sum_double(__Pyx_c_diff_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(-0.0626120363218102, 0), __pyx_v_pt1), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.430331482911935, 0), __pyx_v_pt2)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.492943519233745, 0), __pyx_v_pt3))); + + /* "fontTools/misc/bezierTools.py":295 + * ) + * + * return v0 + v1 + v2 # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyFloat_FromDouble(((__pyx_v_v0 + __pyx_v_v1) + __pyx_v_v2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 295, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":254 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("fontTools.misc.bezierTools.approximateQuadraticArcLengthC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":298 + * + * + * def calcQuadraticBounds(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the bounding rectangle for a quadratic Bezier segment. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_17calcQuadraticBounds(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_16calcQuadraticBounds, "calcQuadraticBounds(pt1, pt2, pt3)\n\nCalculates the bounding rectangle for a quadratic Bezier segment.\n\nArgs:\n pt1: Start point of the Bezier as a 2D tuple.\n pt2: Handle point of the Bezier as a 2D tuple.\n pt3: End point of the Bezier as a 2D tuple.\n\nReturns:\n A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``.\n\nExample::\n\n >>> calcQuadraticBounds((0, 0), (50, 100), (100, 0))\n (0, 0, 100, 50.0)\n >>> calcQuadraticBounds((0, 0), (100, 0), (100, 100))\n (0.0, 0.0, 100, 100)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_17calcQuadraticBounds = {"calcQuadraticBounds", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_17calcQuadraticBounds, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_16calcQuadraticBounds}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_17calcQuadraticBounds(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcQuadraticBounds (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 298, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 298, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 298, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 298, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "calcQuadraticBounds", 0) < (0)) __PYX_ERR(0, 298, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 3; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("calcQuadraticBounds", 1, 3, 3, i); __PYX_ERR(0, 298, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 298, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 298, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 298, __pyx_L3_error) + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcQuadraticBounds", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 298, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticBounds", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_16calcQuadraticBounds(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_16calcQuadraticBounds(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3) { + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_cx = NULL; + PyObject *__pyx_v_cy = NULL; + PyObject *__pyx_v_ax2 = NULL; + PyObject *__pyx_v_ay2 = NULL; + PyObject *__pyx_v_roots = NULL; + PyObject *__pyx_v_points = NULL; + PyObject *__pyx_7genexpr__pyx_v_t = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + size_t __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *(*__pyx_t_7)(PyObject *); + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_t_10; + int __pyx_t_11; + Py_ssize_t __pyx_t_12; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcQuadraticBounds", 0); + + /* "fontTools/misc/bezierTools.py":316 + * (0.0, 0.0, 100, 100) + * """ + * (ax, ay), (bx, by), (cx, cy) = calcQuadraticParameters(pt1, pt2, pt3) # <<<<<<<<<<<<<< + * ax2 = ax * 2.0 + * ay2 = ay * 2.0 +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_calcQuadraticParameters); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_2, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_4, (4-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 3)) { + if (size > 3) __Pyx_RaiseTooManyValuesError(3); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 316, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_3); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 2); + __Pyx_INCREF(__pyx_t_5); + } else { + __pyx_t_3 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_5 = __Pyx_PyList_GetItemRefFast(sequence, 2, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_5); + } + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = __Pyx_PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_6 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); + index = 0; __pyx_t_3 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_3)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 1; __pyx_t_2 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 2; __pyx_t_5 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_5)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_5); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 3) < (0)) __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 316, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_6); + __pyx_t_8 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_8); + } else { + __pyx_t_6 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_6); + __pyx_t_8 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_8); + } + #else + __pyx_t_6 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_8 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_9 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_9); + index = 0; __pyx_t_6 = __pyx_t_7(__pyx_t_9); if (unlikely(!__pyx_t_6)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_6); + index = 1; __pyx_t_8 = __pyx_t_7(__pyx_t_9); if (unlikely(!__pyx_t_8)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_8); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_9), 2) < (0)) __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_ax = __pyx_t_6; + __pyx_t_6 = 0; + __pyx_v_ay = __pyx_t_8; + __pyx_t_8 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_2))) || (PyList_CheckExact(__pyx_t_2))) { + PyObject* sequence = __pyx_t_2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 316, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_8 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_8); + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_6); + } else { + __pyx_t_8 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_8); + __pyx_t_6 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_6); + } + #else + __pyx_t_8 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_6 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + #endif + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_9 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_9); + index = 0; __pyx_t_8 = __pyx_t_7(__pyx_t_9); if (unlikely(!__pyx_t_8)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_8); + index = 1; __pyx_t_6 = __pyx_t_7(__pyx_t_9); if (unlikely(!__pyx_t_6)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_6); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_9), 2) < (0)) __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_bx = __pyx_t_8; + __pyx_t_8 = 0; + __pyx_v_by = __pyx_t_6; + __pyx_t_6 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_5))) || (PyList_CheckExact(__pyx_t_5))) { + PyObject* sequence = __pyx_t_5; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 316, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_6); + __pyx_t_8 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_8); + } else { + __pyx_t_6 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_6); + __pyx_t_8 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_8); + } + #else + __pyx_t_6 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_8 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + #endif + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_9 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_9); + index = 0; __pyx_t_6 = __pyx_t_7(__pyx_t_9); if (unlikely(!__pyx_t_6)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_6); + index = 1; __pyx_t_8 = __pyx_t_7(__pyx_t_9); if (unlikely(!__pyx_t_8)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_8); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_9), 2) < (0)) __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_L10_unpacking_done:; + } + __pyx_v_cx = __pyx_t_6; + __pyx_t_6 = 0; + __pyx_v_cy = __pyx_t_8; + __pyx_t_8 = 0; + + /* "fontTools/misc/bezierTools.py":317 + * """ + * (ax, ay), (bx, by), (cx, cy) = calcQuadraticParameters(pt1, pt2, pt3) + * ax2 = ax * 2.0 # <<<<<<<<<<<<<< + * ay2 = ay * 2.0 + * roots = [] +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_ax, __pyx_mstate_global->__pyx_float_2_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 317, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_ax2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":318 + * (ax, ay), (bx, by), (cx, cy) = calcQuadraticParameters(pt1, pt2, pt3) + * ax2 = ax * 2.0 + * ay2 = ay * 2.0 # <<<<<<<<<<<<<< + * roots = [] + * if ax2 != 0: +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_ay, __pyx_mstate_global->__pyx_float_2_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 318, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_ay2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":319 + * ax2 = ax * 2.0 + * ay2 = ay * 2.0 + * roots = [] # <<<<<<<<<<<<<< + * if ax2 != 0: + * roots.append(-bx / ax2) +*/ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 319, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_roots = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":320 + * ay2 = ay * 2.0 + * roots = [] + * if ax2 != 0: # <<<<<<<<<<<<<< + * roots.append(-bx / ax2) + * if ay2 != 0: +*/ + __pyx_t_10 = (__Pyx_PyLong_BoolNeObjC(__pyx_v_ax2, __pyx_mstate_global->__pyx_int_0, 0, 0)); if (unlikely((__pyx_t_10 < 0))) __PYX_ERR(0, 320, __pyx_L1_error) + if (__pyx_t_10) { + + /* "fontTools/misc/bezierTools.py":321 + * roots = [] + * if ax2 != 0: + * roots.append(-bx / ax2) # <<<<<<<<<<<<<< + * if ay2 != 0: + * roots.append(-by / ay2) +*/ + __pyx_t_1 = PyNumber_Negative(__pyx_v_bx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 321, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_v_ax2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 321, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_roots, __pyx_t_5); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 321, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":320 + * ay2 = ay * 2.0 + * roots = [] + * if ax2 != 0: # <<<<<<<<<<<<<< + * roots.append(-bx / ax2) + * if ay2 != 0: +*/ + } + + /* "fontTools/misc/bezierTools.py":322 + * if ax2 != 0: + * roots.append(-bx / ax2) + * if ay2 != 0: # <<<<<<<<<<<<<< + * roots.append(-by / ay2) + * points = [ +*/ + __pyx_t_10 = (__Pyx_PyLong_BoolNeObjC(__pyx_v_ay2, __pyx_mstate_global->__pyx_int_0, 0, 0)); if (unlikely((__pyx_t_10 < 0))) __PYX_ERR(0, 322, __pyx_L1_error) + if (__pyx_t_10) { + + /* "fontTools/misc/bezierTools.py":323 + * roots.append(-bx / ax2) + * if ay2 != 0: + * roots.append(-by / ay2) # <<<<<<<<<<<<<< + * points = [ + * (ax * t * t + bx * t + cx, ay * t * t + by * t + cy) +*/ + __pyx_t_5 = PyNumber_Negative(__pyx_v_by); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 323, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_1 = __Pyx_PyNumber_Divide(__pyx_t_5, __pyx_v_ay2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 323, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_roots, __pyx_t_1); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 323, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":322 + * if ax2 != 0: + * roots.append(-bx / ax2) + * if ay2 != 0: # <<<<<<<<<<<<<< + * roots.append(-by / ay2) + * points = [ +*/ + } + + /* "fontTools/misc/bezierTools.py":328 + * for t in roots + * if 0 <= t < 1 + * ] + [pt1, pt3] # <<<<<<<<<<<<<< + * return calcBounds(points) + * +*/ + { /* enter inner scope */ + + /* "fontTools/misc/bezierTools.py":324 + * if ay2 != 0: + * roots.append(-by / ay2) + * points = [ # <<<<<<<<<<<<<< + * (ax * t * t + bx * t + cx, ay * t * t + by * t + cy) + * for t in roots +*/ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 324, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/misc/bezierTools.py":326 + * points = [ + * (ax * t * t + bx * t + cx, ay * t * t + by * t + cy) + * for t in roots # <<<<<<<<<<<<<< + * if 0 <= t < 1 + * ] + [pt1, pt3] +*/ + __pyx_t_5 = __pyx_v_roots; __Pyx_INCREF(__pyx_t_5); + __pyx_t_12 = 0; + for (;;) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_5); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 326, __pyx_L15_error) + #endif + if (__pyx_t_12 >= __pyx_temp) break; + } + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(__pyx_t_5, __pyx_t_12, __Pyx_ReferenceSharing_OwnStrongReference); + ++__pyx_t_12; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 326, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_7genexpr__pyx_v_t, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":327 + * (ax * t * t + bx * t + cx, ay * t * t + by * t + cy) + * for t in roots + * if 0 <= t < 1 # <<<<<<<<<<<<<< + * ] + [pt1, pt3] + * return calcBounds(points) +*/ + __pyx_t_2 = PyObject_RichCompare(__pyx_mstate_global->__pyx_int_0, __pyx_7genexpr__pyx_v_t, Py_LE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 327, __pyx_L15_error) + if (__Pyx_PyObject_IsTrue(__pyx_t_2)) { + __Pyx_DECREF(__pyx_t_2); + __pyx_t_2 = PyObject_RichCompare(__pyx_7genexpr__pyx_v_t, __pyx_mstate_global->__pyx_int_1, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 327, __pyx_L15_error) + } + __pyx_t_10 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_10 < 0))) __PYX_ERR(0, 327, __pyx_L15_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__pyx_t_10) { + + /* "fontTools/misc/bezierTools.py":325 + * roots.append(-by / ay2) + * points = [ + * (ax * t * t + bx * t + cx, ay * t * t + by * t + cy) # <<<<<<<<<<<<<< + * for t in roots + * if 0 <= t < 1 +*/ + __pyx_t_2 = PyNumber_Multiply(__pyx_v_ax, __pyx_7genexpr__pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_2, __pyx_7genexpr__pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_v_bx, __pyx_7genexpr__pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_8 = PyNumber_Add(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_8, __pyx_v_cx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = PyNumber_Multiply(__pyx_v_ay, __pyx_7genexpr__pyx_v_t); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_8, __pyx_7genexpr__pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = PyNumber_Multiply(__pyx_v_by, __pyx_7genexpr__pyx_v_t); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_6 = PyNumber_Add(__pyx_t_3, __pyx_t_8); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = PyNumber_Add(__pyx_t_6, __pyx_v_cy); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 325, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_2) != (0)) __PYX_ERR(0, 325, __pyx_L15_error); + __Pyx_GIVEREF(__pyx_t_8); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_8) != (0)) __PYX_ERR(0, 325, __pyx_L15_error); + __pyx_t_2 = 0; + __pyx_t_8 = 0; + if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_6))) __PYX_ERR(0, 324, __pyx_L15_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":327 + * (ax * t * t + bx * t + cx, ay * t * t + by * t + cy) + * for t in roots + * if 0 <= t < 1 # <<<<<<<<<<<<<< + * ] + [pt1, pt3] + * return calcBounds(points) +*/ + } + + /* "fontTools/misc/bezierTools.py":326 + * points = [ + * (ax * t * t + bx * t + cx, ay * t * t + by * t + cy) + * for t in roots # <<<<<<<<<<<<<< + * if 0 <= t < 1 + * ] + [pt1, pt3] +*/ + } + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_7genexpr__pyx_v_t); __pyx_7genexpr__pyx_v_t = 0; + goto __pyx_L20_exit_scope; + __pyx_L15_error:; + __Pyx_XDECREF(__pyx_7genexpr__pyx_v_t); __pyx_7genexpr__pyx_v_t = 0; + goto __pyx_L1_error; + __pyx_L20_exit_scope:; + } /* exit inner scope */ + + /* "fontTools/misc/bezierTools.py":328 + * for t in roots + * if 0 <= t < 1 + * ] + [pt1, pt3] # <<<<<<<<<<<<<< + * return calcBounds(points) + * +*/ + __pyx_t_5 = PyList_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 328, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_5, 0, __pyx_v_pt1) != (0)) __PYX_ERR(0, 328, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt3); + __Pyx_GIVEREF(__pyx_v_pt3); + if (__Pyx_PyList_SET_ITEM(__pyx_t_5, 1, __pyx_v_pt3) != (0)) __PYX_ERR(0, 328, __pyx_L1_error); + __pyx_t_6 = PyNumber_Add(__pyx_t_1, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 328, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_v_points = ((PyObject*)__pyx_t_6); + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":329 + * if 0 <= t < 1 + * ] + [pt1, pt3] + * return calcBounds(points) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_5 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_calcBounds); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 329, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_5); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_v_points}; + __pyx_t_6 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_4, (2-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 329, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":298 + * + * + * def calcQuadraticBounds(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the bounding rectangle for a quadratic Bezier segment. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticBounds", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_cx); + __Pyx_XDECREF(__pyx_v_cy); + __Pyx_XDECREF(__pyx_v_ax2); + __Pyx_XDECREF(__pyx_v_ay2); + __Pyx_XDECREF(__pyx_v_roots); + __Pyx_XDECREF(__pyx_v_points); + __Pyx_XDECREF(__pyx_7genexpr__pyx_v_t); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":332 + * + * + * def approximateCubicArcLength(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * """Approximates the arc length for a cubic Bezier segment. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_19approximateCubicArcLength(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_18approximateCubicArcLength, "approximateCubicArcLength(pt1, pt2, pt3, pt4)\n\nApproximates the arc length for a cubic Bezier segment.\n\nUses Gauss-Lobatto quadrature with n=5 points to approximate arc length.\nSee :func:`calcCubicArcLength` for a slower but more accurate result.\n\nArgs:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n\nReturns:\n Arc length value.\n\nExample::\n\n >>> approximateCubicArcLength((0, 0), (25, 100), (75, 100), (100, 0))\n 190.04332968932817\n >>> approximateCubicArcLength((0, 0), (50, 0), (100, 50), (100, 100))\n 154.8852074945903\n >>> approximateCubicArcLength((0, 0), (50, 0), (100, 0), (150, 0)) # line; exact result should be 150.\n 149.99999999999991\n >>> approximateCubicArcLength((0, 0), (50, 0), (100, 0), (-50, 0)) # cusp; exact result should be 150.\n 136.9267662156362\n >>> approximateCubicArcLength((0, 0), (50, 0), (100, -50), (-50, 0)) # cusp\n 154.80848416537057"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_19approximateCubicArcLength = {"approximateCubicArcLength", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_19approximateCubicArcLength, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_18approximateCubicArcLength}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_19approximateCubicArcLength(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_pt4 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("approximateCubicArcLength (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,&__pyx_mstate_global->__pyx_n_u_pt4,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 332, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 332, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 332, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 332, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 332, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "approximateCubicArcLength", 0) < (0)) __PYX_ERR(0, 332, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("approximateCubicArcLength", 1, 4, 4, i); __PYX_ERR(0, 332, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 332, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 332, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 332, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 332, __pyx_L3_error) + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_pt4 = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("approximateCubicArcLength", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 332, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.approximateCubicArcLength", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_18approximateCubicArcLength(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_18approximateCubicArcLength(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + size_t __pyx_t_9; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("approximateCubicArcLength", 0); + + /* "fontTools/misc/bezierTools.py":357 + * 154.80848416537057 + * """ + * return approximateCubicArcLengthC( # <<<<<<<<<<<<<< + * complex(*pt1), complex(*pt2), complex(*pt3), complex(*pt4) + * ) +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_approximateCubicArcLengthC); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 357, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/misc/bezierTools.py":358 + * """ + * return approximateCubicArcLengthC( + * complex(*pt1), complex(*pt2), complex(*pt3), complex(*pt4) # <<<<<<<<<<<<<< + * ) + * +*/ + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_pt1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_pt2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_pt3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_pt4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_8 = __Pyx_PyObject_Call(((PyObject *)(&PyComplex_Type)), __pyx_t_4, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 358, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_9 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_9 = 0; + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_2, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_t_8}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_9, (5-__pyx_t_9) | (__pyx_t_9*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 357, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":332 + * + * + * def approximateCubicArcLength(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * """Approximates the arc length for a cubic Bezier segment. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("fontTools.misc.bezierTools.approximateCubicArcLength", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":362 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_21approximateCubicArcLengthC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_20approximateCubicArcLengthC, "approximateCubicArcLengthC(double complex pt1, double complex pt2, double complex pt3, double complex pt4)\n\nApproximates the arc length for a cubic Bezier segment.\n\nArgs:\n pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers.\n\nReturns:\n Arc length value."); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_21approximateCubicArcLengthC = {"approximateCubicArcLengthC", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_21approximateCubicArcLengthC, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_20approximateCubicArcLengthC}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_21approximateCubicArcLengthC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_pt1; + __pyx_t_double_complex __pyx_v_pt2; + __pyx_t_double_complex __pyx_v_pt3; + __pyx_t_double_complex __pyx_v_pt4; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("approximateCubicArcLengthC (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,&__pyx_mstate_global->__pyx_n_u_pt4,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 362, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 362, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 362, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 362, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 362, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "approximateCubicArcLengthC", 0) < (0)) __PYX_ERR(0, 362, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("approximateCubicArcLengthC", 1, 4, 4, i); __PYX_ERR(0, 362, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 362, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 362, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 362, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 362, __pyx_L3_error) + } + __pyx_v_pt1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 376, __pyx_L3_error) + __pyx_v_pt2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 376, __pyx_L3_error) + __pyx_v_pt3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 376, __pyx_L3_error) + __pyx_v_pt4 = __Pyx_PyComplex_As___pyx_t_double_complex(values[3]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 376, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("approximateCubicArcLengthC", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 362, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.approximateCubicArcLengthC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_20approximateCubicArcLengthC(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_20approximateCubicArcLengthC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4) { + double __pyx_v_v0; + double __pyx_v_v1; + double __pyx_v_v2; + double __pyx_v_v3; + double __pyx_v_v4; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("approximateCubicArcLengthC", 0); + + /* "fontTools/misc/bezierTools.py":393 + * # abs(BezierCurveC[3].diff(t).subs({t:T})) for T in sorted(0, .5(3/7)**.5/2, .5, 1), + * # weighted 1/20, 49/180, 32/90, 49/180, 1/20 respectively. + * v0 = abs(pt2 - pt1) * 0.15 # <<<<<<<<<<<<<< + * v1 = abs( + * -0.558983582205757 * pt1 +*/ + __pyx_v_v0 = (__Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_pt2, __pyx_v_pt1)) * 0.15); + + /* "fontTools/misc/bezierTools.py":394 + * # weighted 1/20, 49/180, 32/90, 49/180, 1/20 respectively. + * v0 = abs(pt2 - pt1) * 0.15 + * v1 = abs( # <<<<<<<<<<<<<< + * -0.558983582205757 * pt1 + * + 0.325650248872424 * pt2 +*/ + __pyx_v_v1 = __Pyx_c_abs_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(-0.558983582205757, 0), __pyx_v_pt1), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.325650248872424, 0), __pyx_v_pt2)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.208983582205757, 0), __pyx_v_pt3)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.024349751127576, 0), __pyx_v_pt4))); + + /* "fontTools/misc/bezierTools.py":400 + * + 0.024349751127576 * pt4 + * ) + * v2 = abs(pt4 - pt1 + pt3 - pt2) * 0.26666666666666666 # <<<<<<<<<<<<<< + * v3 = abs( + * -0.024349751127576 * pt1 +*/ + __pyx_v_v2 = (__Pyx_c_abs_double(__Pyx_c_diff_double(__Pyx_c_sum_double(__Pyx_c_diff_double(__pyx_v_pt4, __pyx_v_pt1), __pyx_v_pt3), __pyx_v_pt2)) * 0.26666666666666666); + + /* "fontTools/misc/bezierTools.py":401 + * ) + * v2 = abs(pt4 - pt1 + pt3 - pt2) * 0.26666666666666666 + * v3 = abs( # <<<<<<<<<<<<<< + * -0.024349751127576 * pt1 + * - 0.208983582205757 * pt2 +*/ + __pyx_v_v3 = __Pyx_c_abs_double(__Pyx_c_sum_double(__Pyx_c_diff_double(__Pyx_c_diff_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(-0.024349751127576, 0), __pyx_v_pt1), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.208983582205757, 0), __pyx_v_pt2)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.325650248872424, 0), __pyx_v_pt3)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(0.558983582205757, 0), __pyx_v_pt4))); + + /* "fontTools/misc/bezierTools.py":407 + * + 0.558983582205757 * pt4 + * ) + * v4 = abs(pt4 - pt3) * 0.15 # <<<<<<<<<<<<<< + * + * return v0 + v1 + v2 + v3 + v4 +*/ + __pyx_v_v4 = (__Pyx_c_abs_double(__Pyx_c_diff_double(__pyx_v_pt4, __pyx_v_pt3)) * 0.15); + + /* "fontTools/misc/bezierTools.py":409 + * v4 = abs(pt4 - pt3) * 0.15 + * + * return v0 + v1 + v2 + v3 + v4 # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyFloat_FromDouble(((((__pyx_v_v0 + __pyx_v_v1) + __pyx_v_v2) + __pyx_v_v3) + __pyx_v_v4)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 409, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":362 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("fontTools.misc.bezierTools.approximateCubicArcLengthC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":412 + * + * + * def calcCubicBounds(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * """Calculates the bounding rectangle for a quadratic Bezier segment. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_23calcCubicBounds(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_22calcCubicBounds, "calcCubicBounds(pt1, pt2, pt3, pt4)\n\nCalculates the bounding rectangle for a quadratic Bezier segment.\n\nArgs:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n\nReturns:\n A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``.\n\nExample::\n\n >>> calcCubicBounds((0, 0), (25, 100), (75, 100), (100, 0))\n (0, 0, 100, 75.0)\n >>> calcCubicBounds((0, 0), (50, 0), (100, 50), (100, 100))\n (0.0, 0.0, 100, 100)\n >>> print(\"%f %f %f %f\" % calcCubicBounds((50, 0), (0, 100), (100, 100), (50, 0)))\n 35.566243 0.000000 64.433757 75.000000"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_23calcCubicBounds = {"calcCubicBounds", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_23calcCubicBounds, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_22calcCubicBounds}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_23calcCubicBounds(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_pt4 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcCubicBounds (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,&__pyx_mstate_global->__pyx_n_u_pt4,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 412, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 412, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 412, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 412, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 412, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "calcCubicBounds", 0) < (0)) __PYX_ERR(0, 412, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("calcCubicBounds", 1, 4, 4, i); __PYX_ERR(0, 412, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 412, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 412, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 412, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 412, __pyx_L3_error) + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_pt4 = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcCubicBounds", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 412, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicBounds", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_22calcCubicBounds(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_22calcCubicBounds(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4) { + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_cx = NULL; + PyObject *__pyx_v_cy = NULL; + PyObject *__pyx_v_dx = NULL; + PyObject *__pyx_v_dy = NULL; + PyObject *__pyx_v_ax3 = NULL; + PyObject *__pyx_v_ay3 = NULL; + PyObject *__pyx_v_bx2 = NULL; + PyObject *__pyx_v_by2 = NULL; + PyObject *__pyx_v_xRoots = NULL; + PyObject *__pyx_v_yRoots = NULL; + PyObject *__pyx_v_roots = NULL; + PyObject *__pyx_v_points = NULL; + PyObject *__pyx_8genexpr1__pyx_v_t = NULL; + PyObject *__pyx_8genexpr2__pyx_v_t = NULL; + PyObject *__pyx_8genexpr3__pyx_v_t = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + size_t __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *(*__pyx_t_8)(PyObject *); + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + Py_ssize_t __pyx_t_11; + PyObject *(*__pyx_t_12)(PyObject *); + int __pyx_t_13; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcCubicBounds", 0); + + /* "fontTools/misc/bezierTools.py":430 + * 35.566243 0.000000 64.433757 75.000000 + * """ + * (ax, ay), (bx, by), (cx, cy), (dx, dy) = calcCubicParameters(pt1, pt2, pt3, pt4) # <<<<<<<<<<<<<< + * # calc first derivative + * ax3 = ax * 3.0 +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_calcCubicParameters); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_2, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_4, (5-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 430, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_3); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 2); + __Pyx_INCREF(__pyx_t_5); + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 3); + __Pyx_INCREF(__pyx_t_6); + } else { + __pyx_t_3 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_5 = __Pyx_PyList_GetItemRefFast(sequence, 2, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyList_GetItemRefFast(sequence, 3, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_6); + } + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_3,&__pyx_t_2,&__pyx_t_5,&__pyx_t_6}; + for (i=0; i < 4; i++) { + PyObject* item = __Pyx_PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_3,&__pyx_t_2,&__pyx_t_5,&__pyx_t_6}; + __pyx_t_7 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_8 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_7); + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_8(__pyx_t_7); if (unlikely(!item)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 4) < (0)) __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 430, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_7 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_7); + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_9); + } else { + __pyx_t_7 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_7); + __pyx_t_9 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_9); + } + #else + __pyx_t_7 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_9 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_10 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_8 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_10); + index = 0; __pyx_t_7 = __pyx_t_8(__pyx_t_10); if (unlikely(!__pyx_t_7)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_7); + index = 1; __pyx_t_9 = __pyx_t_8(__pyx_t_10); if (unlikely(!__pyx_t_9)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_9); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_10), 2) < (0)) __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_ax = __pyx_t_7; + __pyx_t_7 = 0; + __pyx_v_ay = __pyx_t_9; + __pyx_t_9 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_2))) || (PyList_CheckExact(__pyx_t_2))) { + PyObject* sequence = __pyx_t_2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 430, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_9); + __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_7); + } else { + __pyx_t_9 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_9); + __pyx_t_7 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_7); + } + #else + __pyx_t_9 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_7 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + #endif + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_10 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_8 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_10); + index = 0; __pyx_t_9 = __pyx_t_8(__pyx_t_10); if (unlikely(!__pyx_t_9)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_9); + index = 1; __pyx_t_7 = __pyx_t_8(__pyx_t_10); if (unlikely(!__pyx_t_7)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_7); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_10), 2) < (0)) __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_bx = __pyx_t_9; + __pyx_t_9 = 0; + __pyx_v_by = __pyx_t_7; + __pyx_t_7 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_5))) || (PyList_CheckExact(__pyx_t_5))) { + PyObject* sequence = __pyx_t_5; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 430, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_7 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_7); + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_9); + } else { + __pyx_t_7 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_7); + __pyx_t_9 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_9); + } + #else + __pyx_t_7 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_9 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + #endif + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_10 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_8 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_10); + index = 0; __pyx_t_7 = __pyx_t_8(__pyx_t_10); if (unlikely(!__pyx_t_7)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_7); + index = 1; __pyx_t_9 = __pyx_t_8(__pyx_t_10); if (unlikely(!__pyx_t_9)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_9); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_10), 2) < (0)) __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_L10_unpacking_done:; + } + __pyx_v_cx = __pyx_t_7; + __pyx_t_7 = 0; + __pyx_v_cy = __pyx_t_9; + __pyx_t_9 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_6))) || (PyList_CheckExact(__pyx_t_6))) { + PyObject* sequence = __pyx_t_6; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 430, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_9); + __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_7); + } else { + __pyx_t_9 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_9); + __pyx_t_7 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_7); + } + #else + __pyx_t_9 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_7 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + #endif + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_10 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 430, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_8 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_10); + index = 0; __pyx_t_9 = __pyx_t_8(__pyx_t_10); if (unlikely(!__pyx_t_9)) goto __pyx_L11_unpacking_failed; + __Pyx_GOTREF(__pyx_t_9); + index = 1; __pyx_t_7 = __pyx_t_8(__pyx_t_10); if (unlikely(!__pyx_t_7)) goto __pyx_L11_unpacking_failed; + __Pyx_GOTREF(__pyx_t_7); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_10), 2) < (0)) __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + goto __pyx_L12_unpacking_done; + __pyx_L11_unpacking_failed:; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 430, __pyx_L1_error) + __pyx_L12_unpacking_done:; + } + __pyx_v_dx = __pyx_t_9; + __pyx_t_9 = 0; + __pyx_v_dy = __pyx_t_7; + __pyx_t_7 = 0; + + /* "fontTools/misc/bezierTools.py":432 + * (ax, ay), (bx, by), (cx, cy), (dx, dy) = calcCubicParameters(pt1, pt2, pt3, pt4) + * # calc first derivative + * ax3 = ax * 3.0 # <<<<<<<<<<<<<< + * ay3 = ay * 3.0 + * bx2 = bx * 2.0 +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_ax, __pyx_mstate_global->__pyx_float_3_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 432, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_ax3 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":433 + * # calc first derivative + * ax3 = ax * 3.0 + * ay3 = ay * 3.0 # <<<<<<<<<<<<<< + * bx2 = bx * 2.0 + * by2 = by * 2.0 +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_ay, __pyx_mstate_global->__pyx_float_3_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 433, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_ay3 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":434 + * ax3 = ax * 3.0 + * ay3 = ay * 3.0 + * bx2 = bx * 2.0 # <<<<<<<<<<<<<< + * by2 = by * 2.0 + * xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1] +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_bx, __pyx_mstate_global->__pyx_float_2_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 434, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_bx2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":435 + * ay3 = ay * 3.0 + * bx2 = bx * 2.0 + * by2 = by * 2.0 # <<<<<<<<<<<<<< + * xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1] + * yRoots = [t for t in solveQuadratic(ay3, by2, cy) if 0 <= t < 1] +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_by, __pyx_mstate_global->__pyx_float_2_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 435, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_by2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":436 + * bx2 = bx * 2.0 + * by2 = by * 2.0 + * xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1] # <<<<<<<<<<<<<< + * yRoots = [t for t in solveQuadratic(ay3, by2, cy) if 0 <= t < 1] + * roots = xRoots + yRoots +*/ + { /* enter inner scope */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 436, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_solveQuadratic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 436, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_5); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_5, __pyx_v_ax3, __pyx_v_bx2, __pyx_v_cx}; + __pyx_t_6 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_4, (4-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 436, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_6); + } + if (likely(PyList_CheckExact(__pyx_t_6)) || PyTuple_CheckExact(__pyx_t_6)) { + __pyx_t_2 = __pyx_t_6; __Pyx_INCREF(__pyx_t_2); + __pyx_t_11 = 0; + __pyx_t_12 = NULL; + } else { + __pyx_t_11 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 436, __pyx_L15_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_12 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 436, __pyx_L15_error) + } + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + for (;;) { + if (likely(!__pyx_t_12)) { + if (likely(PyList_CheckExact(__pyx_t_2))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 436, __pyx_L15_error) + #endif + if (__pyx_t_11 >= __pyx_temp) break; + } + __pyx_t_6 = __Pyx_PyList_GetItemRefFast(__pyx_t_2, __pyx_t_11, __Pyx_ReferenceSharing_OwnStrongReference); + ++__pyx_t_11; + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_2); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 436, __pyx_L15_error) + #endif + if (__pyx_t_11 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_6 = __Pyx_NewRef(PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_11)); + #else + __pyx_t_6 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_11); + #endif + ++__pyx_t_11; + } + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 436, __pyx_L15_error) + } else { + __pyx_t_6 = __pyx_t_12(__pyx_t_2); + if (unlikely(!__pyx_t_6)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 436, __pyx_L15_error) + PyErr_Clear(); + } + break; + } + } + __Pyx_GOTREF(__pyx_t_6); + __Pyx_XDECREF_SET(__pyx_8genexpr1__pyx_v_t, __pyx_t_6); + __pyx_t_6 = 0; + __pyx_t_6 = PyObject_RichCompare(__pyx_mstate_global->__pyx_int_0, __pyx_8genexpr1__pyx_v_t, Py_LE); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 436, __pyx_L15_error) + if (__Pyx_PyObject_IsTrue(__pyx_t_6)) { + __Pyx_DECREF(__pyx_t_6); + __pyx_t_6 = PyObject_RichCompare(__pyx_8genexpr1__pyx_v_t, __pyx_mstate_global->__pyx_int_1, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 436, __pyx_L15_error) + } + __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_13 < 0))) __PYX_ERR(0, 436, __pyx_L15_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (__pyx_t_13) { + if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_8genexpr1__pyx_v_t))) __PYX_ERR(0, 436, __pyx_L15_error) + } + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_t); __pyx_8genexpr1__pyx_v_t = 0; + goto __pyx_L20_exit_scope; + __pyx_L15_error:; + __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_t); __pyx_8genexpr1__pyx_v_t = 0; + goto __pyx_L1_error; + __pyx_L20_exit_scope:; + } /* exit inner scope */ + __pyx_v_xRoots = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":437 + * by2 = by * 2.0 + * xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1] + * yRoots = [t for t in solveQuadratic(ay3, by2, cy) if 0 <= t < 1] # <<<<<<<<<<<<<< + * roots = xRoots + yRoots + * +*/ + { /* enter inner scope */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 437, __pyx_L23_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_solveQuadratic); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 437, __pyx_L23_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5); + assert(__pyx_t_6); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_5, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_6, __pyx_v_ay3, __pyx_v_by2, __pyx_v_cy}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_5, __pyx_callargs+__pyx_t_4, (4-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 437, __pyx_L23_error) + __Pyx_GOTREF(__pyx_t_2); + } + if (likely(PyList_CheckExact(__pyx_t_2)) || PyTuple_CheckExact(__pyx_t_2)) { + __pyx_t_5 = __pyx_t_2; __Pyx_INCREF(__pyx_t_5); + __pyx_t_11 = 0; + __pyx_t_12 = NULL; + } else { + __pyx_t_11 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 437, __pyx_L23_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_12 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_5); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 437, __pyx_L23_error) + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + for (;;) { + if (likely(!__pyx_t_12)) { + if (likely(PyList_CheckExact(__pyx_t_5))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_5); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 437, __pyx_L23_error) + #endif + if (__pyx_t_11 >= __pyx_temp) break; + } + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(__pyx_t_5, __pyx_t_11, __Pyx_ReferenceSharing_OwnStrongReference); + ++__pyx_t_11; + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_5); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 437, __pyx_L23_error) + #endif + if (__pyx_t_11 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_2 = __Pyx_NewRef(PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_11)); + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_5, __pyx_t_11); + #endif + ++__pyx_t_11; + } + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 437, __pyx_L23_error) + } else { + __pyx_t_2 = __pyx_t_12(__pyx_t_5); + if (unlikely(!__pyx_t_2)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 437, __pyx_L23_error) + PyErr_Clear(); + } + break; + } + } + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_8genexpr2__pyx_v_t, __pyx_t_2); + __pyx_t_2 = 0; + __pyx_t_2 = PyObject_RichCompare(__pyx_mstate_global->__pyx_int_0, __pyx_8genexpr2__pyx_v_t, Py_LE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 437, __pyx_L23_error) + if (__Pyx_PyObject_IsTrue(__pyx_t_2)) { + __Pyx_DECREF(__pyx_t_2); + __pyx_t_2 = PyObject_RichCompare(__pyx_8genexpr2__pyx_v_t, __pyx_mstate_global->__pyx_int_1, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 437, __pyx_L23_error) + } + __pyx_t_13 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_13 < 0))) __PYX_ERR(0, 437, __pyx_L23_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__pyx_t_13) { + if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_8genexpr2__pyx_v_t))) __PYX_ERR(0, 437, __pyx_L23_error) + } + } + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_t); __pyx_8genexpr2__pyx_v_t = 0; + goto __pyx_L28_exit_scope; + __pyx_L23_error:; + __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_t); __pyx_8genexpr2__pyx_v_t = 0; + goto __pyx_L1_error; + __pyx_L28_exit_scope:; + } /* exit inner scope */ + __pyx_v_yRoots = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":438 + * xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1] + * yRoots = [t for t in solveQuadratic(ay3, by2, cy) if 0 <= t < 1] + * roots = xRoots + yRoots # <<<<<<<<<<<<<< + * + * points = [ +*/ + __pyx_t_1 = PyNumber_Add(__pyx_v_xRoots, __pyx_v_yRoots); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 438, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_roots = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":446 + * ) + * for t in roots + * ] + [pt1, pt4] # <<<<<<<<<<<<<< + * return calcBounds(points) + * +*/ + { /* enter inner scope */ + + /* "fontTools/misc/bezierTools.py":440 + * roots = xRoots + yRoots + * + * points = [ # <<<<<<<<<<<<<< + * ( + * ax * t * t * t + bx * t * t + cx * t + dx, +*/ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 440, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/misc/bezierTools.py":445 + * ay * t * t * t + by * t * t + cy * t + dy, + * ) + * for t in roots # <<<<<<<<<<<<<< + * ] + [pt1, pt4] + * return calcBounds(points) +*/ + __pyx_t_5 = __pyx_v_roots; __Pyx_INCREF(__pyx_t_5); + __pyx_t_11 = 0; + for (;;) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_5); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 445, __pyx_L31_error) + #endif + if (__pyx_t_11 >= __pyx_temp) break; + } + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(__pyx_t_5, __pyx_t_11, __Pyx_ReferenceSharing_OwnStrongReference); + ++__pyx_t_11; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 445, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_8genexpr3__pyx_v_t, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":442 + * points = [ + * ( + * ax * t * t * t + bx * t * t + cx * t + dx, # <<<<<<<<<<<<<< + * ay * t * t * t + by * t * t + cy * t + dy, + * ) +*/ + __pyx_t_2 = PyNumber_Multiply(__pyx_v_ax, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = PyNumber_Multiply(__pyx_t_2, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_t_6, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyNumber_Multiply(__pyx_v_bx, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_6, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyNumber_Add(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Multiply(__pyx_v_cx, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyNumber_Add(__pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Add(__pyx_t_2, __pyx_v_dx); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":443 + * ( + * ax * t * t * t + bx * t * t + cx * t + dx, + * ay * t * t * t + by * t * t + cy * t + dy, # <<<<<<<<<<<<<< + * ) + * for t in roots +*/ + __pyx_t_2 = PyNumber_Multiply(__pyx_v_ay, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = PyNumber_Multiply(__pyx_t_2, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_t_6, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyNumber_Multiply(__pyx_v_by, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = PyNumber_Multiply(__pyx_t_6, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyNumber_Add(__pyx_t_2, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = PyNumber_Multiply(__pyx_v_cy, __pyx_8genexpr3__pyx_v_t); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_2 = PyNumber_Add(__pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = PyNumber_Add(__pyx_t_2, __pyx_v_dy); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 443, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":442 + * points = [ + * ( + * ax * t * t * t + bx * t * t + cx * t + dx, # <<<<<<<<<<<<<< + * ay * t * t * t + by * t * t + cy * t + dy, + * ) +*/ + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 442, __pyx_L31_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3) != (0)) __PYX_ERR(0, 442, __pyx_L31_error); + __Pyx_GIVEREF(__pyx_t_7); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_7) != (0)) __PYX_ERR(0, 442, __pyx_L31_error); + __pyx_t_3 = 0; + __pyx_t_7 = 0; + if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_2))) __PYX_ERR(0, 440, __pyx_L31_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":445 + * ay * t * t * t + by * t * t + cy * t + dy, + * ) + * for t in roots # <<<<<<<<<<<<<< + * ] + [pt1, pt4] + * return calcBounds(points) +*/ + } + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_8genexpr3__pyx_v_t); __pyx_8genexpr3__pyx_v_t = 0; + goto __pyx_L35_exit_scope; + __pyx_L31_error:; + __Pyx_XDECREF(__pyx_8genexpr3__pyx_v_t); __pyx_8genexpr3__pyx_v_t = 0; + goto __pyx_L1_error; + __pyx_L35_exit_scope:; + } /* exit inner scope */ + + /* "fontTools/misc/bezierTools.py":446 + * ) + * for t in roots + * ] + [pt1, pt4] # <<<<<<<<<<<<<< + * return calcBounds(points) + * +*/ + __pyx_t_5 = PyList_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 446, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_5, 0, __pyx_v_pt1) != (0)) __PYX_ERR(0, 446, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt4); + __Pyx_GIVEREF(__pyx_v_pt4); + if (__Pyx_PyList_SET_ITEM(__pyx_t_5, 1, __pyx_v_pt4) != (0)) __PYX_ERR(0, 446, __pyx_L1_error); + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 446, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_v_points = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":447 + * for t in roots + * ] + [pt1, pt4] + * return calcBounds(points) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_5 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_calcBounds); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 447, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_5); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_v_points}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_4, (2-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 447, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":412 + * + * + * def calcCubicBounds(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * """Calculates the bounding rectangle for a quadratic Bezier segment. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicBounds", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_cx); + __Pyx_XDECREF(__pyx_v_cy); + __Pyx_XDECREF(__pyx_v_dx); + __Pyx_XDECREF(__pyx_v_dy); + __Pyx_XDECREF(__pyx_v_ax3); + __Pyx_XDECREF(__pyx_v_ay3); + __Pyx_XDECREF(__pyx_v_bx2); + __Pyx_XDECREF(__pyx_v_by2); + __Pyx_XDECREF(__pyx_v_xRoots); + __Pyx_XDECREF(__pyx_v_yRoots); + __Pyx_XDECREF(__pyx_v_roots); + __Pyx_XDECREF(__pyx_v_points); + __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_t); + __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_t); + __Pyx_XDECREF(__pyx_8genexpr3__pyx_v_t); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":450 + * + * + * def splitLine(pt1, pt2, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a line at a given coordinate. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_25splitLine(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_24splitLine, "splitLine(pt1, pt2, where, isHorizontal)\n\nSplit a line at a given coordinate.\n\nArgs:\n pt1: Start point of line as 2D tuple.\n pt2: End point of line as 2D tuple.\n where: Position at which to split the line.\n isHorizontal: Direction of the ray splitting the line. If true,\n ``where`` is interpreted as a Y coordinate; if false, then\n ``where`` is interpreted as an X coordinate.\n\nReturns:\n A list of two line segments (each line segment being two 2D tuples)\n if the line was successfully split, or a list containing the original\n line.\n\nExample::\n\n >>> printSegments(splitLine((0, 0), (100, 100), 50, True))\n ((0, 0), (50, 50))\n ((50, 50), (100, 100))\n >>> printSegments(splitLine((0, 0), (100, 100), 100, True))\n ((0, 0), (100, 100))\n >>> printSegments(splitLine((0, 0), (100, 100), 0, True))\n ((0, 0), (0, 0))\n ((0, 0), (100, 100))\n >>> printSegments(splitLine((0, 0), (100, 100), 0, False))\n ((0, 0), (0, 0))\n ((0, 0), (100, 100))\n >>> printSegments(splitLine((100, 0), (0, 0), 50, False))\n ((100, 0), (50, 0))\n ((50, 0), (0, 0))\n >>> printSegments(splitLine((0, 100), (0, 0), 50, True))\n ((0, 100), (0, 50))\n ((0, 50), (0, 0))"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_25splitLine = {"splitLine", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_25splitLine, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_24splitLine}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_25splitLine(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_where = 0; + PyObject *__pyx_v_isHorizontal = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("splitLine (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_where,&__pyx_mstate_global->__pyx_n_u_isHorizontal,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 450, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 450, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 450, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 450, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 450, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "splitLine", 0) < (0)) __PYX_ERR(0, 450, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("splitLine", 1, 4, 4, i); __PYX_ERR(0, 450, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 450, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 450, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 450, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 450, __pyx_L3_error) + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_where = values[2]; + __pyx_v_isHorizontal = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("splitLine", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 450, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitLine", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_24splitLine(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_where, __pyx_v_isHorizontal); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_24splitLine(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_where, PyObject *__pyx_v_isHorizontal) { + PyObject *__pyx_v_pt1x = NULL; + PyObject *__pyx_v_pt1y = NULL; + PyObject *__pyx_v_pt2x = NULL; + PyObject *__pyx_v_pt2y = NULL; + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_a = NULL; + PyObject *__pyx_v_t = NULL; + PyObject *__pyx_v_midPt = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *(*__pyx_t_4)(PyObject *); + int __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("splitLine", 0); + + /* "fontTools/misc/bezierTools.py":486 + * ((0, 50), (0, 0)) + * """ + * pt1x, pt1y = pt1 # <<<<<<<<<<<<<< + * pt2x, pt2y = pt2 + * +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_pt1))) || (PyList_CheckExact(__pyx_v_pt1))) { + PyObject* sequence = __pyx_v_pt1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 486, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 486, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 486, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 486, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 486, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 486, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 486, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 486, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_pt1x = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_pt1y = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":487 + * """ + * pt1x, pt1y = pt1 + * pt2x, pt2y = pt2 # <<<<<<<<<<<<<< + * + * ax = pt2x - pt1x +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_pt2))) || (PyList_CheckExact(__pyx_v_pt2))) { + PyObject* sequence = __pyx_v_pt2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 487, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 487, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 487, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 487, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 487, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 487, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 487, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 487, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_pt2x = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_pt2y = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":489 + * pt2x, pt2y = pt2 + * + * ax = pt2x - pt1x # <<<<<<<<<<<<<< + * ay = pt2y - pt1y + * +*/ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_pt2x, __pyx_v_pt1x); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 489, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_ax = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":490 + * + * ax = pt2x - pt1x + * ay = pt2y - pt1y # <<<<<<<<<<<<<< + * + * bx = pt1x +*/ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_pt2y, __pyx_v_pt1y); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 490, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_ay = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":492 + * ay = pt2y - pt1y + * + * bx = pt1x # <<<<<<<<<<<<<< + * by = pt1y + * +*/ + __Pyx_INCREF(__pyx_v_pt1x); + __pyx_v_bx = __pyx_v_pt1x; + + /* "fontTools/misc/bezierTools.py":493 + * + * bx = pt1x + * by = pt1y # <<<<<<<<<<<<<< + * + * a = (ax, ay)[isHorizontal] +*/ + __Pyx_INCREF(__pyx_v_pt1y); + __pyx_v_by = __pyx_v_pt1y; + + /* "fontTools/misc/bezierTools.py":495 + * by = pt1y + * + * a = (ax, ay)[isHorizontal] # <<<<<<<<<<<<<< + * + * if a == 0: +*/ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 495, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_ax); + __Pyx_GIVEREF(__pyx_v_ax); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_ax) != (0)) __PYX_ERR(0, 495, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_ay); + __Pyx_GIVEREF(__pyx_v_ay); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_ay) != (0)) __PYX_ERR(0, 495, __pyx_L1_error); + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 495, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_a = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":497 + * a = (ax, ay)[isHorizontal] + * + * if a == 0: # <<<<<<<<<<<<<< + * return [(pt1, pt2)] + * t = (where - (bx, by)[isHorizontal]) / a +*/ + __pyx_t_5 = (__Pyx_PyLong_BoolEqObjC(__pyx_v_a, __pyx_mstate_global->__pyx_int_0, 0, 0)); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 497, __pyx_L1_error) + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":498 + * + * if a == 0: + * return [(pt1, pt2)] # <<<<<<<<<<<<<< + * t = (where - (bx, by)[isHorizontal]) / a + * if 0 <= t < 1: +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 498, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_pt1) != (0)) __PYX_ERR(0, 498, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt2); + __Pyx_GIVEREF(__pyx_v_pt2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_pt2) != (0)) __PYX_ERR(0, 498, __pyx_L1_error); + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 498, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_t_2) != (0)) __PYX_ERR(0, 498, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":497 + * a = (ax, ay)[isHorizontal] + * + * if a == 0: # <<<<<<<<<<<<<< + * return [(pt1, pt2)] + * t = (where - (bx, by)[isHorizontal]) / a +*/ + } + + /* "fontTools/misc/bezierTools.py":499 + * if a == 0: + * return [(pt1, pt2)] + * t = (where - (bx, by)[isHorizontal]) / a # <<<<<<<<<<<<<< + * if 0 <= t < 1: + * midPt = ax * t + bx, ay * t + by +*/ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 499, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_bx); + __Pyx_GIVEREF(__pyx_v_bx); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_bx) != (0)) __PYX_ERR(0, 499, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_by); + __Pyx_GIVEREF(__pyx_v_by); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_by) != (0)) __PYX_ERR(0, 499, __pyx_L1_error); + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 499, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Subtract(__pyx_v_where, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 499, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_v_a); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 499, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_t = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":500 + * return [(pt1, pt2)] + * t = (where - (bx, by)[isHorizontal]) / a + * if 0 <= t < 1: # <<<<<<<<<<<<<< + * midPt = ax * t + bx, ay * t + by + * return [(pt1, midPt), (midPt, pt2)] +*/ + __pyx_t_2 = PyObject_RichCompare(__pyx_mstate_global->__pyx_int_0, __pyx_v_t, Py_LE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 500, __pyx_L1_error) + if (__Pyx_PyObject_IsTrue(__pyx_t_2)) { + __Pyx_DECREF(__pyx_t_2); + __pyx_t_2 = PyObject_RichCompare(__pyx_v_t, __pyx_mstate_global->__pyx_int_1, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 500, __pyx_L1_error) + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 500, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":501 + * t = (where - (bx, by)[isHorizontal]) / a + * if 0 <= t < 1: + * midPt = ax * t + bx, ay * t + by # <<<<<<<<<<<<<< + * return [(pt1, midPt), (midPt, pt2)] + * else: +*/ + __pyx_t_2 = PyNumber_Multiply(__pyx_v_ax, __pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 501, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_bx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 501, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_v_ay, __pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 501, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Add(__pyx_t_2, __pyx_v_by); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 501, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 501, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 501, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3) != (0)) __PYX_ERR(0, 501, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_v_midPt = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":502 + * if 0 <= t < 1: + * midPt = ax * t + bx, ay * t + by + * return [(pt1, midPt), (midPt, pt2)] # <<<<<<<<<<<<<< + * else: + * return [(pt1, pt2)] +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 502, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_pt1) != (0)) __PYX_ERR(0, 502, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_midPt); + __Pyx_GIVEREF(__pyx_v_midPt); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_midPt) != (0)) __PYX_ERR(0, 502, __pyx_L1_error); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 502, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_midPt); + __Pyx_GIVEREF(__pyx_v_midPt); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_midPt) != (0)) __PYX_ERR(0, 502, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt2); + __Pyx_GIVEREF(__pyx_v_pt2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_pt2) != (0)) __PYX_ERR(0, 502, __pyx_L1_error); + __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 502, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_t_2) != (0)) __PYX_ERR(0, 502, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 1, __pyx_t_3) != (0)) __PYX_ERR(0, 502, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":500 + * return [(pt1, pt2)] + * t = (where - (bx, by)[isHorizontal]) / a + * if 0 <= t < 1: # <<<<<<<<<<<<<< + * midPt = ax * t + bx, ay * t + by + * return [(pt1, midPt), (midPt, pt2)] +*/ + } + + /* "fontTools/misc/bezierTools.py":504 + * return [(pt1, midPt), (midPt, pt2)] + * else: + * return [(pt1, pt2)] # <<<<<<<<<<<<<< + * + * +*/ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 504, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_pt1) != (0)) __PYX_ERR(0, 504, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt2); + __Pyx_GIVEREF(__pyx_v_pt2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_pt2) != (0)) __PYX_ERR(0, 504, __pyx_L1_error); + __pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 504, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 504, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + } + + /* "fontTools/misc/bezierTools.py":450 + * + * + * def splitLine(pt1, pt2, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a line at a given coordinate. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitLine", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_pt1x); + __Pyx_XDECREF(__pyx_v_pt1y); + __Pyx_XDECREF(__pyx_v_pt2x); + __Pyx_XDECREF(__pyx_v_pt2y); + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_a); + __Pyx_XDECREF(__pyx_v_t); + __Pyx_XDECREF(__pyx_v_midPt); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":507 + * + * + * def splitQuadratic(pt1, pt2, pt3, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a quadratic Bezier curve at a given coordinate. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_27splitQuadratic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_26splitQuadratic, "splitQuadratic(pt1, pt2, pt3, where, isHorizontal)\n\nSplit a quadratic Bezier curve at a given coordinate.\n\nArgs:\n pt1,pt2,pt3: Control points of the Bezier as 2D tuples.\n where: Position at which to split the curve.\n isHorizontal: Direction of the ray splitting the curve. If true,\n ``where`` is interpreted as a Y coordinate; if false, then\n ``where`` is interpreted as an X coordinate.\n\nReturns:\n A list of two curve segments (each curve segment being three 2D tuples)\n if the curve was successfully split, or a list containing the original\n curve.\n\nExample::\n\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 150, False))\n ((0, 0), (50, 100), (100, 0))\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, False))\n ((0, 0), (25, 50), (50, 50))\n ((50, 50), (75, 50), (100, 0))\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, False))\n ((0, 0), (12.5, 25), (25, 37.5))\n ((25, 37.5), (62.5, 75), (100, 0))\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, True))\n ((0, 0), (7.32233, 14.6447), (14.6447, 25))\n ((14.6447, 25), (50, 75), (85.3553, 25))\n ((85.3553, 25), (92.6777, 14.6447), (100, -7.10543e-15))\n >>> # XXX I'm not at all sure if the following behavior is desirable:\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, True))\n ((0, 0), (25, 50), (50, 50))\n ((50, 50), (50, 50), (50, 50))\n ((50, 50), (75, 50), (100, 0))"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_27splitQuadratic = {"splitQuadratic", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_27splitQuadratic, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_26splitQuadratic}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_27splitQuadratic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_where = 0; + PyObject *__pyx_v_isHorizontal = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("splitQuadratic (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,&__pyx_mstate_global->__pyx_n_u_where,&__pyx_mstate_global->__pyx_n_u_isHorizontal,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 507, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 5: + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 507, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 507, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 507, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 507, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 507, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "splitQuadratic", 0) < (0)) __PYX_ERR(0, 507, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 5; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("splitQuadratic", 1, 5, 5, i); __PYX_ERR(0, 507, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 5)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 507, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 507, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 507, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 507, __pyx_L3_error) + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 507, __pyx_L3_error) + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_where = values[3]; + __pyx_v_isHorizontal = values[4]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("splitQuadratic", 1, 5, 5, __pyx_nargs); __PYX_ERR(0, 507, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitQuadratic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_26splitQuadratic(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_where, __pyx_v_isHorizontal); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_14splitQuadratic_2generator2(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/misc/bezierTools.py":546 + * a[isHorizontal], b[isHorizontal], c[isHorizontal] - where + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) # <<<<<<<<<<<<<< + * if not solutions: + * return [(pt1, pt2, pt3)] +*/ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_14splitQuadratic_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("genexpr", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr(__pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr, __pyx_mstate_global->__pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 546, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_genexpr_arg_0 = __pyx_genexpr_arg_0; + __Pyx_INCREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_4misc_11bezierTools_14splitQuadratic_2generator2, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[0]), (PyObject *) __pyx_cur_scope, __pyx_mstate_global->__pyx_n_u_genexpr, __pyx_mstate_global->__pyx_n_u_splitQuadratic_locals_genexpr, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools); if (unlikely(!gen)) __PYX_ERR(0, 546, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitQuadratic.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_14splitQuadratic_2generator2(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *(*__pyx_t_3)(PyObject *); + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("genexpr", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 546, __pyx_L1_error) + __pyx_r = PyList_New(0); if (unlikely(!__pyx_r)) __PYX_ERR(0, 546, __pyx_L1_error) + __Pyx_GOTREF(__pyx_r); + if (unlikely(!__pyx_cur_scope->__pyx_genexpr_arg_0)) { __Pyx_RaiseUnboundLocalError(".0"); __PYX_ERR(0, 546, __pyx_L1_error) } + if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) { + __pyx_t_1 = __pyx_cur_scope->__pyx_genexpr_arg_0; __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = 0; + __pyx_t_3 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_genexpr_arg_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 546, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 546, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_3)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 546, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(__pyx_t_1, __pyx_t_2, __Pyx_ReferenceSharing_OwnStrongReference); + ++__pyx_t_2; + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 546, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = __Pyx_NewRef(PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2)); + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); + #endif + ++__pyx_t_2; + } + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 546, __pyx_L1_error) + } else { + __pyx_t_4 = __pyx_t_3(__pyx_t_1); + if (unlikely(!__pyx_t_4)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 546, __pyx_L1_error) + PyErr_Clear(); + } + break; + } + } + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_t); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_t, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + __pyx_t_4 = 0; + __pyx_t_4 = PyObject_RichCompare(__pyx_mstate_global->__pyx_int_0, __pyx_cur_scope->__pyx_v_t, Py_LE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 546, __pyx_L1_error) + if (__Pyx_PyObject_IsTrue(__pyx_t_4)) { + __Pyx_DECREF(__pyx_t_4); + __pyx_t_4 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_t, __pyx_mstate_global->__pyx_int_1, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 546, __pyx_L1_error) + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 546, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_5) { + if (unlikely(__Pyx_ListComp_Append(__pyx_r, (PyObject*)__pyx_cur_scope->__pyx_v_t))) __PYX_ERR(0, 546, __pyx_L1_error) + } + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_r); __pyx_r = 0; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + if (__Pyx_PyErr_Occurred()) { + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":507 + * + * + * def splitQuadratic(pt1, pt2, pt3, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a quadratic Bezier curve at a given coordinate. + * +*/ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_26splitQuadratic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_where, PyObject *__pyx_v_isHorizontal) { + PyObject *__pyx_v_a = NULL; + PyObject *__pyx_v_b = NULL; + PyObject *__pyx_v_c = NULL; + PyObject *__pyx_v_solutions = NULL; + PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_14splitQuadratic_2generator2 = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + size_t __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *(*__pyx_t_7)(PyObject *); + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_t_10; + int __pyx_t_11; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("splitQuadratic", 0); + + /* "fontTools/misc/bezierTools.py":542 + * ((50, 50), (75, 50), (100, 0)) + * """ + * a, b, c = calcQuadraticParameters(pt1, pt2, pt3) # <<<<<<<<<<<<<< + * solutions = solveQuadratic( + * a[isHorizontal], b[isHorizontal], c[isHorizontal] - where +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_calcQuadraticParameters); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 542, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_2, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_4, (4-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 542, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 3)) { + if (size > 3) __Pyx_RaiseTooManyValuesError(3); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 542, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_3); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 2); + __Pyx_INCREF(__pyx_t_5); + } else { + __pyx_t_3 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 542, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 542, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_5 = __Pyx_PyList_GetItemRefFast(sequence, 2, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 542, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_5); + } + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 542, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 542, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = __Pyx_PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 542, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_6 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 542, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); + index = 0; __pyx_t_3 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_3)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 1; __pyx_t_2 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 2; __pyx_t_5 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_5)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_5); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 3) < (0)) __PYX_ERR(0, 542, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 542, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_a = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_b = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_c = __pyx_t_5; + __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":543 + * """ + * a, b, c = calcQuadraticParameters(pt1, pt2, pt3) + * solutions = solveQuadratic( # <<<<<<<<<<<<<< + * a[isHorizontal], b[isHorizontal], c[isHorizontal] - where + * ) +*/ + __pyx_t_5 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_solveQuadratic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 543, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/misc/bezierTools.py":544 + * a, b, c = calcQuadraticParameters(pt1, pt2, pt3) + * solutions = solveQuadratic( + * a[isHorizontal], b[isHorizontal], c[isHorizontal] - where # <<<<<<<<<<<<<< + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) +*/ + __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_a, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 544, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_v_b, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 544, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_8 = __Pyx_PyObject_GetItem(__pyx_v_c, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 544, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = PyNumber_Subtract(__pyx_t_8, __pyx_v_where); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 544, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_5); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_5, __pyx_t_3, __pyx_t_6, __pyx_t_9}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_4, (4-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 543, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_v_solutions = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":546 + * a[isHorizontal], b[isHorizontal], c[isHorizontal] - where + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) # <<<<<<<<<<<<<< + * if not solutions: + * return [(pt1, pt2, pt3)] +*/ + __pyx_t_1 = __pyx_pf_9fontTools_4misc_11bezierTools_14splitQuadratic_genexpr(NULL, __pyx_v_solutions); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 546, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_Generator_GetInlinedResult(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 546, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely((PyList_Sort(__pyx_t_2) < 0))) __PYX_ERR(0, 546, __pyx_L1_error) + __Pyx_DECREF_SET(__pyx_v_solutions, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":547 + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) + * if not solutions: # <<<<<<<<<<<<<< + * return [(pt1, pt2, pt3)] + * return _splitQuadraticAtT(a, b, c, *solutions) +*/ + __pyx_t_10 = __Pyx_PyObject_IsTrue(__pyx_v_solutions); if (unlikely((__pyx_t_10 < 0))) __PYX_ERR(0, 547, __pyx_L1_error) + __pyx_t_11 = (!__pyx_t_10); + if (__pyx_t_11) { + + /* "fontTools/misc/bezierTools.py":548 + * solutions = sorted(t for t in solutions if 0 <= t < 1) + * if not solutions: + * return [(pt1, pt2, pt3)] # <<<<<<<<<<<<<< + * return _splitQuadraticAtT(a, b, c, *solutions) + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 548, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_pt1) != (0)) __PYX_ERR(0, 548, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt2); + __Pyx_GIVEREF(__pyx_v_pt2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_pt2) != (0)) __PYX_ERR(0, 548, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt3); + __Pyx_GIVEREF(__pyx_v_pt3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_pt3) != (0)) __PYX_ERR(0, 548, __pyx_L1_error); + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 548, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_t_2) != (0)) __PYX_ERR(0, 548, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":547 + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) + * if not solutions: # <<<<<<<<<<<<<< + * return [(pt1, pt2, pt3)] + * return _splitQuadraticAtT(a, b, c, *solutions) +*/ + } + + /* "fontTools/misc/bezierTools.py":549 + * if not solutions: + * return [(pt1, pt2, pt3)] + * return _splitQuadraticAtT(a, b, c, *solutions) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_splitQuadraticAtT); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 549, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 549, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_a); + __Pyx_GIVEREF(__pyx_v_a); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_a) != (0)) __PYX_ERR(0, 549, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_b); + __Pyx_GIVEREF(__pyx_v_b); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_b) != (0)) __PYX_ERR(0, 549, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_c); + __Pyx_GIVEREF(__pyx_v_c); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_c) != (0)) __PYX_ERR(0, 549, __pyx_L1_error); + __pyx_t_9 = __Pyx_PySequence_Tuple(__pyx_v_solutions); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 549, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_6 = PyNumber_Add(__pyx_t_2, __pyx_t_9); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 549, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_6, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 549, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_r = __pyx_t_9; + __pyx_t_9 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":507 + * + * + * def splitQuadratic(pt1, pt2, pt3, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a quadratic Bezier curve at a given coordinate. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitQuadratic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_a); + __Pyx_XDECREF(__pyx_v_b); + __Pyx_XDECREF(__pyx_v_c); + __Pyx_XDECREF(__pyx_v_solutions); + __Pyx_XDECREF(__pyx_gb_9fontTools_4misc_11bezierTools_14splitQuadratic_2generator2); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":552 + * + * + * def splitCubic(pt1, pt2, pt3, pt4, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a cubic Bezier curve at a given coordinate. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_29splitCubic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_28splitCubic, "splitCubic(pt1, pt2, pt3, pt4, where, isHorizontal)\n\nSplit a cubic Bezier curve at a given coordinate.\n\nArgs:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n where: Position at which to split the curve.\n isHorizontal: Direction of the ray splitting the curve. If true,\n ``where`` is interpreted as a Y coordinate; if false, then\n ``where`` is interpreted as an X coordinate.\n\nReturns:\n A list of two curve segments (each curve segment being four 2D tuples)\n if the curve was successfully split, or a list containing the original\n curve.\n\nExample::\n\n >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 150, False))\n ((0, 0), (25, 100), (75, 100), (100, 0))\n >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 50, False))\n ((0, 0), (12.5, 50), (31.25, 75), (50, 75))\n ((50, 75), (68.75, 75), (87.5, 50), (100, 0))\n >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 25, True))\n ((0, 0), (2.29379, 9.17517), (4.79804, 17.5085), (7.47414, 25))\n ((7.47414, 25), (31.2886, 91.6667), (68.7114, 91.6667), (92.5259, 25))\n ((92.5259, 25), (95.202, 17.5085), (97.7062, 9.17517), (100, 1.77636e-15))"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_29splitCubic = {"splitCubic", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_29splitCubic, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_28splitCubic}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_29splitCubic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_pt4 = 0; + PyObject *__pyx_v_where = 0; + PyObject *__pyx_v_isHorizontal = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[6] = {0,0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("splitCubic (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,&__pyx_mstate_global->__pyx_n_u_pt4,&__pyx_mstate_global->__pyx_n_u_where,&__pyx_mstate_global->__pyx_n_u_isHorizontal,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 552, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 6: + values[5] = __Pyx_ArgRef_FASTCALL(__pyx_args, 5); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[5])) __PYX_ERR(0, 552, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 5: + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 552, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 552, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 552, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 552, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 552, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "splitCubic", 0) < (0)) __PYX_ERR(0, 552, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 6; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("splitCubic", 1, 6, 6, i); __PYX_ERR(0, 552, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 6)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 552, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 552, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 552, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 552, __pyx_L3_error) + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 552, __pyx_L3_error) + values[5] = __Pyx_ArgRef_FASTCALL(__pyx_args, 5); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[5])) __PYX_ERR(0, 552, __pyx_L3_error) + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_pt4 = values[3]; + __pyx_v_where = values[4]; + __pyx_v_isHorizontal = values[5]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("splitCubic", 1, 6, 6, __pyx_nargs); __PYX_ERR(0, 552, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_28splitCubic(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4, __pyx_v_where, __pyx_v_isHorizontal); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_10splitCubic_2generator3(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/misc/bezierTools.py":583 + * a[isHorizontal], b[isHorizontal], c[isHorizontal], d[isHorizontal] - where + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) # <<<<<<<<<<<<<< + * if not solutions: + * return [(pt1, pt2, pt3, pt4)] +*/ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_10splitCubic_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("genexpr", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr(__pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr, __pyx_mstate_global->__pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 583, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_genexpr_arg_0 = __pyx_genexpr_arg_0; + __Pyx_INCREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_4misc_11bezierTools_10splitCubic_2generator3, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[1]), (PyObject *) __pyx_cur_scope, __pyx_mstate_global->__pyx_n_u_genexpr, __pyx_mstate_global->__pyx_n_u_splitCubic_locals_genexpr, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools); if (unlikely(!gen)) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubic.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_10splitCubic_2generator3(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *(*__pyx_t_3)(PyObject *); + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("genexpr", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 583, __pyx_L1_error) + __pyx_r = PyList_New(0); if (unlikely(!__pyx_r)) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_GOTREF(__pyx_r); + if (unlikely(!__pyx_cur_scope->__pyx_genexpr_arg_0)) { __Pyx_RaiseUnboundLocalError(".0"); __PYX_ERR(0, 583, __pyx_L1_error) } + if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) { + __pyx_t_1 = __pyx_cur_scope->__pyx_genexpr_arg_0; __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = 0; + __pyx_t_3 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_genexpr_arg_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 583, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_3)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 583, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(__pyx_t_1, __pyx_t_2, __Pyx_ReferenceSharing_OwnStrongReference); + ++__pyx_t_2; + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 583, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = __Pyx_NewRef(PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2)); + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); + #endif + ++__pyx_t_2; + } + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 583, __pyx_L1_error) + } else { + __pyx_t_4 = __pyx_t_3(__pyx_t_1); + if (unlikely(!__pyx_t_4)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 583, __pyx_L1_error) + PyErr_Clear(); + } + break; + } + } + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_t); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_t, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + __pyx_t_4 = 0; + __pyx_t_4 = PyObject_RichCompare(__pyx_mstate_global->__pyx_int_0, __pyx_cur_scope->__pyx_v_t, Py_LE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 583, __pyx_L1_error) + if (__Pyx_PyObject_IsTrue(__pyx_t_4)) { + __Pyx_DECREF(__pyx_t_4); + __pyx_t_4 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_t, __pyx_mstate_global->__pyx_int_1, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 583, __pyx_L1_error) + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_5) { + if (unlikely(__Pyx_ListComp_Append(__pyx_r, (PyObject*)__pyx_cur_scope->__pyx_v_t))) __PYX_ERR(0, 583, __pyx_L1_error) + } + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_r); __pyx_r = 0; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + if (__Pyx_PyErr_Occurred()) { + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":552 + * + * + * def splitCubic(pt1, pt2, pt3, pt4, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a cubic Bezier curve at a given coordinate. + * +*/ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_28splitCubic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4, PyObject *__pyx_v_where, PyObject *__pyx_v_isHorizontal) { + PyObject *__pyx_v_a = NULL; + PyObject *__pyx_v_b = NULL; + PyObject *__pyx_v_c = NULL; + PyObject *__pyx_v_d = NULL; + PyObject *__pyx_v_solutions = NULL; + PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_10splitCubic_2generator3 = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + size_t __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *(*__pyx_t_8)(PyObject *); + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + int __pyx_t_11; + int __pyx_t_12; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("splitCubic", 0); + + /* "fontTools/misc/bezierTools.py":579 + * ((92.5259, 25), (95.202, 17.5085), (97.7062, 9.17517), (100, 1.77636e-15)) + * """ + * a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) # <<<<<<<<<<<<<< + * solutions = solveCubic( + * a[isHorizontal], b[isHorizontal], c[isHorizontal], d[isHorizontal] - where +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_calcCubicParameters); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 579, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_2, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_4, (5-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 579, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 579, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_3); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 2); + __Pyx_INCREF(__pyx_t_5); + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 3); + __Pyx_INCREF(__pyx_t_6); + } else { + __pyx_t_3 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 579, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 579, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_5 = __Pyx_PyList_GetItemRefFast(sequence, 2, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 579, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyList_GetItemRefFast(sequence, 3, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 579, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_6); + } + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_3,&__pyx_t_2,&__pyx_t_5,&__pyx_t_6}; + for (i=0; i < 4; i++) { + PyObject* item = __Pyx_PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 579, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_3,&__pyx_t_2,&__pyx_t_5,&__pyx_t_6}; + __pyx_t_7 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 579, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_8 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_7); + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_8(__pyx_t_7); if (unlikely(!item)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 4) < (0)) __PYX_ERR(0, 579, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 579, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_a = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_b = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_c = __pyx_t_5; + __pyx_t_5 = 0; + __pyx_v_d = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":580 + * """ + * a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) + * solutions = solveCubic( # <<<<<<<<<<<<<< + * a[isHorizontal], b[isHorizontal], c[isHorizontal], d[isHorizontal] - where + * ) +*/ + __pyx_t_6 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_solveCubic); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 580, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + + /* "fontTools/misc/bezierTools.py":581 + * a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) + * solutions = solveCubic( + * a[isHorizontal], b[isHorizontal], c[isHorizontal], d[isHorizontal] - where # <<<<<<<<<<<<<< + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) +*/ + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_v_a, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 581, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_v_b, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 581, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = __Pyx_PyObject_GetItem(__pyx_v_c, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 581, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_9 = __Pyx_PyObject_GetItem(__pyx_v_d, __pyx_v_isHorizontal); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 581, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = PyNumber_Subtract(__pyx_t_9, __pyx_v_where); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 581, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5); + assert(__pyx_t_6); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_5, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_6, __pyx_t_2, __pyx_t_3, __pyx_t_7, __pyx_t_10}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_5, __pyx_callargs+__pyx_t_4, (5-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 580, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_v_solutions = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":583 + * a[isHorizontal], b[isHorizontal], c[isHorizontal], d[isHorizontal] - where + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) # <<<<<<<<<<<<<< + * if not solutions: + * return [(pt1, pt2, pt3, pt4)] +*/ + __pyx_t_1 = __pyx_pf_9fontTools_4misc_11bezierTools_10splitCubic_genexpr(NULL, __pyx_v_solutions); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __Pyx_Generator_GetInlinedResult(__pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely((PyList_Sort(__pyx_t_5) < 0))) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_DECREF_SET(__pyx_v_solutions, __pyx_t_5); + __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":584 + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) + * if not solutions: # <<<<<<<<<<<<<< + * return [(pt1, pt2, pt3, pt4)] + * return _splitCubicAtT(a, b, c, d, *solutions) +*/ + __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_v_solutions); if (unlikely((__pyx_t_11 < 0))) __PYX_ERR(0, 584, __pyx_L1_error) + __pyx_t_12 = (!__pyx_t_11); + if (__pyx_t_12) { + + /* "fontTools/misc/bezierTools.py":585 + * solutions = sorted(t for t in solutions if 0 <= t < 1) + * if not solutions: + * return [(pt1, pt2, pt3, pt4)] # <<<<<<<<<<<<<< + * return _splitCubicAtT(a, b, c, d, *solutions) + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 585, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_pt1) != (0)) __PYX_ERR(0, 585, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt2); + __Pyx_GIVEREF(__pyx_v_pt2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_pt2) != (0)) __PYX_ERR(0, 585, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt3); + __Pyx_GIVEREF(__pyx_v_pt3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_v_pt3) != (0)) __PYX_ERR(0, 585, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt4); + __Pyx_GIVEREF(__pyx_v_pt4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_v_pt4) != (0)) __PYX_ERR(0, 585, __pyx_L1_error); + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 585, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_t_5) != (0)) __PYX_ERR(0, 585, __pyx_L1_error); + __pyx_t_5 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":584 + * ) + * solutions = sorted(t for t in solutions if 0 <= t < 1) + * if not solutions: # <<<<<<<<<<<<<< + * return [(pt1, pt2, pt3, pt4)] + * return _splitCubicAtT(a, b, c, d, *solutions) +*/ + } + + /* "fontTools/misc/bezierTools.py":586 + * if not solutions: + * return [(pt1, pt2, pt3, pt4)] + * return _splitCubicAtT(a, b, c, d, *solutions) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_splitCubicAtT); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 586, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 586, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_a); + __Pyx_GIVEREF(__pyx_v_a); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_a) != (0)) __PYX_ERR(0, 586, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_b); + __Pyx_GIVEREF(__pyx_v_b); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_b) != (0)) __PYX_ERR(0, 586, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_c); + __Pyx_GIVEREF(__pyx_v_c); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_v_c) != (0)) __PYX_ERR(0, 586, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_d); + __Pyx_GIVEREF(__pyx_v_d); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_v_d) != (0)) __PYX_ERR(0, 586, __pyx_L1_error); + __pyx_t_10 = __Pyx_PySequence_Tuple(__pyx_v_solutions); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 586, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_7 = PyNumber_Add(__pyx_t_5, __pyx_t_10); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 586, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_7, NULL); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 586, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_r = __pyx_t_10; + __pyx_t_10 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":552 + * + * + * def splitCubic(pt1, pt2, pt3, pt4, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a cubic Bezier curve at a given coordinate. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_a); + __Pyx_XDECREF(__pyx_v_b); + __Pyx_XDECREF(__pyx_v_c); + __Pyx_XDECREF(__pyx_v_d); + __Pyx_XDECREF(__pyx_v_solutions); + __Pyx_XDECREF(__pyx_gb_9fontTools_4misc_11bezierTools_10splitCubic_2generator3); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":589 + * + * + * def splitQuadraticAtT(pt1, pt2, pt3, *ts): # <<<<<<<<<<<<<< + * """Split a quadratic Bezier curve at one or more values of t. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_31splitQuadraticAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_30splitQuadraticAtT, "splitQuadraticAtT(pt1, pt2, pt3, *ts)\n\nSplit a quadratic Bezier curve at one or more values of t.\n\nArgs:\n pt1,pt2,pt3: Control points of the Bezier as 2D tuples.\n *ts: Positions at which to split the curve.\n\nReturns:\n A list of curve segments (each curve segment being three 2D tuples).\n\nExamples::\n\n >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5))\n ((0, 0), (25, 50), (50, 50))\n ((50, 50), (75, 50), (100, 0))\n >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5, 0.75))\n ((0, 0), (25, 50), (50, 50))\n ((50, 50), (62.5, 50), (75, 37.5))\n ((75, 37.5), (87.5, 25), (100, 0))"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_31splitQuadraticAtT = {"splitQuadraticAtT", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_31splitQuadraticAtT, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_30splitQuadraticAtT}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_31splitQuadraticAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_ts = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("splitQuadraticAtT (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + __pyx_v_ts = __Pyx_ArgsSlice_FASTCALL(__pyx_args, 3, __pyx_nargs); + if (unlikely(!__pyx_v_ts)) { + __Pyx_RefNannyFinishContext(); + return NULL; + } + __Pyx_GOTREF(__pyx_v_ts); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 589, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + default: + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 589, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 589, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 589, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + const Py_ssize_t used_pos_args = (kwd_pos_args < 3) ? kwd_pos_args : 3; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, used_pos_args, __pyx_kwds_len, "splitQuadraticAtT", 0) < (0)) __PYX_ERR(0, 589, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 3; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("splitQuadraticAtT", 0, 3, 3, i); __PYX_ERR(0, 589, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs < 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 589, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 589, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 589, __pyx_L3_error) + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("splitQuadraticAtT", 0, 3, 3, __pyx_nargs); __PYX_ERR(0, 589, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_DECREF(__pyx_v_ts); __pyx_v_ts = 0; + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitQuadraticAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_30splitQuadraticAtT(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_ts); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_DECREF(__pyx_v_ts); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_30splitQuadraticAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_ts) { + PyObject *__pyx_v_a = NULL; + PyObject *__pyx_v_b = NULL; + PyObject *__pyx_v_c = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + size_t __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *(*__pyx_t_7)(PyObject *); + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("splitQuadraticAtT", 0); + + /* "fontTools/misc/bezierTools.py":609 + * ((75, 37.5), (87.5, 25), (100, 0)) + * """ + * a, b, c = calcQuadraticParameters(pt1, pt2, pt3) # <<<<<<<<<<<<<< + * return _splitQuadraticAtT(a, b, c, *ts) + * +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_calcQuadraticParameters); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 609, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_2, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_4, (4-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 609, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 3)) { + if (size > 3) __Pyx_RaiseTooManyValuesError(3); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 609, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_3); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 2); + __Pyx_INCREF(__pyx_t_5); + } else { + __pyx_t_3 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 609, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 609, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_5 = __Pyx_PyList_GetItemRefFast(sequence, 2, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 609, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_5); + } + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 609, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 609, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = __Pyx_PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 609, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_6 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 609, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); + index = 0; __pyx_t_3 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_3)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 1; __pyx_t_2 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 2; __pyx_t_5 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_5)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_5); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 3) < (0)) __PYX_ERR(0, 609, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 609, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_a = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_b = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_c = __pyx_t_5; + __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":610 + * """ + * a, b, c = calcQuadraticParameters(pt1, pt2, pt3) + * return _splitQuadraticAtT(a, b, c, *ts) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_splitQuadraticAtT); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 610, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 610, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_a); + __Pyx_GIVEREF(__pyx_v_a); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_a) != (0)) __PYX_ERR(0, 610, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_b); + __Pyx_GIVEREF(__pyx_v_b); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_b) != (0)) __PYX_ERR(0, 610, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_c); + __Pyx_GIVEREF(__pyx_v_c); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_v_c) != (0)) __PYX_ERR(0, 610, __pyx_L1_error); + __pyx_t_2 = PyNumber_Add(__pyx_t_5, __pyx_v_ts); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 610, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_2, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 610, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":589 + * + * + * def splitQuadraticAtT(pt1, pt2, pt3, *ts): # <<<<<<<<<<<<<< + * """Split a quadratic Bezier curve at one or more values of t. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitQuadraticAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_a); + __Pyx_XDECREF(__pyx_v_b); + __Pyx_XDECREF(__pyx_v_c); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":613 + * + * + * def splitCubicAtT(pt1, pt2, pt3, pt4, *ts): # <<<<<<<<<<<<<< + * """Split a cubic Bezier curve at one or more values of t. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_33splitCubicAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_32splitCubicAtT, "splitCubicAtT(pt1, pt2, pt3, pt4, *ts)\n\nSplit a cubic Bezier curve at one or more values of t.\n\nArgs:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n *ts: Positions at which to split the curve.\n\nReturns:\n A list of curve segments (each curve segment being four 2D tuples).\n\nExamples::\n\n >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5))\n ((0, 0), (12.5, 50), (31.25, 75), (50, 75))\n ((50, 75), (68.75, 75), (87.5, 50), (100, 0))\n >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5, 0.75))\n ((0, 0), (12.5, 50), (31.25, 75), (50, 75))\n ((50, 75), (59.375, 75), (68.75, 68.75), (77.3438, 56.25))\n ((77.3438, 56.25), (85.9375, 43.75), (93.75, 25), (100, 0))"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_33splitCubicAtT = {"splitCubicAtT", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_33splitCubicAtT, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_32splitCubicAtT}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_33splitCubicAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_pt4 = 0; + PyObject *__pyx_v_ts = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("splitCubicAtT (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + __pyx_v_ts = __Pyx_ArgsSlice_FASTCALL(__pyx_args, 4, __pyx_nargs); + if (unlikely(!__pyx_v_ts)) { + __Pyx_RefNannyFinishContext(); + return NULL; + } + __Pyx_GOTREF(__pyx_v_ts); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,&__pyx_mstate_global->__pyx_n_u_pt4,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 613, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + default: + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 613, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 613, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 613, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 613, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + const Py_ssize_t used_pos_args = (kwd_pos_args < 4) ? kwd_pos_args : 4; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, used_pos_args, __pyx_kwds_len, "splitCubicAtT", 0) < (0)) __PYX_ERR(0, 613, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("splitCubicAtT", 0, 4, 4, i); __PYX_ERR(0, 613, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs < 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 613, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 613, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 613, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 613, __pyx_L3_error) + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_pt4 = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("splitCubicAtT", 0, 4, 4, __pyx_nargs); __PYX_ERR(0, 613, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_DECREF(__pyx_v_ts); __pyx_v_ts = 0; + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubicAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_32splitCubicAtT(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4, __pyx_v_ts); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_DECREF(__pyx_v_ts); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_32splitCubicAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4, PyObject *__pyx_v_ts) { + PyObject *__pyx_v_a = NULL; + PyObject *__pyx_v_b = NULL; + PyObject *__pyx_v_c = NULL; + PyObject *__pyx_v_d = NULL; + PyObject *__pyx_v_split = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + size_t __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *(*__pyx_t_8)(PyObject *); + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("splitCubicAtT", 0); + + /* "fontTools/misc/bezierTools.py":633 + * ((77.3438, 56.25), (85.9375, 43.75), (93.75, 25), (100, 0)) + * """ + * a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) # <<<<<<<<<<<<<< + * split = _splitCubicAtT(a, b, c, d, *ts) + * +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_calcCubicParameters); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 633, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_2, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_4, (5-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 633, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 633, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_3); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 2); + __Pyx_INCREF(__pyx_t_5); + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 3); + __Pyx_INCREF(__pyx_t_6); + } else { + __pyx_t_3 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 633, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 633, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_5 = __Pyx_PyList_GetItemRefFast(sequence, 2, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 633, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyList_GetItemRefFast(sequence, 3, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 633, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_6); + } + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_3,&__pyx_t_2,&__pyx_t_5,&__pyx_t_6}; + for (i=0; i < 4; i++) { + PyObject* item = __Pyx_PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 633, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_3,&__pyx_t_2,&__pyx_t_5,&__pyx_t_6}; + __pyx_t_7 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 633, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_8 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_7); + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_8(__pyx_t_7); if (unlikely(!item)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 4) < (0)) __PYX_ERR(0, 633, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 633, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_a = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_b = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_c = __pyx_t_5; + __pyx_t_5 = 0; + __pyx_v_d = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":634 + * """ + * a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) + * split = _splitCubicAtT(a, b, c, d, *ts) # <<<<<<<<<<<<<< + * + * # the split impl can introduce floating point errors; we know the first +*/ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_splitCubicAtT); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 634, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 634, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_INCREF(__pyx_v_a); + __Pyx_GIVEREF(__pyx_v_a); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_v_a) != (0)) __PYX_ERR(0, 634, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_b); + __Pyx_GIVEREF(__pyx_v_b); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_v_b) != (0)) __PYX_ERR(0, 634, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_c); + __Pyx_GIVEREF(__pyx_v_c); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_v_c) != (0)) __PYX_ERR(0, 634, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_d); + __Pyx_GIVEREF(__pyx_v_d); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_v_d) != (0)) __PYX_ERR(0, 634, __pyx_L1_error); + __pyx_t_5 = PyNumber_Add(__pyx_t_6, __pyx_v_ts); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 634, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_5, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 634, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_v_split = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":639 + * # segment should always start at pt1 and the last segment should end at pt4, + * # so we set those values directly before returning. + * split[0] = (pt1, *split[0][1:]) # <<<<<<<<<<<<<< + * split[-1] = (*split[-1][:-1], pt4) + * return split +*/ + __pyx_t_5 = PyList_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 639, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_5, 0, __pyx_v_pt1) != (0)) __PYX_ERR(0, 639, __pyx_L1_error); + __pyx_t_6 = __pyx_t_5; + __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_split, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 639, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_1 = __Pyx_PyObject_GetSlice(__pyx_t_5, 1, 0, NULL, NULL, &__pyx_mstate_global->__pyx_slice[0], 1, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 639, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (__Pyx_PyList_Extend(__pyx_t_6, __pyx_t_1) < (0)) __PYX_ERR(0, 639, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + { + PyObject *__pyx_temp = PyList_AsTuple(__pyx_t_6); + __Pyx_DECREF(__pyx_t_6); + __pyx_t_6 = __pyx_temp; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 639, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + if (unlikely((__Pyx_SetItemInt(__pyx_v_split, 0, __pyx_t_6, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference) < 0))) __PYX_ERR(0, 639, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":640 + * # so we set those values directly before returning. + * split[0] = (pt1, *split[0][1:]) + * split[-1] = (*split[-1][:-1], pt4) # <<<<<<<<<<<<<< + * return split + * +*/ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_split, -1L, long, 1, __Pyx_PyLong_From_long, 0, 1, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 640, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __Pyx_PyObject_GetSlice(__pyx_t_1, 0, -1L, NULL, NULL, &__pyx_mstate_global->__pyx_slice[1], 0, 1, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 640, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_6 = __Pyx_PySequence_ListKeepNew(__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 640, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (__Pyx_ListComp_Append(__pyx_t_6, __pyx_v_pt4) < (0)) __PYX_ERR(0, 640, __pyx_L1_error) + { + PyObject *__pyx_temp = PyList_AsTuple(__pyx_t_6); + __Pyx_DECREF(__pyx_t_6); + __pyx_t_6 = __pyx_temp; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 640, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + if (unlikely((__Pyx_SetItemInt(__pyx_v_split, -1L, __pyx_t_6, long, 1, __Pyx_PyLong_From_long, 0, 1, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference) < 0))) __PYX_ERR(0, 640, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":641 + * split[0] = (pt1, *split[0][1:]) + * split[-1] = (*split[-1][:-1], pt4) + * return split # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_split); + __pyx_r = __pyx_v_split; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":613 + * + * + * def splitCubicAtT(pt1, pt2, pt3, pt4, *ts): # <<<<<<<<<<<<<< + * """Split a cubic Bezier curve at one or more values of t. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubicAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_a); + __Pyx_XDECREF(__pyx_v_b); + __Pyx_XDECREF(__pyx_v_c); + __Pyx_XDECREF(__pyx_v_d); + __Pyx_XDECREF(__pyx_v_split); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_36generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/misc/bezierTools.py":644 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * pt1=cython.complex, + * pt2=cython.complex, +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_35splitCubicAtTC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_34splitCubicAtTC, "splitCubicAtTC(double complex pt1, double complex pt2, double complex pt3, double complex pt4, *ts)\n\nSplit a cubic Bezier curve at one or more values of t.\n\nArgs:\n pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers..\n *ts: Positions at which to split the curve.\n\nYields:\n Curve segments (each curve segment being four complex numbers)."); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_35splitCubicAtTC = {"splitCubicAtTC", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_35splitCubicAtTC, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_34splitCubicAtTC}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_35splitCubicAtTC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_pt1; + __pyx_t_double_complex __pyx_v_pt2; + __pyx_t_double_complex __pyx_v_pt3; + __pyx_t_double_complex __pyx_v_pt4; + PyObject *__pyx_v_ts = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("splitCubicAtTC (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + __pyx_v_ts = __Pyx_ArgsSlice_FASTCALL(__pyx_args, 4, __pyx_nargs); + if (unlikely(!__pyx_v_ts)) { + __Pyx_RefNannyFinishContext(); + return NULL; + } + __Pyx_GOTREF(__pyx_v_ts); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,&__pyx_mstate_global->__pyx_n_u_pt4,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 644, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + default: + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 644, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 644, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 644, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 644, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + const Py_ssize_t used_pos_args = (kwd_pos_args < 4) ? kwd_pos_args : 4; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, used_pos_args, __pyx_kwds_len, "splitCubicAtTC", 0) < (0)) __PYX_ERR(0, 644, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("splitCubicAtTC", 0, 4, 4, i); __PYX_ERR(0, 644, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs < 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 644, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 644, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 644, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 644, __pyx_L3_error) + } + __pyx_v_pt1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 654, __pyx_L3_error) + __pyx_v_pt2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 654, __pyx_L3_error) + __pyx_v_pt3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 654, __pyx_L3_error) + __pyx_v_pt4 = __Pyx_PyComplex_As___pyx_t_double_complex(values[3]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 654, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("splitCubicAtTC", 0, 4, 4, __pyx_nargs); __PYX_ERR(0, 644, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_CLEAR(__pyx_v_ts); + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubicAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_34splitCubicAtTC(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4, __pyx_v_ts); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_DECREF(__pyx_v_ts); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_34splitCubicAtTC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4, PyObject *__pyx_v_ts) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("splitCubicAtTC", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC(__pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC, __pyx_mstate_global->__pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 644, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_v_pt1 = __pyx_v_pt1; + __pyx_cur_scope->__pyx_v_pt2 = __pyx_v_pt2; + __pyx_cur_scope->__pyx_v_pt3 = __pyx_v_pt3; + __pyx_cur_scope->__pyx_v_pt4 = __pyx_v_pt4; + __pyx_cur_scope->__pyx_v_ts = __pyx_v_ts; + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_ts); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_ts); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_4misc_11bezierTools_36generator, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[2]), (PyObject *) __pyx_cur_scope, __pyx_mstate_global->__pyx_n_u_splitCubicAtTC, __pyx_mstate_global->__pyx_n_u_splitCubicAtTC, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools); if (unlikely(!gen)) __PYX_ERR(0, 644, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubicAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_36generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *(*__pyx_t_7)(PyObject *); + __pyx_t_double_complex __pyx_t_8; + __pyx_t_double_complex __pyx_t_9; + __pyx_t_double_complex __pyx_t_10; + __pyx_t_double_complex __pyx_t_11; + __Pyx_PySendResult __pyx_t_12; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("splitCubicAtTC", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + case 1: goto __pyx_L6_resume_from_yield_from; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(__pyx_sent_value != Py_None)) { + if (unlikely(__pyx_sent_value)) PyErr_SetString(PyExc_TypeError, "can't send non-None value to a just-started generator"); + __PYX_ERR(0, 644, __pyx_L1_error) + } + + /* "fontTools/misc/bezierTools.py":664 + * Curve segments (each curve segment being four complex numbers). + * """ + * a, b, c, d = calcCubicParametersC(pt1, pt2, pt3, pt4) # <<<<<<<<<<<<<< + * yield from _splitCubicAtTC(a, b, c, d, *ts) + * +*/ + __pyx_t_1 = __pyx_f_9fontTools_4misc_11bezierTools_calcCubicParametersC(__pyx_cur_scope->__pyx_v_pt1, __pyx_cur_scope->__pyx_v_pt2, __pyx_cur_scope->__pyx_v_pt3, __pyx_cur_scope->__pyx_v_pt4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 664, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 664, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_3); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 2); + __Pyx_INCREF(__pyx_t_4); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 3); + __Pyx_INCREF(__pyx_t_5); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 664, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 664, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(sequence, 2, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 664, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyList_GetItemRefFast(sequence, 3, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 664, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_5); + } + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_3,&__pyx_t_4,&__pyx_t_5}; + for (i=0; i < 4; i++) { + PyObject* item = __Pyx_PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 664, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_3,&__pyx_t_4,&__pyx_t_5}; + __pyx_t_6 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 664, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_7(__pyx_t_6); if (unlikely(!item)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 4) < (0)) __PYX_ERR(0, 664, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + goto __pyx_L5_unpacking_done; + __pyx_L4_unpacking_failed:; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 664, __pyx_L1_error) + __pyx_L5_unpacking_done:; + } + __pyx_t_8 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 664, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_9 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 664, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_10 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 664, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_11 = __Pyx_PyComplex_As___pyx_t_double_complex(__pyx_t_5); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 664, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_cur_scope->__pyx_v_a = __pyx_t_8; + __pyx_cur_scope->__pyx_v_b = __pyx_t_9; + __pyx_cur_scope->__pyx_v_c = __pyx_t_10; + __pyx_cur_scope->__pyx_v_d = __pyx_t_11; + + /* "fontTools/misc/bezierTools.py":665 + * """ + * a, b, c, d = calcCubicParametersC(pt1, pt2, pt3, pt4) + * yield from _splitCubicAtTC(a, b, c, d, *ts) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_splitCubicAtTC_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 665, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __pyx_PyComplex_FromComplex(__pyx_cur_scope->__pyx_v_a); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 665, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_cur_scope->__pyx_v_b); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 665, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = __pyx_PyComplex_FromComplex(__pyx_cur_scope->__pyx_v_c); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 665, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __pyx_PyComplex_FromComplex(__pyx_cur_scope->__pyx_v_d); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 665, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 665, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5) != (0)) __PYX_ERR(0, 665, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_4) != (0)) __PYX_ERR(0, 665, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_3) != (0)) __PYX_ERR(0, 665, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_2) != (0)) __PYX_ERR(0, 665, __pyx_L1_error); + __pyx_t_5 = 0; + __pyx_t_4 = 0; + __pyx_t_3 = 0; + __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_6, __pyx_cur_scope->__pyx_v_ts); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 665, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_2, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 665, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_12 = __Pyx_Generator_Yield_From(__pyx_generator, __pyx_t_6, &__pyx_r); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (likely(__pyx_t_12 == PYGEN_NEXT)) { + __Pyx_GOTREF(__pyx_r); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + /* return from generator, yielding value */ + __pyx_generator->resume_label = 1; + return __pyx_r; + __pyx_L6_resume_from_yield_from:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 665, __pyx_L1_error) + } else if (likely(__pyx_t_12 == PYGEN_RETURN)) { + __Pyx_GOTREF(__pyx_r); + __Pyx_DECREF(__pyx_r); __pyx_r = 0; + } else { + __Pyx_XGOTREF(__pyx_r); + __PYX_ERR(0, 665, __pyx_L1_error) + } + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* "fontTools/misc/bezierTools.py":644 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * pt1=cython.complex, + * pt2=cython.complex, +*/ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + if (__Pyx_PyErr_Occurred()) { + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_AddTraceback("splitCubicAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":668 + * + * + * @cython.returns(cython.complex) # <<<<<<<<<<<<<< + * @cython.locals( + * t=cython.double, +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_38splitCubicIntoTwoAtTC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_37splitCubicIntoTwoAtTC, "splitCubicIntoTwoAtTC(double complex pt1, double complex pt2, double complex pt3, double complex pt4, double t)\n\nSplit a cubic Bezier curve at t.\n\nArgs:\n pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers.\n t: Position at which to split the curve.\n\nReturns:\n A tuple of two curve segments (each curve segment being four complex numbers)."); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_38splitCubicIntoTwoAtTC = {"splitCubicIntoTwoAtTC", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_38splitCubicIntoTwoAtTC, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_37splitCubicIntoTwoAtTC}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_38splitCubicIntoTwoAtTC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_pt1; + __pyx_t_double_complex __pyx_v_pt2; + __pyx_t_double_complex __pyx_v_pt3; + __pyx_t_double_complex __pyx_v_pt4; + double __pyx_v_t; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("splitCubicIntoTwoAtTC (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,&__pyx_mstate_global->__pyx_n_u_pt4,&__pyx_mstate_global->__pyx_n_u_t,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 668, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 5: + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 668, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 668, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 668, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 668, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 668, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "splitCubicIntoTwoAtTC", 0) < (0)) __PYX_ERR(0, 668, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 5; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("splitCubicIntoTwoAtTC", 1, 5, 5, i); __PYX_ERR(0, 668, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 5)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 668, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 668, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 668, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 668, __pyx_L3_error) + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 668, __pyx_L3_error) + } + __pyx_v_pt1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 682, __pyx_L3_error) + __pyx_v_pt2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 682, __pyx_L3_error) + __pyx_v_pt3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 682, __pyx_L3_error) + __pyx_v_pt4 = __Pyx_PyComplex_As___pyx_t_double_complex(values[3]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 682, __pyx_L3_error) + __pyx_v_t = __Pyx_PyFloat_AsDouble(values[4]); if (unlikely((__pyx_v_t == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 682, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("splitCubicIntoTwoAtTC", 1, 5, 5, __pyx_nargs); __PYX_ERR(0, 668, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubicIntoTwoAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_37splitCubicIntoTwoAtTC(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4, __pyx_v_t); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_37splitCubicIntoTwoAtTC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4, double __pyx_v_t) { + double __pyx_v_t2; + double __pyx_v__1_t; + double __pyx_v__1_t_2; + double __pyx_v__2_t_1_t; + __pyx_t_double_complex __pyx_v_pointAtT; + __pyx_t_double_complex __pyx_v_off1; + __pyx_t_double_complex __pyx_v_off2; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("splitCubicIntoTwoAtTC", 0); + + /* "fontTools/misc/bezierTools.py":692 + * A tuple of two curve segments (each curve segment being four complex numbers). + * """ + * t2 = t * t # <<<<<<<<<<<<<< + * _1_t = 1 - t + * _1_t_2 = _1_t * _1_t +*/ + __pyx_v_t2 = (__pyx_v_t * __pyx_v_t); + + /* "fontTools/misc/bezierTools.py":693 + * """ + * t2 = t * t + * _1_t = 1 - t # <<<<<<<<<<<<<< + * _1_t_2 = _1_t * _1_t + * _2_t_1_t = 2 * t * _1_t +*/ + __pyx_v__1_t = (1.0 - __pyx_v_t); + + /* "fontTools/misc/bezierTools.py":694 + * t2 = t * t + * _1_t = 1 - t + * _1_t_2 = _1_t * _1_t # <<<<<<<<<<<<<< + * _2_t_1_t = 2 * t * _1_t + * pointAtT = ( +*/ + __pyx_v__1_t_2 = (__pyx_v__1_t * __pyx_v__1_t); + + /* "fontTools/misc/bezierTools.py":695 + * _1_t = 1 - t + * _1_t_2 = _1_t * _1_t + * _2_t_1_t = 2 * t * _1_t # <<<<<<<<<<<<<< + * pointAtT = ( + * _1_t_2 * _1_t * pt1 + 3 * (_1_t_2 * t * pt2 + _1_t * t2 * pt3) + t2 * t * pt4 +*/ + __pyx_v__2_t_1_t = ((2.0 * __pyx_v_t) * __pyx_v__1_t); + + /* "fontTools/misc/bezierTools.py":697 + * _2_t_1_t = 2 * t * _1_t + * pointAtT = ( + * _1_t_2 * _1_t * pt1 + 3 * (_1_t_2 * t * pt2 + _1_t * t2 * pt3) + t2 * t * pt4 # <<<<<<<<<<<<<< + * ) + * off1 = _1_t_2 * pt1 + _2_t_1_t * pt2 + t2 * pt3 +*/ + __pyx_v_pointAtT = __Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts((__pyx_v__1_t_2 * __pyx_v__1_t), 0), __pyx_v_pt1), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(3, 0), __Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts((__pyx_v__1_t_2 * __pyx_v_t), 0), __pyx_v_pt2), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts((__pyx_v__1_t * __pyx_v_t2), 0), __pyx_v_pt3)))), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts((__pyx_v_t2 * __pyx_v_t), 0), __pyx_v_pt4)); + + /* "fontTools/misc/bezierTools.py":699 + * _1_t_2 * _1_t * pt1 + 3 * (_1_t_2 * t * pt2 + _1_t * t2 * pt3) + t2 * t * pt4 + * ) + * off1 = _1_t_2 * pt1 + _2_t_1_t * pt2 + t2 * pt3 # <<<<<<<<<<<<<< + * off2 = _1_t_2 * pt2 + _2_t_1_t * pt3 + t2 * pt4 + * +*/ + __pyx_v_off1 = __Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(__pyx_v__1_t_2, 0), __pyx_v_pt1), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(__pyx_v__2_t_1_t, 0), __pyx_v_pt2)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(__pyx_v_t2, 0), __pyx_v_pt3)); + + /* "fontTools/misc/bezierTools.py":700 + * ) + * off1 = _1_t_2 * pt1 + _2_t_1_t * pt2 + t2 * pt3 + * off2 = _1_t_2 * pt2 + _2_t_1_t * pt3 + t2 * pt4 # <<<<<<<<<<<<<< + * + * pt2 = pt1 + (pt2 - pt1) * t +*/ + __pyx_v_off2 = __Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(__pyx_v__1_t_2, 0), __pyx_v_pt2), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(__pyx_v__2_t_1_t, 0), __pyx_v_pt3)), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(__pyx_v_t2, 0), __pyx_v_pt4)); + + /* "fontTools/misc/bezierTools.py":702 + * off2 = _1_t_2 * pt2 + _2_t_1_t * pt3 + t2 * pt4 + * + * pt2 = pt1 + (pt2 - pt1) * t # <<<<<<<<<<<<<< + * pt3 = pt4 + (pt3 - pt4) * _1_t + * +*/ + __pyx_v_pt2 = __Pyx_c_sum_double(__pyx_v_pt1, __Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_pt2, __pyx_v_pt1), __pyx_t_double_complex_from_parts(__pyx_v_t, 0))); + + /* "fontTools/misc/bezierTools.py":703 + * + * pt2 = pt1 + (pt2 - pt1) * t + * pt3 = pt4 + (pt3 - pt4) * _1_t # <<<<<<<<<<<<<< + * + * return ((pt1, pt2, off1, pointAtT), (pointAtT, off2, pt3, pt4)) +*/ + __pyx_v_pt3 = __Pyx_c_sum_double(__pyx_v_pt4, __Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_pt3, __pyx_v_pt4), __pyx_t_double_complex_from_parts(__pyx_v__1_t, 0))); + + /* "fontTools/misc/bezierTools.py":705 + * pt3 = pt4 + (pt3 - pt4) * _1_t + * + * return ((pt1, pt2, off1, pointAtT), (pointAtT, off2, pt3, pt4)) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_pt1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 705, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __pyx_PyComplex_FromComplex(__pyx_v_pt2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 705, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __pyx_PyComplex_FromComplex(__pyx_v_off1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 705, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_v_pointAtT); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 705, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 705, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 705, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2) != (0)) __PYX_ERR(0, 705, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3) != (0)) __PYX_ERR(0, 705, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4) != (0)) __PYX_ERR(0, 705, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_t_4 = 0; + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_v_pointAtT); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 705, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = __pyx_PyComplex_FromComplex(__pyx_v_off2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 705, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __pyx_PyComplex_FromComplex(__pyx_v_pt3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 705, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_pt4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 705, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 705, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4) != (0)) __PYX_ERR(0, 705, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_3) != (0)) __PYX_ERR(0, 705, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_2) != (0)) __PYX_ERR(0, 705, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_1) != (0)) __PYX_ERR(0, 705, __pyx_L1_error); + __pyx_t_4 = 0; + __pyx_t_3 = 0; + __pyx_t_2 = 0; + __pyx_t_1 = 0; + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 705, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5) != (0)) __PYX_ERR(0, 705, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_6) != (0)) __PYX_ERR(0, 705, __pyx_L1_error); + __pyx_t_5 = 0; + __pyx_t_6 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":668 + * + * + * @cython.returns(cython.complex) # <<<<<<<<<<<<<< + * @cython.locals( + * t=cython.double, +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.misc.bezierTools.splitCubicIntoTwoAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":708 + * + * + * def _splitQuadraticAtT(a, b, c, *ts): # <<<<<<<<<<<<<< + * ts = list(ts) + * segments = [] +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_40_splitQuadraticAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_39_splitQuadraticAtT, "_splitQuadraticAtT(a, b, c, *ts)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_40_splitQuadraticAtT = {"_splitQuadraticAtT", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_40_splitQuadraticAtT, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_39_splitQuadraticAtT}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_40_splitQuadraticAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_a = 0; + PyObject *__pyx_v_b = 0; + PyObject *__pyx_v_c = 0; + PyObject *__pyx_v_ts = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_splitQuadraticAtT (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + __pyx_v_ts = __Pyx_ArgsSlice_FASTCALL(__pyx_args, 3, __pyx_nargs); + if (unlikely(!__pyx_v_ts)) { + __Pyx_RefNannyFinishContext(); + return NULL; + } + __Pyx_GOTREF(__pyx_v_ts); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_a,&__pyx_mstate_global->__pyx_n_u_b,&__pyx_mstate_global->__pyx_n_u_c,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 708, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + default: + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 708, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 708, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 708, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + const Py_ssize_t used_pos_args = (kwd_pos_args < 3) ? kwd_pos_args : 3; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, used_pos_args, __pyx_kwds_len, "_splitQuadraticAtT", 0) < (0)) __PYX_ERR(0, 708, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 3; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_splitQuadraticAtT", 0, 3, 3, i); __PYX_ERR(0, 708, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs < 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 708, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 708, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 708, __pyx_L3_error) + } + __pyx_v_a = values[0]; + __pyx_v_b = values[1]; + __pyx_v_c = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_splitQuadraticAtT", 0, 3, 3, __pyx_nargs); __PYX_ERR(0, 708, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_DECREF(__pyx_v_ts); __pyx_v_ts = 0; + __Pyx_AddTraceback("fontTools.misc.bezierTools._splitQuadraticAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_39_splitQuadraticAtT(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_c, __pyx_v_ts); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_DECREF(__pyx_v_ts); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_39_splitQuadraticAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_ts) { + PyObject *__pyx_v_segments = NULL; + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_cx = NULL; + PyObject *__pyx_v_cy = NULL; + PyObject *__pyx_v_i = NULL; + PyObject *__pyx_v_t1 = NULL; + PyObject *__pyx_v_t2 = NULL; + PyObject *__pyx_v_delta = NULL; + PyObject *__pyx_v_delta_2 = NULL; + PyObject *__pyx_v_a1x = NULL; + PyObject *__pyx_v_a1y = NULL; + PyObject *__pyx_v_b1x = NULL; + PyObject *__pyx_v_b1y = NULL; + PyObject *__pyx_v_t1_2 = NULL; + PyObject *__pyx_v_c1x = NULL; + PyObject *__pyx_v_c1y = NULL; + PyObject *__pyx_v_pt1 = NULL; + PyObject *__pyx_v_pt2 = NULL; + PyObject *__pyx_v_pt3 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *(*__pyx_t_5)(PyObject *); + Py_ssize_t __pyx_t_6; + size_t __pyx_t_7; + PyObject *(*__pyx_t_8)(PyObject *); + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_splitQuadraticAtT", 0); + __Pyx_INCREF(__pyx_v_ts); + + /* "fontTools/misc/bezierTools.py":709 + * + * def _splitQuadraticAtT(a, b, c, *ts): + * ts = list(ts) # <<<<<<<<<<<<<< + * segments = [] + * ts.insert(0, 0.0) +*/ + __pyx_t_1 = PySequence_List(__pyx_v_ts); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 709, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF_SET(__pyx_v_ts, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":710 + * def _splitQuadraticAtT(a, b, c, *ts): + * ts = list(ts) + * segments = [] # <<<<<<<<<<<<<< + * ts.insert(0, 0.0) + * ts.append(1.0) +*/ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 710, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_segments = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":711 + * ts = list(ts) + * segments = [] + * ts.insert(0, 0.0) # <<<<<<<<<<<<<< + * ts.append(1.0) + * ax, ay = a +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_ts, __pyx_mstate_global->__pyx_n_u_insert); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 711, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_mstate_global->__pyx_tuple[0], NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 711, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":712 + * segments = [] + * ts.insert(0, 0.0) + * ts.append(1.0) # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b +*/ + __pyx_t_3 = __Pyx_PyObject_Append(__pyx_v_ts, __pyx_mstate_global->__pyx_float_1_0); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 712, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":713 + * ts.insert(0, 0.0) + * ts.append(1.0) + * ax, ay = a # <<<<<<<<<<<<<< + * bx, by = b + * cx, cy = c +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_a))) || (PyList_CheckExact(__pyx_v_a))) { + PyObject* sequence = __pyx_v_a; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 713, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 713, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 713, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 713, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 713, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_v_a); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 713, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); + index = 0; __pyx_t_2 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < (0)) __PYX_ERR(0, 713, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 713, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_ax = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_ay = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":714 + * ts.append(1.0) + * ax, ay = a + * bx, by = b # <<<<<<<<<<<<<< + * cx, cy = c + * for i in range(len(ts) - 1): +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_b))) || (PyList_CheckExact(__pyx_v_b))) { + PyObject* sequence = __pyx_v_b; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 714, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 714, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 714, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 714, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 714, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_v_b); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 714, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); + index = 0; __pyx_t_1 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < (0)) __PYX_ERR(0, 714, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 714, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_bx = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_by = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":715 + * ax, ay = a + * bx, by = b + * cx, cy = c # <<<<<<<<<<<<<< + * for i in range(len(ts) - 1): + * t1 = ts[i] +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_c))) || (PyList_CheckExact(__pyx_v_c))) { + PyObject* sequence = __pyx_v_c; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 715, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 715, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 715, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 715, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 715, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_v_c); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 715, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); + index = 0; __pyx_t_2 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < (0)) __PYX_ERR(0, 715, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 715, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_cx = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_cy = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":716 + * bx, by = b + * cx, cy = c + * for i in range(len(ts) - 1): # <<<<<<<<<<<<<< + * t1 = ts[i] + * t2 = ts[i + 1] +*/ + __pyx_t_2 = NULL; + __pyx_t_6 = PyObject_Length(__pyx_v_ts); if (unlikely(__pyx_t_6 == ((Py_ssize_t)-1))) __PYX_ERR(0, 716, __pyx_L1_error) + __pyx_t_4 = PyLong_FromSsize_t((__pyx_t_6 - 1)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 716, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = 1; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_t_4}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)(&PyRange_Type), __pyx_callargs+__pyx_t_7, (2-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 716, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_4 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 716, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_8 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 716, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + for (;;) { + { + __pyx_t_1 = __pyx_t_8(__pyx_t_4); + if (unlikely(!__pyx_t_1)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 716, __pyx_L1_error) + PyErr_Clear(); + } + break; + } + } + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":717 + * cx, cy = c + * for i in range(len(ts) - 1): + * t1 = ts[i] # <<<<<<<<<<<<<< + * t2 = ts[i + 1] + * delta = t2 - t1 +*/ + __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_ts, __pyx_v_i); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 717, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XDECREF_SET(__pyx_v_t1, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":718 + * for i in range(len(ts) - 1): + * t1 = ts[i] + * t2 = ts[i + 1] # <<<<<<<<<<<<<< + * delta = t2 - t1 + * # calc new a, b and c +*/ + __pyx_t_1 = __Pyx_PyLong_AddObjC(__pyx_v_i, __pyx_mstate_global->__pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 718, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_v_ts, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 718, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_t2, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":719 + * t1 = ts[i] + * t2 = ts[i + 1] + * delta = t2 - t1 # <<<<<<<<<<<<<< + * # calc new a, b and c + * delta_2 = delta * delta +*/ + __pyx_t_2 = PyNumber_Subtract(__pyx_v_t2, __pyx_v_t1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 719, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_v_delta, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":721 + * delta = t2 - t1 + * # calc new a, b and c + * delta_2 = delta * delta # <<<<<<<<<<<<<< + * a1x = ax * delta_2 + * a1y = ay * delta_2 +*/ + __pyx_t_2 = PyNumber_Multiply(__pyx_v_delta, __pyx_v_delta); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 721, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_v_delta_2, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":722 + * # calc new a, b and c + * delta_2 = delta * delta + * a1x = ax * delta_2 # <<<<<<<<<<<<<< + * a1y = ay * delta_2 + * b1x = (2 * ax * t1 + bx) * delta +*/ + __pyx_t_2 = PyNumber_Multiply(__pyx_v_ax, __pyx_v_delta_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 722, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_v_a1x, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":723 + * delta_2 = delta * delta + * a1x = ax * delta_2 + * a1y = ay * delta_2 # <<<<<<<<<<<<<< + * b1x = (2 * ax * t1 + bx) * delta + * b1y = (2 * ay * t1 + by) * delta +*/ + __pyx_t_2 = PyNumber_Multiply(__pyx_v_ay, __pyx_v_delta_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 723, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_v_a1y, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":724 + * a1x = ax * delta_2 + * a1y = ay * delta_2 + * b1x = (2 * ax * t1 + bx) * delta # <<<<<<<<<<<<<< + * b1y = (2 * ay * t1 + by) * delta + * t1_2 = t1 * t1 +*/ + __pyx_t_2 = __Pyx_PyLong_MultiplyCObj(__pyx_mstate_global->__pyx_int_2, __pyx_v_ax, 2, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 724, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_v_t1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 724, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_bx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 724, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_v_delta); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 724, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF_SET(__pyx_v_b1x, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":725 + * a1y = ay * delta_2 + * b1x = (2 * ax * t1 + bx) * delta + * b1y = (2 * ay * t1 + by) * delta # <<<<<<<<<<<<<< + * t1_2 = t1 * t1 + * c1x = ax * t1_2 + bx * t1 + cx +*/ + __pyx_t_1 = __Pyx_PyLong_MultiplyCObj(__pyx_mstate_global->__pyx_int_2, __pyx_v_ay, 2, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 725, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_v_t1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 725, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_by); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 725, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_v_delta); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 725, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_b1y, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":726 + * b1x = (2 * ax * t1 + bx) * delta + * b1y = (2 * ay * t1 + by) * delta + * t1_2 = t1 * t1 # <<<<<<<<<<<<<< + * c1x = ax * t1_2 + bx * t1 + cx + * c1y = ay * t1_2 + by * t1 + cy +*/ + __pyx_t_2 = PyNumber_Multiply(__pyx_v_t1, __pyx_v_t1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 726, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_v_t1_2, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":727 + * b1y = (2 * ay * t1 + by) * delta + * t1_2 = t1 * t1 + * c1x = ax * t1_2 + bx * t1 + cx # <<<<<<<<<<<<<< + * c1y = ay * t1_2 + by * t1 + cy + * +*/ + __pyx_t_2 = PyNumber_Multiply(__pyx_v_ax, __pyx_v_t1_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 727, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_v_bx, __pyx_v_t1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 727, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_9 = PyNumber_Add(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 727, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_9, __pyx_v_cx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 727, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_XDECREF_SET(__pyx_v_c1x, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":728 + * t1_2 = t1 * t1 + * c1x = ax * t1_2 + bx * t1 + cx + * c1y = ay * t1_2 + by * t1 + cy # <<<<<<<<<<<<<< + * + * pt1, pt2, pt3 = calcQuadraticPoints((a1x, a1y), (b1x, b1y), (c1x, c1y)) +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_ay, __pyx_v_t1_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 728, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_9 = PyNumber_Multiply(__pyx_v_by, __pyx_v_t1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 728, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 728, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_9 = PyNumber_Add(__pyx_t_2, __pyx_v_cy); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 728, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF_SET(__pyx_v_c1y, __pyx_t_9); + __pyx_t_9 = 0; + + /* "fontTools/misc/bezierTools.py":730 + * c1y = ay * t1_2 + by * t1 + cy + * + * pt1, pt2, pt3 = calcQuadraticPoints((a1x, a1y), (b1x, b1y), (c1x, c1y)) # <<<<<<<<<<<<<< + * segments.append((pt1, pt2, pt3)) + * return segments +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_calcQuadraticPoints); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 730, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 730, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_INCREF(__pyx_v_a1x); + __Pyx_GIVEREF(__pyx_v_a1x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_v_a1x) != (0)) __PYX_ERR(0, 730, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_a1y); + __Pyx_GIVEREF(__pyx_v_a1y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_v_a1y) != (0)) __PYX_ERR(0, 730, __pyx_L1_error); + __pyx_t_11 = PyTuple_New(2); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 730, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_INCREF(__pyx_v_b1x); + __Pyx_GIVEREF(__pyx_v_b1x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_v_b1x) != (0)) __PYX_ERR(0, 730, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_b1y); + __Pyx_GIVEREF(__pyx_v_b1y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_v_b1y) != (0)) __PYX_ERR(0, 730, __pyx_L1_error); + __pyx_t_12 = PyTuple_New(2); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 730, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_INCREF(__pyx_v_c1x); + __Pyx_GIVEREF(__pyx_v_c1x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_v_c1x) != (0)) __PYX_ERR(0, 730, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_c1y); + __Pyx_GIVEREF(__pyx_v_c1y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_12, 1, __pyx_v_c1y) != (0)) __PYX_ERR(0, 730, __pyx_L1_error); + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_2, __pyx_t_10, __pyx_t_11, __pyx_t_12}; + __pyx_t_9 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_7, (4-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 730, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + } + if ((likely(PyTuple_CheckExact(__pyx_t_9))) || (PyList_CheckExact(__pyx_t_9))) { + PyObject* sequence = __pyx_t_9; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 3)) { + if (size > 3) __Pyx_RaiseTooManyValuesError(3); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 730, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_12 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_12); + __pyx_t_11 = PyTuple_GET_ITEM(sequence, 2); + __Pyx_INCREF(__pyx_t_11); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 730, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_12 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 730, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_12); + __pyx_t_11 = __Pyx_PyList_GetItemRefFast(sequence, 2, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 730, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_11); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 730, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_12 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 730, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __pyx_t_11 = __Pyx_PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 730, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + #endif + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_10 = PyObject_GetIter(__pyx_t_9); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 730, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_5 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_10); + index = 0; __pyx_t_1 = __pyx_t_5(__pyx_t_10); if (unlikely(!__pyx_t_1)) goto __pyx_L11_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_12 = __pyx_t_5(__pyx_t_10); if (unlikely(!__pyx_t_12)) goto __pyx_L11_unpacking_failed; + __Pyx_GOTREF(__pyx_t_12); + index = 2; __pyx_t_11 = __pyx_t_5(__pyx_t_10); if (unlikely(!__pyx_t_11)) goto __pyx_L11_unpacking_failed; + __Pyx_GOTREF(__pyx_t_11); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_10), 3) < (0)) __PYX_ERR(0, 730, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + goto __pyx_L12_unpacking_done; + __pyx_L11_unpacking_failed:; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 730, __pyx_L1_error) + __pyx_L12_unpacking_done:; + } + __Pyx_XDECREF_SET(__pyx_v_pt1, __pyx_t_1); + __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_pt2, __pyx_t_12); + __pyx_t_12 = 0; + __Pyx_XDECREF_SET(__pyx_v_pt3, __pyx_t_11); + __pyx_t_11 = 0; + + /* "fontTools/misc/bezierTools.py":731 + * + * pt1, pt2, pt3 = calcQuadraticPoints((a1x, a1y), (b1x, b1y), (c1x, c1y)) + * segments.append((pt1, pt2, pt3)) # <<<<<<<<<<<<<< + * return segments + * +*/ + __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 731, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_pt1) != (0)) __PYX_ERR(0, 731, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt2); + __Pyx_GIVEREF(__pyx_v_pt2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_v_pt2) != (0)) __PYX_ERR(0, 731, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt3); + __Pyx_GIVEREF(__pyx_v_pt3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_v_pt3) != (0)) __PYX_ERR(0, 731, __pyx_L1_error); + __pyx_t_3 = __Pyx_PyList_Append(__pyx_v_segments, __pyx_t_9); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 731, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "fontTools/misc/bezierTools.py":716 + * bx, by = b + * cx, cy = c + * for i in range(len(ts) - 1): # <<<<<<<<<<<<<< + * t1 = ts[i] + * t2 = ts[i + 1] +*/ + } + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":732 + * pt1, pt2, pt3 = calcQuadraticPoints((a1x, a1y), (b1x, b1y), (c1x, c1y)) + * segments.append((pt1, pt2, pt3)) + * return segments # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_segments); + __pyx_r = __pyx_v_segments; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":708 + * + * + * def _splitQuadraticAtT(a, b, c, *ts): # <<<<<<<<<<<<<< + * ts = list(ts) + * segments = [] +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_AddTraceback("fontTools.misc.bezierTools._splitQuadraticAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_ts); + __Pyx_XDECREF(__pyx_v_segments); + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_cx); + __Pyx_XDECREF(__pyx_v_cy); + __Pyx_XDECREF(__pyx_v_i); + __Pyx_XDECREF(__pyx_v_t1); + __Pyx_XDECREF(__pyx_v_t2); + __Pyx_XDECREF(__pyx_v_delta); + __Pyx_XDECREF(__pyx_v_delta_2); + __Pyx_XDECREF(__pyx_v_a1x); + __Pyx_XDECREF(__pyx_v_a1y); + __Pyx_XDECREF(__pyx_v_b1x); + __Pyx_XDECREF(__pyx_v_b1y); + __Pyx_XDECREF(__pyx_v_t1_2); + __Pyx_XDECREF(__pyx_v_c1x); + __Pyx_XDECREF(__pyx_v_c1y); + __Pyx_XDECREF(__pyx_v_pt1); + __Pyx_XDECREF(__pyx_v_pt2); + __Pyx_XDECREF(__pyx_v_pt3); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":735 + * + * + * def _splitCubicAtT(a, b, c, d, *ts): # <<<<<<<<<<<<<< + * ts = list(ts) + * ts.insert(0, 0.0) +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_42_splitCubicAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_41_splitCubicAtT, "_splitCubicAtT(a, b, c, d, *ts)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_42_splitCubicAtT = {"_splitCubicAtT", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_42_splitCubicAtT, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_41_splitCubicAtT}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_42_splitCubicAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_a = 0; + PyObject *__pyx_v_b = 0; + PyObject *__pyx_v_c = 0; + PyObject *__pyx_v_d = 0; + PyObject *__pyx_v_ts = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_splitCubicAtT (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + __pyx_v_ts = __Pyx_ArgsSlice_FASTCALL(__pyx_args, 4, __pyx_nargs); + if (unlikely(!__pyx_v_ts)) { + __Pyx_RefNannyFinishContext(); + return NULL; + } + __Pyx_GOTREF(__pyx_v_ts); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_a,&__pyx_mstate_global->__pyx_n_u_b,&__pyx_mstate_global->__pyx_n_u_c,&__pyx_mstate_global->__pyx_n_u_d,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 735, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + default: + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 735, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 735, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 735, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 735, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + const Py_ssize_t used_pos_args = (kwd_pos_args < 4) ? kwd_pos_args : 4; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, used_pos_args, __pyx_kwds_len, "_splitCubicAtT", 0) < (0)) __PYX_ERR(0, 735, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_splitCubicAtT", 0, 4, 4, i); __PYX_ERR(0, 735, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs < 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 735, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 735, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 735, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 735, __pyx_L3_error) + } + __pyx_v_a = values[0]; + __pyx_v_b = values[1]; + __pyx_v_c = values[2]; + __pyx_v_d = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_splitCubicAtT", 0, 4, 4, __pyx_nargs); __PYX_ERR(0, 735, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_DECREF(__pyx_v_ts); __pyx_v_ts = 0; + __Pyx_AddTraceback("fontTools.misc.bezierTools._splitCubicAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_41_splitCubicAtT(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_c, __pyx_v_d, __pyx_v_ts); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_DECREF(__pyx_v_ts); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_41_splitCubicAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_ts) { + PyObject *__pyx_v_segments = NULL; + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_cx = NULL; + PyObject *__pyx_v_cy = NULL; + PyObject *__pyx_v_dx = NULL; + PyObject *__pyx_v_dy = NULL; + PyObject *__pyx_v_i = NULL; + PyObject *__pyx_v_t1 = NULL; + PyObject *__pyx_v_t2 = NULL; + PyObject *__pyx_v_delta = NULL; + PyObject *__pyx_v_delta_2 = NULL; + PyObject *__pyx_v_delta_3 = NULL; + PyObject *__pyx_v_t1_2 = NULL; + PyObject *__pyx_v_t1_3 = NULL; + PyObject *__pyx_v_a1x = NULL; + PyObject *__pyx_v_a1y = NULL; + PyObject *__pyx_v_b1x = NULL; + PyObject *__pyx_v_b1y = NULL; + PyObject *__pyx_v_c1x = NULL; + PyObject *__pyx_v_c1y = NULL; + PyObject *__pyx_v_d1x = NULL; + PyObject *__pyx_v_d1y = NULL; + PyObject *__pyx_v_pt1 = NULL; + PyObject *__pyx_v_pt2 = NULL; + PyObject *__pyx_v_pt3 = NULL; + PyObject *__pyx_v_pt4 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *(*__pyx_t_5)(PyObject *); + Py_ssize_t __pyx_t_6; + size_t __pyx_t_7; + PyObject *(*__pyx_t_8)(PyObject *); + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + PyObject *__pyx_t_13 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_splitCubicAtT", 0); + __Pyx_INCREF(__pyx_v_ts); + + /* "fontTools/misc/bezierTools.py":736 + * + * def _splitCubicAtT(a, b, c, d, *ts): + * ts = list(ts) # <<<<<<<<<<<<<< + * ts.insert(0, 0.0) + * ts.append(1.0) +*/ + __pyx_t_1 = PySequence_List(__pyx_v_ts); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 736, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF_SET(__pyx_v_ts, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":737 + * def _splitCubicAtT(a, b, c, d, *ts): + * ts = list(ts) + * ts.insert(0, 0.0) # <<<<<<<<<<<<<< + * ts.append(1.0) + * segments = [] +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_ts, __pyx_mstate_global->__pyx_n_u_insert); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 737, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_mstate_global->__pyx_tuple[0], NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 737, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":738 + * ts = list(ts) + * ts.insert(0, 0.0) + * ts.append(1.0) # <<<<<<<<<<<<<< + * segments = [] + * ax, ay = a +*/ + __pyx_t_3 = __Pyx_PyObject_Append(__pyx_v_ts, __pyx_mstate_global->__pyx_float_1_0); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 738, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":739 + * ts.insert(0, 0.0) + * ts.append(1.0) + * segments = [] # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b +*/ + __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 739, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_v_segments = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":740 + * ts.append(1.0) + * segments = [] + * ax, ay = a # <<<<<<<<<<<<<< + * bx, by = b + * cx, cy = c +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_a))) || (PyList_CheckExact(__pyx_v_a))) { + PyObject* sequence = __pyx_v_a; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 740, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 740, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 740, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 740, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 740, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_v_a); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 740, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); + index = 0; __pyx_t_2 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < (0)) __PYX_ERR(0, 740, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 740, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_ax = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_ay = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":741 + * segments = [] + * ax, ay = a + * bx, by = b # <<<<<<<<<<<<<< + * cx, cy = c + * dx, dy = d +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_b))) || (PyList_CheckExact(__pyx_v_b))) { + PyObject* sequence = __pyx_v_b; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 741, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 741, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 741, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 741, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 741, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_v_b); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 741, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); + index = 0; __pyx_t_1 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < (0)) __PYX_ERR(0, 741, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 741, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_bx = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_by = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":742 + * ax, ay = a + * bx, by = b + * cx, cy = c # <<<<<<<<<<<<<< + * dx, dy = d + * for i in range(len(ts) - 1): +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_c))) || (PyList_CheckExact(__pyx_v_c))) { + PyObject* sequence = __pyx_v_c; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 742, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 742, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 742, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 742, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 742, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_v_c); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 742, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); + index = 0; __pyx_t_2 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < (0)) __PYX_ERR(0, 742, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 742, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_cx = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_cy = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":743 + * bx, by = b + * cx, cy = c + * dx, dy = d # <<<<<<<<<<<<<< + * for i in range(len(ts) - 1): + * t1 = ts[i] +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_d))) || (PyList_CheckExact(__pyx_v_d))) { + PyObject* sequence = __pyx_v_d; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 743, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 743, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 743, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 743, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 743, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_v_d); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 743, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); + index = 0; __pyx_t_1 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_1)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_5(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_4), 2) < (0)) __PYX_ERR(0, 743, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 743, __pyx_L1_error) + __pyx_L10_unpacking_done:; + } + __pyx_v_dx = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_dy = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":744 + * cx, cy = c + * dx, dy = d + * for i in range(len(ts) - 1): # <<<<<<<<<<<<<< + * t1 = ts[i] + * t2 = ts[i + 1] +*/ + __pyx_t_1 = NULL; + __pyx_t_6 = PyObject_Length(__pyx_v_ts); if (unlikely(__pyx_t_6 == ((Py_ssize_t)-1))) __PYX_ERR(0, 744, __pyx_L1_error) + __pyx_t_4 = PyLong_FromSsize_t((__pyx_t_6 - 1)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 744, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = 1; + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_t_4}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)(&PyRange_Type), __pyx_callargs+__pyx_t_7, (2-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 744, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __pyx_t_4 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 744, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_8 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 744, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + for (;;) { + { + __pyx_t_2 = __pyx_t_8(__pyx_t_4); + if (unlikely(!__pyx_t_2)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 744, __pyx_L1_error) + PyErr_Clear(); + } + break; + } + } + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":745 + * dx, dy = d + * for i in range(len(ts) - 1): + * t1 = ts[i] # <<<<<<<<<<<<<< + * t2 = ts[i + 1] + * delta = t2 - t1 +*/ + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_v_ts, __pyx_v_i); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 745, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_v_t1, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":746 + * for i in range(len(ts) - 1): + * t1 = ts[i] + * t2 = ts[i + 1] # <<<<<<<<<<<<<< + * delta = t2 - t1 + * +*/ + __pyx_t_2 = __Pyx_PyLong_AddObjC(__pyx_v_i, __pyx_mstate_global->__pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 746, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_ts, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 746, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF_SET(__pyx_v_t2, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":747 + * t1 = ts[i] + * t2 = ts[i + 1] + * delta = t2 - t1 # <<<<<<<<<<<<<< + * + * delta_2 = delta * delta +*/ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_t2, __pyx_v_t1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 747, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XDECREF_SET(__pyx_v_delta, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":749 + * delta = t2 - t1 + * + * delta_2 = delta * delta # <<<<<<<<<<<<<< + * delta_3 = delta * delta_2 + * t1_2 = t1 * t1 +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_delta, __pyx_v_delta); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 749, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XDECREF_SET(__pyx_v_delta_2, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":750 + * + * delta_2 = delta * delta + * delta_3 = delta * delta_2 # <<<<<<<<<<<<<< + * t1_2 = t1 * t1 + * t1_3 = t1 * t1_2 +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_delta, __pyx_v_delta_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 750, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XDECREF_SET(__pyx_v_delta_3, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":751 + * delta_2 = delta * delta + * delta_3 = delta * delta_2 + * t1_2 = t1 * t1 # <<<<<<<<<<<<<< + * t1_3 = t1 * t1_2 + * +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_t1, __pyx_v_t1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 751, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XDECREF_SET(__pyx_v_t1_2, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":752 + * delta_3 = delta * delta_2 + * t1_2 = t1 * t1 + * t1_3 = t1 * t1_2 # <<<<<<<<<<<<<< + * + * # calc new a, b, c and d +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_t1, __pyx_v_t1_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 752, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XDECREF_SET(__pyx_v_t1_3, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":755 + * + * # calc new a, b, c and d + * a1x = ax * delta_3 # <<<<<<<<<<<<<< + * a1y = ay * delta_3 + * b1x = (3 * ax * t1 + bx) * delta_2 +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_ax, __pyx_v_delta_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 755, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XDECREF_SET(__pyx_v_a1x, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":756 + * # calc new a, b, c and d + * a1x = ax * delta_3 + * a1y = ay * delta_3 # <<<<<<<<<<<<<< + * b1x = (3 * ax * t1 + bx) * delta_2 + * b1y = (3 * ay * t1 + by) * delta_2 +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_ay, __pyx_v_delta_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 756, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XDECREF_SET(__pyx_v_a1y, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":757 + * a1x = ax * delta_3 + * a1y = ay * delta_3 + * b1x = (3 * ax * t1 + bx) * delta_2 # <<<<<<<<<<<<<< + * b1y = (3 * ay * t1 + by) * delta_2 + * c1x = (2 * bx * t1 + cx + 3 * ax * t1_2) * delta +*/ + __pyx_t_1 = __Pyx_PyLong_MultiplyCObj(__pyx_mstate_global->__pyx_int_3, __pyx_v_ax, 3, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 757, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_v_t1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 757, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_bx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 757, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_v_delta_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 757, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_b1x, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":758 + * a1y = ay * delta_3 + * b1x = (3 * ax * t1 + bx) * delta_2 + * b1y = (3 * ay * t1 + by) * delta_2 # <<<<<<<<<<<<<< + * c1x = (2 * bx * t1 + cx + 3 * ax * t1_2) * delta + * c1y = (2 * by * t1 + cy + 3 * ay * t1_2) * delta +*/ + __pyx_t_2 = __Pyx_PyLong_MultiplyCObj(__pyx_mstate_global->__pyx_int_3, __pyx_v_ay, 3, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 758, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_v_t1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 758, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_by); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 758, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_v_delta_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 758, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF_SET(__pyx_v_b1y, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":759 + * b1x = (3 * ax * t1 + bx) * delta_2 + * b1y = (3 * ay * t1 + by) * delta_2 + * c1x = (2 * bx * t1 + cx + 3 * ax * t1_2) * delta # <<<<<<<<<<<<<< + * c1y = (2 * by * t1 + cy + 3 * ay * t1_2) * delta + * d1x = ax * t1_3 + bx * t1_2 + cx * t1 + dx +*/ + __pyx_t_1 = __Pyx_PyLong_MultiplyCObj(__pyx_mstate_global->__pyx_int_2, __pyx_v_bx, 2, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 759, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_v_t1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 759, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_cx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 759, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyLong_MultiplyCObj(__pyx_mstate_global->__pyx_int_3, __pyx_v_ax, 3, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 759, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_9 = PyNumber_Multiply(__pyx_t_2, __pyx_v_t1_2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 759, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 759, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_9 = PyNumber_Multiply(__pyx_t_2, __pyx_v_delta); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 759, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF_SET(__pyx_v_c1x, __pyx_t_9); + __pyx_t_9 = 0; + + /* "fontTools/misc/bezierTools.py":760 + * b1y = (3 * ay * t1 + by) * delta_2 + * c1x = (2 * bx * t1 + cx + 3 * ax * t1_2) * delta + * c1y = (2 * by * t1 + cy + 3 * ay * t1_2) * delta # <<<<<<<<<<<<<< + * d1x = ax * t1_3 + bx * t1_2 + cx * t1 + dx + * d1y = ay * t1_3 + by * t1_2 + cy * t1 + dy +*/ + __pyx_t_9 = __Pyx_PyLong_MultiplyCObj(__pyx_mstate_global->__pyx_int_2, __pyx_v_by, 2, 0, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 760, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_9, __pyx_v_t1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 760, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_9 = PyNumber_Add(__pyx_t_2, __pyx_v_cy); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 760, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyLong_MultiplyCObj(__pyx_mstate_global->__pyx_int_3, __pyx_v_ay, 3, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 760, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_v_t1_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 760, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_9, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 760, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_v_delta); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 760, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF_SET(__pyx_v_c1y, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":761 + * c1x = (2 * bx * t1 + cx + 3 * ax * t1_2) * delta + * c1y = (2 * by * t1 + cy + 3 * ay * t1_2) * delta + * d1x = ax * t1_3 + bx * t1_2 + cx * t1 + dx # <<<<<<<<<<<<<< + * d1y = ay * t1_3 + by * t1_2 + cy * t1 + dy + * pt1, pt2, pt3, pt4 = calcCubicPoints( +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_ax, __pyx_v_t1_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 761, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_v_bx, __pyx_v_t1_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 761, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_9 = PyNumber_Add(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 761, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_v_cx, __pyx_v_t1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 761, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Add(__pyx_t_9, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 761, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_dx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 761, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF_SET(__pyx_v_d1x, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":762 + * c1y = (2 * by * t1 + cy + 3 * ay * t1_2) * delta + * d1x = ax * t1_3 + bx * t1_2 + cx * t1 + dx + * d1y = ay * t1_3 + by * t1_2 + cy * t1 + dy # <<<<<<<<<<<<<< + * pt1, pt2, pt3, pt4 = calcCubicPoints( + * (a1x, a1y), (b1x, b1y), (c1x, c1y), (d1x, d1y) +*/ + __pyx_t_2 = PyNumber_Multiply(__pyx_v_ay, __pyx_v_t1_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 762, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_v_by, __pyx_v_t1_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 762, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_9 = PyNumber_Add(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 762, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_v_cy, __pyx_v_t1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 762, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Add(__pyx_t_9, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 762, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_dy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 762, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF_SET(__pyx_v_d1y, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":763 + * d1x = ax * t1_3 + bx * t1_2 + cx * t1 + dx + * d1y = ay * t1_3 + by * t1_2 + cy * t1 + dy + * pt1, pt2, pt3, pt4 = calcCubicPoints( # <<<<<<<<<<<<<< + * (a1x, a1y), (b1x, b1y), (c1x, c1y), (d1x, d1y) + * ) +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_mstate_global->__pyx_n_u_calcCubicPoints); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 763, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + + /* "fontTools/misc/bezierTools.py":764 + * d1y = ay * t1_3 + by * t1_2 + cy * t1 + dy + * pt1, pt2, pt3, pt4 = calcCubicPoints( + * (a1x, a1y), (b1x, b1y), (c1x, c1y), (d1x, d1y) # <<<<<<<<<<<<<< + * ) + * segments.append((pt1, pt2, pt3, pt4)) +*/ + __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 764, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_INCREF(__pyx_v_a1x); + __Pyx_GIVEREF(__pyx_v_a1x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_v_a1x) != (0)) __PYX_ERR(0, 764, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_a1y); + __Pyx_GIVEREF(__pyx_v_a1y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_v_a1y) != (0)) __PYX_ERR(0, 764, __pyx_L1_error); + __pyx_t_11 = PyTuple_New(2); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 764, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_INCREF(__pyx_v_b1x); + __Pyx_GIVEREF(__pyx_v_b1x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_v_b1x) != (0)) __PYX_ERR(0, 764, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_b1y); + __Pyx_GIVEREF(__pyx_v_b1y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_v_b1y) != (0)) __PYX_ERR(0, 764, __pyx_L1_error); + __pyx_t_12 = PyTuple_New(2); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 764, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_INCREF(__pyx_v_c1x); + __Pyx_GIVEREF(__pyx_v_c1x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_v_c1x) != (0)) __PYX_ERR(0, 764, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_c1y); + __Pyx_GIVEREF(__pyx_v_c1y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_12, 1, __pyx_v_c1y) != (0)) __PYX_ERR(0, 764, __pyx_L1_error); + __pyx_t_13 = PyTuple_New(2); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 764, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_13); + __Pyx_INCREF(__pyx_v_d1x); + __Pyx_GIVEREF(__pyx_v_d1x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_v_d1x) != (0)) __PYX_ERR(0, 764, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_d1y); + __Pyx_GIVEREF(__pyx_v_d1y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_13, 1, __pyx_v_d1y) != (0)) __PYX_ERR(0, 764, __pyx_L1_error); + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_9))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_9); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_9); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_9, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_2, __pyx_t_10, __pyx_t_11, __pyx_t_12, __pyx_t_13}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_9, __pyx_callargs+__pyx_t_7, (5-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 763, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 763, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_9); + __pyx_t_13 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_13); + __pyx_t_12 = PyTuple_GET_ITEM(sequence, 2); + __Pyx_INCREF(__pyx_t_12); + __pyx_t_11 = PyTuple_GET_ITEM(sequence, 3); + __Pyx_INCREF(__pyx_t_11); + } else { + __pyx_t_9 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 763, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_9); + __pyx_t_13 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 763, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_13); + __pyx_t_12 = __Pyx_PyList_GetItemRefFast(sequence, 2, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 763, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_12); + __pyx_t_11 = __Pyx_PyList_GetItemRefFast(sequence, 3, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 763, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_11); + } + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_9,&__pyx_t_13,&__pyx_t_12,&__pyx_t_11}; + for (i=0; i < 4; i++) { + PyObject* item = __Pyx_PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 763, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_9,&__pyx_t_13,&__pyx_t_12,&__pyx_t_11}; + __pyx_t_10 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 763, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_10); + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_5(__pyx_t_10); if (unlikely(!item)) goto __pyx_L13_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_5(__pyx_t_10), 4) < (0)) __PYX_ERR(0, 763, __pyx_L1_error) + __pyx_t_5 = NULL; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + goto __pyx_L14_unpacking_done; + __pyx_L13_unpacking_failed:; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_5 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 763, __pyx_L1_error) + __pyx_L14_unpacking_done:; + } + + /* "fontTools/misc/bezierTools.py":763 + * d1x = ax * t1_3 + bx * t1_2 + cx * t1 + dx + * d1y = ay * t1_3 + by * t1_2 + cy * t1 + dy + * pt1, pt2, pt3, pt4 = calcCubicPoints( # <<<<<<<<<<<<<< + * (a1x, a1y), (b1x, b1y), (c1x, c1y), (d1x, d1y) + * ) +*/ + __Pyx_XDECREF_SET(__pyx_v_pt1, __pyx_t_9); + __pyx_t_9 = 0; + __Pyx_XDECREF_SET(__pyx_v_pt2, __pyx_t_13); + __pyx_t_13 = 0; + __Pyx_XDECREF_SET(__pyx_v_pt3, __pyx_t_12); + __pyx_t_12 = 0; + __Pyx_XDECREF_SET(__pyx_v_pt4, __pyx_t_11); + __pyx_t_11 = 0; + + /* "fontTools/misc/bezierTools.py":766 + * (a1x, a1y), (b1x, b1y), (c1x, c1y), (d1x, d1y) + * ) + * segments.append((pt1, pt2, pt3, pt4)) # <<<<<<<<<<<<<< + * return segments + * +*/ + __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 766, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_v_pt1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_pt1) != (0)) __PYX_ERR(0, 766, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt2); + __Pyx_GIVEREF(__pyx_v_pt2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_pt2) != (0)) __PYX_ERR(0, 766, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt3); + __Pyx_GIVEREF(__pyx_v_pt3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_pt3) != (0)) __PYX_ERR(0, 766, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_pt4); + __Pyx_GIVEREF(__pyx_v_pt4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_pt4) != (0)) __PYX_ERR(0, 766, __pyx_L1_error); + __pyx_t_3 = __Pyx_PyList_Append(__pyx_v_segments, __pyx_t_1); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 766, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":744 + * cx, cy = c + * dx, dy = d + * for i in range(len(ts) - 1): # <<<<<<<<<<<<<< + * t1 = ts[i] + * t2 = ts[i + 1] +*/ + } + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":767 + * ) + * segments.append((pt1, pt2, pt3, pt4)) + * return segments # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_segments); + __pyx_r = __pyx_v_segments; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":735 + * + * + * def _splitCubicAtT(a, b, c, d, *ts): # <<<<<<<<<<<<<< + * ts = list(ts) + * ts.insert(0, 0.0) +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_XDECREF(__pyx_t_13); + __Pyx_AddTraceback("fontTools.misc.bezierTools._splitCubicAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_ts); + __Pyx_XDECREF(__pyx_v_segments); + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_cx); + __Pyx_XDECREF(__pyx_v_cy); + __Pyx_XDECREF(__pyx_v_dx); + __Pyx_XDECREF(__pyx_v_dy); + __Pyx_XDECREF(__pyx_v_i); + __Pyx_XDECREF(__pyx_v_t1); + __Pyx_XDECREF(__pyx_v_t2); + __Pyx_XDECREF(__pyx_v_delta); + __Pyx_XDECREF(__pyx_v_delta_2); + __Pyx_XDECREF(__pyx_v_delta_3); + __Pyx_XDECREF(__pyx_v_t1_2); + __Pyx_XDECREF(__pyx_v_t1_3); + __Pyx_XDECREF(__pyx_v_a1x); + __Pyx_XDECREF(__pyx_v_a1y); + __Pyx_XDECREF(__pyx_v_b1x); + __Pyx_XDECREF(__pyx_v_b1y); + __Pyx_XDECREF(__pyx_v_c1x); + __Pyx_XDECREF(__pyx_v_c1y); + __Pyx_XDECREF(__pyx_v_d1x); + __Pyx_XDECREF(__pyx_v_d1y); + __Pyx_XDECREF(__pyx_v_pt1); + __Pyx_XDECREF(__pyx_v_pt2); + __Pyx_XDECREF(__pyx_v_pt3); + __Pyx_XDECREF(__pyx_v_pt4); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_45generator1(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/misc/bezierTools.py":770 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * a=cython.complex, + * b=cython.complex, +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_44_splitCubicAtTC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_43_splitCubicAtTC, "_splitCubicAtTC(double complex a, double complex b, double complex c, double complex d, *ts)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_44_splitCubicAtTC = {"_splitCubicAtTC", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_44_splitCubicAtTC, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_43_splitCubicAtTC}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_44_splitCubicAtTC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_a; + __pyx_t_double_complex __pyx_v_b; + __pyx_t_double_complex __pyx_v_c; + __pyx_t_double_complex __pyx_v_d; + PyObject *__pyx_v_ts = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_splitCubicAtTC (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + __pyx_v_ts = __Pyx_ArgsSlice_FASTCALL(__pyx_args, 4, __pyx_nargs); + if (unlikely(!__pyx_v_ts)) { + __Pyx_RefNannyFinishContext(); + return NULL; + } + __Pyx_GOTREF(__pyx_v_ts); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_a,&__pyx_mstate_global->__pyx_n_u_b,&__pyx_mstate_global->__pyx_n_u_c,&__pyx_mstate_global->__pyx_n_u_d,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 770, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + default: + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 770, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 770, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 770, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 770, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + const Py_ssize_t used_pos_args = (kwd_pos_args < 4) ? kwd_pos_args : 4; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, used_pos_args, __pyx_kwds_len, "_splitCubicAtTC", 0) < (0)) __PYX_ERR(0, 770, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_splitCubicAtTC", 0, 4, 4, i); __PYX_ERR(0, 770, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs < 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 770, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 770, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 770, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 770, __pyx_L3_error) + } + __pyx_v_a = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 785, __pyx_L3_error) + __pyx_v_b = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 785, __pyx_L3_error) + __pyx_v_c = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 785, __pyx_L3_error) + __pyx_v_d = __Pyx_PyComplex_As___pyx_t_double_complex(values[3]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 785, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_splitCubicAtTC", 0, 4, 4, __pyx_nargs); __PYX_ERR(0, 770, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_CLEAR(__pyx_v_ts); + __Pyx_AddTraceback("fontTools.misc.bezierTools._splitCubicAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_43_splitCubicAtTC(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_c, __pyx_v_d, __pyx_v_ts); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_DECREF(__pyx_v_ts); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_43_splitCubicAtTC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_a, __pyx_t_double_complex __pyx_v_b, __pyx_t_double_complex __pyx_v_c, __pyx_t_double_complex __pyx_v_d, PyObject *__pyx_v_ts) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_splitCubicAtTC", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC(__pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC, __pyx_mstate_global->__pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 770, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_v_a = __pyx_v_a; + __pyx_cur_scope->__pyx_v_b = __pyx_v_b; + __pyx_cur_scope->__pyx_v_c = __pyx_v_c; + __pyx_cur_scope->__pyx_v_d = __pyx_v_d; + __pyx_cur_scope->__pyx_v_ts = __pyx_v_ts; + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_ts); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_ts); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_4misc_11bezierTools_45generator1, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[3]), (PyObject *) __pyx_cur_scope, __pyx_mstate_global->__pyx_n_u_splitCubicAtTC_2, __pyx_mstate_global->__pyx_n_u_splitCubicAtTC_2, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools); if (unlikely(!gen)) __PYX_ERR(0, 770, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.misc.bezierTools._splitCubicAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_45generator1(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + Py_ssize_t __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + size_t __pyx_t_6; + PyObject *(*__pyx_t_7)(PyObject *); + double __pyx_t_8; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + PyObject *(*__pyx_t_13)(PyObject *); + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_splitCubicAtTC", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + case 1: goto __pyx_L8_resume_from_yield; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(__pyx_sent_value != Py_None)) { + if (unlikely(__pyx_sent_value)) PyErr_SetString(PyExc_TypeError, "can't send non-None value to a just-started generator"); + __PYX_ERR(0, 770, __pyx_L1_error) + } + + /* "fontTools/misc/bezierTools.py":786 + * ) + * def _splitCubicAtTC(a, b, c, d, *ts): + * ts = list(ts) # <<<<<<<<<<<<<< + * ts.insert(0, 0.0) + * ts.append(1.0) +*/ + __pyx_t_1 = PySequence_List(__pyx_cur_scope->__pyx_v_ts); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 786, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_ts); + __Pyx_DECREF_SET(__pyx_cur_scope->__pyx_v_ts, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":787 + * def _splitCubicAtTC(a, b, c, d, *ts): + * ts = list(ts) + * ts.insert(0, 0.0) # <<<<<<<<<<<<<< + * ts.append(1.0) + * for i in range(len(ts) - 1): +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_ts, __pyx_mstate_global->__pyx_n_u_insert); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 787, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_mstate_global->__pyx_tuple[0], NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 787, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":788 + * ts = list(ts) + * ts.insert(0, 0.0) + * ts.append(1.0) # <<<<<<<<<<<<<< + * for i in range(len(ts) - 1): + * t1 = ts[i] +*/ + __pyx_t_3 = __Pyx_PyObject_Append(__pyx_cur_scope->__pyx_v_ts, __pyx_mstate_global->__pyx_float_1_0); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 788, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":789 + * ts.insert(0, 0.0) + * ts.append(1.0) + * for i in range(len(ts) - 1): # <<<<<<<<<<<<<< + * t1 = ts[i] + * t2 = ts[i + 1] +*/ + __pyx_t_1 = NULL; + __pyx_t_4 = PyObject_Length(__pyx_cur_scope->__pyx_v_ts); if (unlikely(__pyx_t_4 == ((Py_ssize_t)-1))) __PYX_ERR(0, 789, __pyx_L1_error) + __pyx_t_5 = PyLong_FromSsize_t((__pyx_t_4 - 1)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 789, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = 1; + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_t_5}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)(&PyRange_Type), __pyx_callargs+__pyx_t_6, (2-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 789, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __pyx_t_5 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 789, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_5); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 789, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + for (;;) { + { + __pyx_t_2 = __pyx_t_7(__pyx_t_5); + if (unlikely(!__pyx_t_2)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 789, __pyx_L1_error) + PyErr_Clear(); + } + break; + } + } + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_i); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_i, __pyx_t_2); + __Pyx_GIVEREF(__pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":790 + * ts.append(1.0) + * for i in range(len(ts) - 1): + * t1 = ts[i] # <<<<<<<<<<<<<< + * t2 = ts[i + 1] + * delta = t2 - t1 +*/ + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_cur_scope->__pyx_v_ts, __pyx_cur_scope->__pyx_v_i); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 790, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_8 = __Pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 790, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_cur_scope->__pyx_v_t1 = __pyx_t_8; + + /* "fontTools/misc/bezierTools.py":791 + * for i in range(len(ts) - 1): + * t1 = ts[i] + * t2 = ts[i + 1] # <<<<<<<<<<<<<< + * delta = t2 - t1 + * +*/ + __pyx_t_2 = __Pyx_PyLong_AddObjC(__pyx_cur_scope->__pyx_v_i, __pyx_mstate_global->__pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 791, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_cur_scope->__pyx_v_ts, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 791, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_8 = __Pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 791, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_cur_scope->__pyx_v_t2 = __pyx_t_8; + + /* "fontTools/misc/bezierTools.py":792 + * t1 = ts[i] + * t2 = ts[i + 1] + * delta = t2 - t1 # <<<<<<<<<<<<<< + * + * delta_2 = delta * delta +*/ + __pyx_cur_scope->__pyx_v_delta = (__pyx_cur_scope->__pyx_v_t2 - __pyx_cur_scope->__pyx_v_t1); + + /* "fontTools/misc/bezierTools.py":794 + * delta = t2 - t1 + * + * delta_2 = delta * delta # <<<<<<<<<<<<<< + * delta_3 = delta * delta_2 + * t1_2 = t1 * t1 +*/ + __pyx_cur_scope->__pyx_v_delta_2 = (__pyx_cur_scope->__pyx_v_delta * __pyx_cur_scope->__pyx_v_delta); + + /* "fontTools/misc/bezierTools.py":795 + * + * delta_2 = delta * delta + * delta_3 = delta * delta_2 # <<<<<<<<<<<<<< + * t1_2 = t1 * t1 + * t1_3 = t1 * t1_2 +*/ + __pyx_cur_scope->__pyx_v_delta_3 = (__pyx_cur_scope->__pyx_v_delta * __pyx_cur_scope->__pyx_v_delta_2); + + /* "fontTools/misc/bezierTools.py":796 + * delta_2 = delta * delta + * delta_3 = delta * delta_2 + * t1_2 = t1 * t1 # <<<<<<<<<<<<<< + * t1_3 = t1 * t1_2 + * +*/ + __pyx_cur_scope->__pyx_v_t1_2 = (__pyx_cur_scope->__pyx_v_t1 * __pyx_cur_scope->__pyx_v_t1); + + /* "fontTools/misc/bezierTools.py":797 + * delta_3 = delta * delta_2 + * t1_2 = t1 * t1 + * t1_3 = t1 * t1_2 # <<<<<<<<<<<<<< + * + * # calc new a, b, c and d +*/ + __pyx_cur_scope->__pyx_v_t1_3 = (__pyx_cur_scope->__pyx_v_t1 * __pyx_cur_scope->__pyx_v_t1_2); + + /* "fontTools/misc/bezierTools.py":800 + * + * # calc new a, b, c and d + * a1 = a * delta_3 # <<<<<<<<<<<<<< + * b1 = (3 * a * t1 + b) * delta_2 + * c1 = (2 * b * t1 + c + 3 * a * t1_2) * delta +*/ + __pyx_cur_scope->__pyx_v_a1 = __Pyx_c_prod_double(__pyx_cur_scope->__pyx_v_a, __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_delta_3, 0)); + + /* "fontTools/misc/bezierTools.py":801 + * # calc new a, b, c and d + * a1 = a * delta_3 + * b1 = (3 * a * t1 + b) * delta_2 # <<<<<<<<<<<<<< + * c1 = (2 * b * t1 + c + 3 * a * t1_2) * delta + * d1 = a * t1_3 + b * t1_2 + c * t1 + d +*/ + __pyx_cur_scope->__pyx_v_b1 = __Pyx_c_prod_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(3, 0), __pyx_cur_scope->__pyx_v_a), __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1, 0)), __pyx_cur_scope->__pyx_v_b), __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_delta_2, 0)); + + /* "fontTools/misc/bezierTools.py":802 + * a1 = a * delta_3 + * b1 = (3 * a * t1 + b) * delta_2 + * c1 = (2 * b * t1 + c + 3 * a * t1_2) * delta # <<<<<<<<<<<<<< + * d1 = a * t1_3 + b * t1_2 + c * t1 + d + * pt1, pt2, pt3, pt4 = calcCubicPointsC(a1, b1, c1, d1) +*/ + __pyx_cur_scope->__pyx_v_c1 = __Pyx_c_prod_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(2, 0), __pyx_cur_scope->__pyx_v_b), __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1, 0)), __pyx_cur_scope->__pyx_v_c), __Pyx_c_prod_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts(3, 0), __pyx_cur_scope->__pyx_v_a), __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1_2, 0))), __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_delta, 0)); + + /* "fontTools/misc/bezierTools.py":803 + * b1 = (3 * a * t1 + b) * delta_2 + * c1 = (2 * b * t1 + c + 3 * a * t1_2) * delta + * d1 = a * t1_3 + b * t1_2 + c * t1 + d # <<<<<<<<<<<<<< + * pt1, pt2, pt3, pt4 = calcCubicPointsC(a1, b1, c1, d1) + * yield (pt1, pt2, pt3, pt4) +*/ + __pyx_cur_scope->__pyx_v_d1 = __Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_cur_scope->__pyx_v_a, __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1_3, 0)), __Pyx_c_prod_double(__pyx_cur_scope->__pyx_v_b, __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1_2, 0))), __Pyx_c_prod_double(__pyx_cur_scope->__pyx_v_c, __pyx_t_double_complex_from_parts(__pyx_cur_scope->__pyx_v_t1, 0))), __pyx_cur_scope->__pyx_v_d); + + /* "fontTools/misc/bezierTools.py":804 + * c1 = (2 * b * t1 + c + 3 * a * t1_2) * delta + * d1 = a * t1_3 + b * t1_2 + c * t1 + d + * pt1, pt2, pt3, pt4 = calcCubicPointsC(a1, b1, c1, d1) # <<<<<<<<<<<<<< + * yield (pt1, pt2, pt3, pt4) + * +*/ + __pyx_t_1 = __pyx_f_9fontTools_4misc_11bezierTools_calcCubicPointsC(__pyx_cur_scope->__pyx_v_a1, __pyx_cur_scope->__pyx_v_b1, __pyx_cur_scope->__pyx_v_c1, __pyx_cur_scope->__pyx_v_d1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 804, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 804, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_9 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_9); + __pyx_t_10 = PyTuple_GET_ITEM(sequence, 2); + __Pyx_INCREF(__pyx_t_10); + __pyx_t_11 = PyTuple_GET_ITEM(sequence, 3); + __Pyx_INCREF(__pyx_t_11); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 804, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_9 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 804, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_9); + __pyx_t_10 = __Pyx_PyList_GetItemRefFast(sequence, 2, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 804, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_10); + __pyx_t_11 = __Pyx_PyList_GetItemRefFast(sequence, 3, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 804, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_11); + } + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_9,&__pyx_t_10,&__pyx_t_11}; + for (i=0; i < 4; i++) { + PyObject* item = __Pyx_PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 804, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_9,&__pyx_t_10,&__pyx_t_11}; + __pyx_t_12 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 804, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_13 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_12); + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_13(__pyx_t_12); if (unlikely(!item)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_13(__pyx_t_12), 4) < (0)) __PYX_ERR(0, 804, __pyx_L1_error) + __pyx_t_13 = NULL; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + goto __pyx_L7_unpacking_done; + __pyx_L6_unpacking_failed:; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __pyx_t_13 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 804, __pyx_L1_error) + __pyx_L7_unpacking_done:; + } + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_pt1); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_pt1, __pyx_t_2); + __Pyx_GIVEREF(__pyx_t_2); + __pyx_t_2 = 0; + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_pt2); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_pt2, __pyx_t_9); + __Pyx_GIVEREF(__pyx_t_9); + __pyx_t_9 = 0; + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_pt3); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_pt3, __pyx_t_10); + __Pyx_GIVEREF(__pyx_t_10); + __pyx_t_10 = 0; + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_pt4); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_pt4, __pyx_t_11); + __Pyx_GIVEREF(__pyx_t_11); + __pyx_t_11 = 0; + + /* "fontTools/misc/bezierTools.py":805 + * d1 = a * t1_3 + b * t1_2 + c * t1 + d + * pt1, pt2, pt3, pt4 = calcCubicPointsC(a1, b1, c1, d1) + * yield (pt1, pt2, pt3, pt4) # <<<<<<<<<<<<<< + * + * +*/ + __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 805, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_pt1); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_pt1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_cur_scope->__pyx_v_pt1) != (0)) __PYX_ERR(0, 805, __pyx_L1_error); + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_pt2); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_pt2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_cur_scope->__pyx_v_pt2) != (0)) __PYX_ERR(0, 805, __pyx_L1_error); + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_pt3); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_pt3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_cur_scope->__pyx_v_pt3) != (0)) __PYX_ERR(0, 805, __pyx_L1_error); + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_pt4); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_pt4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_cur_scope->__pyx_v_pt4) != (0)) __PYX_ERR(0, 805, __pyx_L1_error); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + __Pyx_XGIVEREF(__pyx_t_5); + __pyx_cur_scope->__pyx_t_0 = __pyx_t_5; + __pyx_cur_scope->__pyx_t_1 = __pyx_t_7; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + /* return from generator, yielding value */ + __pyx_generator->resume_label = 1; + return __pyx_r; + __pyx_L8_resume_from_yield:; + __pyx_t_5 = __pyx_cur_scope->__pyx_t_0; + __pyx_cur_scope->__pyx_t_0 = 0; + __Pyx_XGOTREF(__pyx_t_5); + __pyx_t_7 = __pyx_cur_scope->__pyx_t_1; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 805, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":789 + * ts.insert(0, 0.0) + * ts.append(1.0) + * for i in range(len(ts) - 1): # <<<<<<<<<<<<<< + * t1 = ts[i] + * t2 = ts[i + 1] +*/ + } + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* "fontTools/misc/bezierTools.py":770 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * a=cython.complex, + * b=cython.complex, +*/ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + if (__Pyx_PyErr_Occurred()) { + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_AddTraceback("_splitCubicAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":815 + * + * + * def solveQuadratic(a, b, c, sqrt=sqrt): # <<<<<<<<<<<<<< + * """Solve a quadratic equation. + * +*/ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_96__defaults__(CYTHON_UNUSED PyObject *__pyx_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__defaults__", 0); + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 815, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__Pyx_CyFunction_Defaults(struct __pyx_defaults, __pyx_self)->arg0); + __Pyx_GIVEREF(__Pyx_CyFunction_Defaults(struct __pyx_defaults, __pyx_self)->arg0); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __Pyx_CyFunction_Defaults(struct __pyx_defaults, __pyx_self)->arg0) != (0)) __PYX_ERR(0, 815, __pyx_L1_error); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 815, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 815, __pyx_L1_error); + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, Py_None) != (0)) __PYX_ERR(0, 815, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("fontTools.misc.bezierTools.__defaults__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_47solveQuadratic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_46solveQuadratic, "solveQuadratic(a, b, c, sqrt=sqrt)\n\nSolve a quadratic equation.\n\nSolves *a*x*x + b*x + c = 0* where a, b and c are real.\n\nArgs:\n a: coefficient of *x\302\262*\n b: coefficient of *x*\n c: constant term\n\nReturns:\n A list of roots. Note that the returned list is neither guaranteed to\n be sorted nor to contain unique values!"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_47solveQuadratic = {"solveQuadratic", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_47solveQuadratic, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_46solveQuadratic}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_47solveQuadratic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_a = 0; + PyObject *__pyx_v_b = 0; + PyObject *__pyx_v_c = 0; + PyObject *__pyx_v_sqrt = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("solveQuadratic (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_a,&__pyx_mstate_global->__pyx_n_u_b,&__pyx_mstate_global->__pyx_n_u_c,&__pyx_mstate_global->__pyx_n_u_sqrt,0}; + struct __pyx_defaults *__pyx_dynamic_args = __Pyx_CyFunction_Defaults(struct __pyx_defaults, __pyx_self); + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 815, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 815, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 815, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 815, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 815, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "solveQuadratic", 0) < (0)) __PYX_ERR(0, 815, __pyx_L3_error) + if (!values[3]) values[3] = __Pyx_NewRef(__pyx_dynamic_args->arg0); + for (Py_ssize_t i = __pyx_nargs; i < 3; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("solveQuadratic", 0, 3, 4, i); __PYX_ERR(0, 815, __pyx_L3_error) } + } + } else { + switch (__pyx_nargs) { + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 815, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 815, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 815, __pyx_L3_error) + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 815, __pyx_L3_error) + break; + default: goto __pyx_L5_argtuple_error; + } + if (!values[3]) values[3] = __Pyx_NewRef(__pyx_dynamic_args->arg0); + } + __pyx_v_a = values[0]; + __pyx_v_b = values[1]; + __pyx_v_c = values[2]; + __pyx_v_sqrt = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("solveQuadratic", 0, 3, 4, __pyx_nargs); __PYX_ERR(0, 815, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.solveQuadratic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_46solveQuadratic(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_c, __pyx_v_sqrt); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_46solveQuadratic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_sqrt) { + PyObject *__pyx_v_roots = NULL; + PyObject *__pyx_v_DD = NULL; + PyObject *__pyx_v_rDD = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + size_t __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("solveQuadratic", 0); + + /* "fontTools/misc/bezierTools.py":829 + * be sorted nor to contain unique values! + * """ + * if abs(a) < epsilon: # <<<<<<<<<<<<<< + * if abs(b) < epsilon: + * # We have a non-equation; therefore, we have no valid solution +*/ + __pyx_t_1 = __Pyx_PyNumber_Absolute(__pyx_v_a); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 829, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_epsilon); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 829, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 829, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 829, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":830 + * """ + * if abs(a) < epsilon: + * if abs(b) < epsilon: # <<<<<<<<<<<<<< + * # We have a non-equation; therefore, we have no valid solution + * roots = [] +*/ + __pyx_t_3 = __Pyx_PyNumber_Absolute(__pyx_v_b); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 830, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_epsilon); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 830, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 830, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 830, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":832 + * if abs(b) < epsilon: + * # We have a non-equation; therefore, we have no valid solution + * roots = [] # <<<<<<<<<<<<<< + * else: + * # We have a linear equation with 1 root. +*/ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 832, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_roots = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":830 + * """ + * if abs(a) < epsilon: + * if abs(b) < epsilon: # <<<<<<<<<<<<<< + * # We have a non-equation; therefore, we have no valid solution + * roots = [] +*/ + goto __pyx_L4; + } + + /* "fontTools/misc/bezierTools.py":835 + * else: + * # We have a linear equation with 1 root. + * roots = [-c / b] # <<<<<<<<<<<<<< + * else: + * # We have a true quadratic equation. Apply the quadratic formula to find two roots. +*/ + /*else*/ { + __pyx_t_1 = PyNumber_Negative(__pyx_v_c); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 835, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_v_b); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 835, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 835, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_t_2) != (0)) __PYX_ERR(0, 835, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_v_roots = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + } + __pyx_L4:; + + /* "fontTools/misc/bezierTools.py":829 + * be sorted nor to contain unique values! + * """ + * if abs(a) < epsilon: # <<<<<<<<<<<<<< + * if abs(b) < epsilon: + * # We have a non-equation; therefore, we have no valid solution +*/ + goto __pyx_L3; + } + + /* "fontTools/misc/bezierTools.py":838 + * else: + * # We have a true quadratic equation. Apply the quadratic formula to find two roots. + * DD = b * b - 4.0 * a * c # <<<<<<<<<<<<<< + * if DD >= 0.0: + * rDD = sqrt(DD) +*/ + /*else*/ { + __pyx_t_1 = PyNumber_Multiply(__pyx_v_b, __pyx_v_b); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 838, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_mstate_global->__pyx_float_4_0, __pyx_v_a); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 838, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_2, __pyx_v_c); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 838, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 838, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_DD = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":839 + * # We have a true quadratic equation. Apply the quadratic formula to find two roots. + * DD = b * b - 4.0 * a * c + * if DD >= 0.0: # <<<<<<<<<<<<<< + * rDD = sqrt(DD) + * roots = [(-b + rDD) / 2.0 / a, (-b - rDD) / 2.0 / a] +*/ + __pyx_t_2 = PyObject_RichCompare(__pyx_v_DD, __pyx_mstate_global->__pyx_float_0_0, Py_GE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 839, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 839, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":840 + * DD = b * b - 4.0 * a * c + * if DD >= 0.0: + * rDD = sqrt(DD) # <<<<<<<<<<<<<< + * roots = [(-b + rDD) / 2.0 / a, (-b - rDD) / 2.0 / a] + * else: +*/ + __pyx_t_3 = NULL; + __Pyx_INCREF(__pyx_v_sqrt); + __pyx_t_1 = __pyx_v_sqrt; + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_3); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_DD}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 840, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __pyx_v_rDD = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":841 + * if DD >= 0.0: + * rDD = sqrt(DD) + * roots = [(-b + rDD) / 2.0 / a, (-b - rDD) / 2.0 / a] # <<<<<<<<<<<<<< + * else: + * # complex roots, ignore +*/ + __pyx_t_2 = PyNumber_Negative(__pyx_v_b); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 841, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_rDD); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 841, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_1, __pyx_mstate_global->__pyx_float_2_0, 2.0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 841, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyNumber_Divide(__pyx_t_2, __pyx_v_a); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 841, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Negative(__pyx_v_b); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 841, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Subtract(__pyx_t_2, __pyx_v_rDD); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 841, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_3, __pyx_mstate_global->__pyx_float_2_0, 2.0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 841, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyNumber_Divide(__pyx_t_2, __pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 841, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyList_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 841, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 841, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 1, __pyx_t_3) != (0)) __PYX_ERR(0, 841, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_v_roots = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":839 + * # We have a true quadratic equation. Apply the quadratic formula to find two roots. + * DD = b * b - 4.0 * a * c + * if DD >= 0.0: # <<<<<<<<<<<<<< + * rDD = sqrt(DD) + * roots = [(-b + rDD) / 2.0 / a, (-b - rDD) / 2.0 / a] +*/ + goto __pyx_L5; + } + + /* "fontTools/misc/bezierTools.py":844 + * else: + * # complex roots, ignore + * roots = [] # <<<<<<<<<<<<<< + * return roots + * +*/ + /*else*/ { + __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 844, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_v_roots = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + } + __pyx_L5:; + } + __pyx_L3:; + + /* "fontTools/misc/bezierTools.py":845 + * # complex roots, ignore + * roots = [] + * return roots # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_roots); + __pyx_r = __pyx_v_roots; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":815 + * + * + * def solveQuadratic(a, b, c, sqrt=sqrt): # <<<<<<<<<<<<<< + * """Solve a quadratic equation. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("fontTools.misc.bezierTools.solveQuadratic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_roots); + __Pyx_XDECREF(__pyx_v_DD); + __Pyx_XDECREF(__pyx_v_rDD); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":848 + * + * + * def solveCubic(a, b, c, d): # <<<<<<<<<<<<<< + * """Solve a cubic equation. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_49solveCubic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_48solveCubic, "solveCubic(a, b, c, d)\n\nSolve a cubic equation.\n\nSolves *a*x*x*x + b*x*x + c*x + d = 0* where a, b, c and d are real.\n\nArgs:\n a: coefficient of *x\302\263*\n b: coefficient of *x\302\262*\n c: coefficient of *x*\n d: constant term\n\nReturns:\n A list of roots. Note that the returned list is neither guaranteed to\n be sorted nor to contain unique values!\n\nExamples::\n\n >>> solveCubic(1, 1, -6, 0)\n [-3.0, -0.0, 2.0]\n >>> solveCubic(-10.0, -9.0, 48.0, -29.0)\n [-2.9, 1.0, 1.0]\n >>> solveCubic(-9.875, -9.0, 47.625, -28.75)\n [-2.911392, 1.0, 1.0]\n >>> solveCubic(1.0, -4.5, 6.75, -3.375)\n [1.5, 1.5, 1.5]\n >>> solveCubic(-12.0, 18.0, -9.0, 1.50023651123)\n [0.5, 0.5, 0.5]\n >>> solveCubic(\n ... 9.0, 0.0, 0.0, -7.62939453125e-05\n ... ) == [-0.0, -0.0, -0.0]\n True"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_49solveCubic = {"solveCubic", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_49solveCubic, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_48solveCubic}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_49solveCubic(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_a = 0; + PyObject *__pyx_v_b = 0; + PyObject *__pyx_v_c = 0; + PyObject *__pyx_v_d = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("solveCubic (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_a,&__pyx_mstate_global->__pyx_n_u_b,&__pyx_mstate_global->__pyx_n_u_c,&__pyx_mstate_global->__pyx_n_u_d,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 848, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 848, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 848, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 848, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 848, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "solveCubic", 0) < (0)) __PYX_ERR(0, 848, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("solveCubic", 1, 4, 4, i); __PYX_ERR(0, 848, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 848, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 848, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 848, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 848, __pyx_L3_error) + } + __pyx_v_a = values[0]; + __pyx_v_b = values[1]; + __pyx_v_c = values[2]; + __pyx_v_d = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("solveCubic", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 848, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.solveCubic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_48solveCubic(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_c, __pyx_v_d); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_48solveCubic(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) { + PyObject *__pyx_v_a1 = NULL; + PyObject *__pyx_v_a2 = NULL; + PyObject *__pyx_v_a3 = NULL; + PyObject *__pyx_v_Q = NULL; + PyObject *__pyx_v_R = NULL; + PyObject *__pyx_v_R2 = NULL; + PyObject *__pyx_v_Q3 = NULL; + PyObject *__pyx_v_R2_Q3 = NULL; + PyObject *__pyx_v_x = NULL; + PyObject *__pyx_v_theta = NULL; + PyObject *__pyx_v_rQ2 = NULL; + PyObject *__pyx_v_a1_3 = NULL; + PyObject *__pyx_v_x0 = NULL; + PyObject *__pyx_v_x1 = NULL; + PyObject *__pyx_v_x2 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + size_t __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + int __pyx_t_7; + double __pyx_t_8; + double __pyx_t_9; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("solveCubic", 0); + __Pyx_INCREF(__pyx_v_a); + + /* "fontTools/misc/bezierTools.py":886 + * # found at: http://www.strangecreations.com/library/snippets/Cubic.C + * # + * if abs(a) < epsilon: # <<<<<<<<<<<<<< + * # don't just test for zero; for very small values of 'a' solveCubic() + * # returns unreliable results, so we fall back to quad. +*/ + __pyx_t_1 = __Pyx_PyNumber_Absolute(__pyx_v_a); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 886, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_epsilon); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 886, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 886, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 886, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":889 + * # don't just test for zero; for very small values of 'a' solveCubic() + * # returns unreliable results, so we fall back to quad. + * return solveQuadratic(b, c, d) # <<<<<<<<<<<<<< + * a = float(a) + * a1 = b / a +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_solveQuadratic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 889, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_2, __pyx_v_b, __pyx_v_c, __pyx_v_d}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_5, (4-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 889, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":886 + * # found at: http://www.strangecreations.com/library/snippets/Cubic.C + * # + * if abs(a) < epsilon: # <<<<<<<<<<<<<< + * # don't just test for zero; for very small values of 'a' solveCubic() + * # returns unreliable results, so we fall back to quad. +*/ + } + + /* "fontTools/misc/bezierTools.py":890 + * # returns unreliable results, so we fall back to quad. + * return solveQuadratic(b, c, d) + * a = float(a) # <<<<<<<<<<<<<< + * a1 = b / a + * a2 = c / a +*/ + __pyx_t_3 = __Pyx_PyNumber_Float(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 890, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF_SET(__pyx_v_a, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":891 + * return solveQuadratic(b, c, d) + * a = float(a) + * a1 = b / a # <<<<<<<<<<<<<< + * a2 = c / a + * a3 = d / a +*/ + __pyx_t_3 = __Pyx_PyNumber_Divide(__pyx_v_b, __pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 891, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_a1 = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":892 + * a = float(a) + * a1 = b / a + * a2 = c / a # <<<<<<<<<<<<<< + * a3 = d / a + * +*/ + __pyx_t_3 = __Pyx_PyNumber_Divide(__pyx_v_c, __pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 892, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_a2 = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":893 + * a1 = b / a + * a2 = c / a + * a3 = d / a # <<<<<<<<<<<<<< + * + * Q = (a1 * a1 - 3.0 * a2) / 9.0 +*/ + __pyx_t_3 = __Pyx_PyNumber_Divide(__pyx_v_d, __pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 893, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_a3 = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":895 + * a3 = d / a + * + * Q = (a1 * a1 - 3.0 * a2) / 9.0 # <<<<<<<<<<<<<< + * R = (2.0 * a1 * a1 * a1 - 9.0 * a1 * a2 + 27.0 * a3) / 54.0 + * +*/ + __pyx_t_3 = PyNumber_Multiply(__pyx_v_a1, __pyx_v_a1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 895, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyNumber_Multiply(__pyx_mstate_global->__pyx_float_3_0, __pyx_v_a2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 895, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Subtract(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 895, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_2, __pyx_mstate_global->__pyx_float_9_0, 9.0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 895, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_Q = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":896 + * + * Q = (a1 * a1 - 3.0 * a2) / 9.0 + * R = (2.0 * a1 * a1 * a1 - 9.0 * a1 * a2 + 27.0 * a3) / 54.0 # <<<<<<<<<<<<<< + * + * R2 = R * R +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_mstate_global->__pyx_float_2_0, __pyx_v_a1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 896, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_v_a1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 896, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_v_a1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 896, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_mstate_global->__pyx_float_9_0, __pyx_v_a1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 896, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_2, __pyx_v_a2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 896, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 896, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Multiply(__pyx_mstate_global->__pyx_float_27_0, __pyx_v_a3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 896, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 896, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_1, __pyx_mstate_global->__pyx_float_54_0, 54.0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 896, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_R = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":898 + * R = (2.0 * a1 * a1 * a1 - 9.0 * a1 * a2 + 27.0 * a3) / 54.0 + * + * R2 = R * R # <<<<<<<<<<<<<< + * Q3 = Q * Q * Q + * R2 = 0 if R2 < epsilon else R2 +*/ + __pyx_t_3 = PyNumber_Multiply(__pyx_v_R, __pyx_v_R); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 898, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_R2 = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":899 + * + * R2 = R * R + * Q3 = Q * Q * Q # <<<<<<<<<<<<<< + * R2 = 0 if R2 < epsilon else R2 + * Q3 = 0 if abs(Q3) < epsilon else Q3 +*/ + __pyx_t_3 = PyNumber_Multiply(__pyx_v_Q, __pyx_v_Q); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 899, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_3, __pyx_v_Q); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 899, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_Q3 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":900 + * R2 = R * R + * Q3 = Q * Q * Q + * R2 = 0 if R2 < epsilon else R2 # <<<<<<<<<<<<<< + * Q3 = 0 if abs(Q3) < epsilon else Q3 + * +*/ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_epsilon); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 900, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyObject_RichCompare(__pyx_v_R2, __pyx_t_3, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 900, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 900, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__pyx_t_4) { + __Pyx_INCREF(__pyx_mstate_global->__pyx_int_0); + __pyx_t_1 = __pyx_mstate_global->__pyx_int_0; + } else { + __Pyx_INCREF(__pyx_v_R2); + __pyx_t_1 = __pyx_v_R2; + } + __Pyx_DECREF_SET(__pyx_v_R2, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":901 + * Q3 = Q * Q * Q + * R2 = 0 if R2 < epsilon else R2 + * Q3 = 0 if abs(Q3) < epsilon else Q3 # <<<<<<<<<<<<<< + * + * R2_Q3 = R2 - Q3 +*/ + __pyx_t_2 = __Pyx_PyNumber_Absolute(__pyx_v_Q3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 901, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_epsilon); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 901, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = PyObject_RichCompare(__pyx_t_2, __pyx_t_3, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 901, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 901, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (__pyx_t_4) { + __Pyx_INCREF(__pyx_mstate_global->__pyx_int_0); + __pyx_t_1 = __pyx_mstate_global->__pyx_int_0; + } else { + __Pyx_INCREF(__pyx_v_Q3); + __pyx_t_1 = __pyx_v_Q3; + } + __Pyx_DECREF_SET(__pyx_v_Q3, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":903 + * Q3 = 0 if abs(Q3) < epsilon else Q3 + * + * R2_Q3 = R2 - Q3 # <<<<<<<<<<<<<< + * + * if R2 == 0.0 and Q3 == 0.0: +*/ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_R2, __pyx_v_Q3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 903, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_R2_Q3 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":905 + * R2_Q3 = R2 - Q3 + * + * if R2 == 0.0 and Q3 == 0.0: # <<<<<<<<<<<<<< + * x = round(-a1 / 3.0, epsilonDigits) + * return [x, x, x] +*/ + __pyx_t_7 = (__Pyx_PyFloat_BoolEqObjC(__pyx_v_R2, __pyx_mstate_global->__pyx_float_0_0, 0.0, 0, 0)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 905, __pyx_L1_error) + if (__pyx_t_7) { + } else { + __pyx_t_4 = __pyx_t_7; + goto __pyx_L5_bool_binop_done; + } + __pyx_t_7 = (__Pyx_PyFloat_BoolEqObjC(__pyx_v_Q3, __pyx_mstate_global->__pyx_float_0_0, 0.0, 0, 0)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 905, __pyx_L1_error) + __pyx_t_4 = __pyx_t_7; + __pyx_L5_bool_binop_done:; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":906 + * + * if R2 == 0.0 and Q3 == 0.0: + * x = round(-a1 / 3.0, epsilonDigits) # <<<<<<<<<<<<<< + * return [x, x, x] + * elif R2_Q3 <= epsilon * 0.5: +*/ + __pyx_t_6 = NULL; + __pyx_t_3 = PyNumber_Negative(__pyx_v_a1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 906, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_3, __pyx_mstate_global->__pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 906, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_epsilonDigits); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 906, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_6, __pyx_t_2, __pyx_t_3}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_builtin_round, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 906, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_v_x = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":907 + * if R2 == 0.0 and Q3 == 0.0: + * x = round(-a1 / 3.0, epsilonDigits) + * return [x, x, x] # <<<<<<<<<<<<<< + * elif R2_Q3 <= epsilon * 0.5: + * # The epsilon * .5 above ensures that Q3 is not zero. +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyList_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 907, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_v_x) != (0)) __PYX_ERR(0, 907, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 1, __pyx_v_x) != (0)) __PYX_ERR(0, 907, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 2, __pyx_v_x) != (0)) __PYX_ERR(0, 907, __pyx_L1_error); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":905 + * R2_Q3 = R2 - Q3 + * + * if R2 == 0.0 and Q3 == 0.0: # <<<<<<<<<<<<<< + * x = round(-a1 / 3.0, epsilonDigits) + * return [x, x, x] +*/ + } + + /* "fontTools/misc/bezierTools.py":908 + * x = round(-a1 / 3.0, epsilonDigits) + * return [x, x, x] + * elif R2_Q3 <= epsilon * 0.5: # <<<<<<<<<<<<<< + * # The epsilon * .5 above ensures that Q3 is not zero. + * theta = acos(max(min(R / sqrt(Q3), 1.0), -1.0)) +*/ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_epsilon); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 908, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_mstate_global->__pyx_float_0_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 908, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyObject_RichCompare(__pyx_v_R2_Q3, __pyx_t_3, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 908, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 908, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":910 + * elif R2_Q3 <= epsilon * 0.5: + * # The epsilon * .5 above ensures that Q3 is not zero. + * theta = acos(max(min(R / sqrt(Q3), 1.0), -1.0)) # <<<<<<<<<<<<<< + * rQ2 = -2.0 * sqrt(Q) + * a1_3 = a1 / 3.0 +*/ + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_acos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 910, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_8 = -1.0; + __pyx_t_9 = 1.0; + __pyx_t_10 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_mstate_global->__pyx_n_u_sqrt); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 910, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_11))) { + __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_11); + assert(__pyx_t_10); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_11); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_11, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_10, __pyx_v_Q3}; + __pyx_t_6 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_11, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 910, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + __pyx_t_11 = __Pyx_PyNumber_Divide(__pyx_v_R, __pyx_t_6); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 910, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_10 = PyFloat_FromDouble(__pyx_t_9); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 910, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_12 = PyObject_RichCompare(__pyx_t_10, __pyx_t_11, Py_LT); __Pyx_XGOTREF(__pyx_t_12); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 910, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_12); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 910, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + if (__pyx_t_4) { + __pyx_t_12 = PyFloat_FromDouble(__pyx_t_9); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 910, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __pyx_t_6 = __pyx_t_12; + __pyx_t_12 = 0; + } else { + __Pyx_INCREF(__pyx_t_11); + __pyx_t_6 = __pyx_t_11; + } + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_INCREF(__pyx_t_6); + __pyx_t_11 = __pyx_t_6; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_12 = PyFloat_FromDouble(__pyx_t_8); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 910, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __pyx_t_10 = PyObject_RichCompare(__pyx_t_12, __pyx_t_11, Py_GT); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 910, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 910, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (__pyx_t_4) { + __pyx_t_10 = PyFloat_FromDouble(__pyx_t_8); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 910, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_6 = __pyx_t_10; + __pyx_t_10 = 0; + } else { + __Pyx_INCREF(__pyx_t_11); + __pyx_t_6 = __pyx_t_11; + } + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_3); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_t_6}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 910, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_v_theta = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":911 + * # The epsilon * .5 above ensures that Q3 is not zero. + * theta = acos(max(min(R / sqrt(Q3), 1.0), -1.0)) + * rQ2 = -2.0 * sqrt(Q) # <<<<<<<<<<<<<< + * a1_3 = a1 / 3.0 + * x0 = rQ2 * cos(theta / 3.0) - a1_3 +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_sqrt); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 911, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_6); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_6, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_v_Q}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_6, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 911, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_6 = PyNumber_Multiply(__pyx_mstate_global->__pyx_float_neg_2_0, __pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 911, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_rQ2 = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":912 + * theta = acos(max(min(R / sqrt(Q3), 1.0), -1.0)) + * rQ2 = -2.0 * sqrt(Q) + * a1_3 = a1 / 3.0 # <<<<<<<<<<<<<< + * x0 = rQ2 * cos(theta / 3.0) - a1_3 + * x1 = rQ2 * cos((theta + 2.0 * pi) / 3.0) - a1_3 +*/ + __pyx_t_6 = __Pyx_PyFloat_TrueDivideObjC(__pyx_v_a1, __pyx_mstate_global->__pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 912, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_v_a1_3 = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":913 + * rQ2 = -2.0 * sqrt(Q) + * a1_3 = a1 / 3.0 + * x0 = rQ2 * cos(theta / 3.0) - a1_3 # <<<<<<<<<<<<<< + * x1 = rQ2 * cos((theta + 2.0 * pi) / 3.0) - a1_3 + * x2 = rQ2 * cos((theta + 4.0 * pi) / 3.0) - a1_3 +*/ + __pyx_t_1 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_cos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 913, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyFloat_TrueDivideObjC(__pyx_v_theta, __pyx_mstate_global->__pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 913, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_1); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_t_3}; + __pyx_t_6 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 913, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + __pyx_t_2 = PyNumber_Multiply(__pyx_v_rQ2, __pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 913, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyNumber_Subtract(__pyx_t_2, __pyx_v_a1_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 913, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_x0 = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":914 + * a1_3 = a1 / 3.0 + * x0 = rQ2 * cos(theta / 3.0) - a1_3 + * x1 = rQ2 * cos((theta + 2.0 * pi) / 3.0) - a1_3 # <<<<<<<<<<<<<< + * x2 = rQ2 * cos((theta + 4.0 * pi) / 3.0) - a1_3 + * x0, x1, x2 = sorted([x0, x1, x2]) +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_cos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 914, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_pi); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 914, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_11 = PyNumber_Multiply(__pyx_mstate_global->__pyx_float_2_0, __pyx_t_1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 914, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_v_theta, __pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 914, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __pyx_t_11 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_1, __pyx_mstate_global->__pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 914, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_t_11}; + __pyx_t_6 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 914, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + __pyx_t_3 = PyNumber_Multiply(__pyx_v_rQ2, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 914, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyNumber_Subtract(__pyx_t_3, __pyx_v_a1_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 914, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_x1 = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":915 + * x0 = rQ2 * cos(theta / 3.0) - a1_3 + * x1 = rQ2 * cos((theta + 2.0 * pi) / 3.0) - a1_3 + * x2 = rQ2 * cos((theta + 4.0 * pi) / 3.0) - a1_3 # <<<<<<<<<<<<<< + * x0, x1, x2 = sorted([x0, x1, x2]) + * # Merge roots that are close-enough +*/ + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_mstate_global->__pyx_n_u_cos); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 915, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_pi); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 915, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_mstate_global->__pyx_float_4_0, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 915, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_v_theta, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 915, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_2, __pyx_mstate_global->__pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 915, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_11))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_11); + assert(__pyx_t_3); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_11); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_11, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_t_1}; + __pyx_t_6 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_11, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 915, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + __pyx_t_11 = PyNumber_Multiply(__pyx_v_rQ2, __pyx_t_6); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 915, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyNumber_Subtract(__pyx_t_11, __pyx_v_a1_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 915, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __pyx_v_x2 = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":916 + * x1 = rQ2 * cos((theta + 2.0 * pi) / 3.0) - a1_3 + * x2 = rQ2 * cos((theta + 4.0 * pi) / 3.0) - a1_3 + * x0, x1, x2 = sorted([x0, x1, x2]) # <<<<<<<<<<<<<< + * # Merge roots that are close-enough + * if x1 - x0 < epsilon and x2 - x1 < epsilon: +*/ + __pyx_t_6 = PyList_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 916, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_INCREF(__pyx_v_x0); + __Pyx_GIVEREF(__pyx_v_x0); + if (__Pyx_PyList_SET_ITEM(__pyx_t_6, 0, __pyx_v_x0) != (0)) __PYX_ERR(0, 916, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_x1); + __Pyx_GIVEREF(__pyx_v_x1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_6, 1, __pyx_v_x1) != (0)) __PYX_ERR(0, 916, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_x2); + __Pyx_GIVEREF(__pyx_v_x2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_6, 2, __pyx_v_x2) != (0)) __PYX_ERR(0, 916, __pyx_L1_error); + if (unlikely((PyList_Sort(__pyx_t_6) < 0))) __PYX_ERR(0, 916, __pyx_L1_error) + if (1) { + PyObject* sequence = __pyx_t_6; + Py_ssize_t size = __Pyx_PyList_GET_SIZE(sequence); + if (unlikely(size != 3)) { + if (size > 3) __Pyx_RaiseTooManyValuesError(3); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 916, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_11 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 916, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_11); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 916, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyList_GetItemRefFast(sequence, 2, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 916, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_3); + #else + __pyx_t_11 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 916, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 916, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 916, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } + __Pyx_DECREF_SET(__pyx_v_x0, __pyx_t_11); + __pyx_t_11 = 0; + __Pyx_DECREF_SET(__pyx_v_x1, __pyx_t_1); + __pyx_t_1 = 0; + __Pyx_DECREF_SET(__pyx_v_x2, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":918 + * x0, x1, x2 = sorted([x0, x1, x2]) + * # Merge roots that are close-enough + * if x1 - x0 < epsilon and x2 - x1 < epsilon: # <<<<<<<<<<<<<< + * x0 = x1 = x2 = round((x0 + x1 + x2) / 3.0, epsilonDigits) + * elif x1 - x0 < epsilon: +*/ + __pyx_t_6 = PyNumber_Subtract(__pyx_v_x1, __pyx_v_x0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 918, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_epsilon); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 918, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyObject_RichCompare(__pyx_t_6, __pyx_t_3, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 918, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 918, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_7) { + } else { + __pyx_t_4 = __pyx_t_7; + goto __pyx_L8_bool_binop_done; + } + __pyx_t_1 = PyNumber_Subtract(__pyx_v_x2, __pyx_v_x1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 918, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_epsilon); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 918, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = PyObject_RichCompare(__pyx_t_1, __pyx_t_3, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 918, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 918, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_4 = __pyx_t_7; + __pyx_L8_bool_binop_done:; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":919 + * # Merge roots that are close-enough + * if x1 - x0 < epsilon and x2 - x1 < epsilon: + * x0 = x1 = x2 = round((x0 + x1 + x2) / 3.0, epsilonDigits) # <<<<<<<<<<<<<< + * elif x1 - x0 < epsilon: + * x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits) +*/ + __pyx_t_3 = NULL; + __pyx_t_1 = PyNumber_Add(__pyx_v_x0, __pyx_v_x1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 919, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_11 = PyNumber_Add(__pyx_t_1, __pyx_v_x2); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 919, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_11, __pyx_mstate_global->__pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 919, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_mstate_global->__pyx_n_u_epsilonDigits); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 919, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_t_1, __pyx_t_11}; + __pyx_t_6 = __Pyx_PyObject_FastCall((PyObject*)__pyx_builtin_round, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 919, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + __Pyx_INCREF(__pyx_t_6); + __Pyx_DECREF_SET(__pyx_v_x0, __pyx_t_6); + __Pyx_INCREF(__pyx_t_6); + __Pyx_DECREF_SET(__pyx_v_x1, __pyx_t_6); + __Pyx_INCREF(__pyx_t_6); + __Pyx_DECREF_SET(__pyx_v_x2, __pyx_t_6); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":918 + * x0, x1, x2 = sorted([x0, x1, x2]) + * # Merge roots that are close-enough + * if x1 - x0 < epsilon and x2 - x1 < epsilon: # <<<<<<<<<<<<<< + * x0 = x1 = x2 = round((x0 + x1 + x2) / 3.0, epsilonDigits) + * elif x1 - x0 < epsilon: +*/ + goto __pyx_L7; + } + + /* "fontTools/misc/bezierTools.py":920 + * if x1 - x0 < epsilon and x2 - x1 < epsilon: + * x0 = x1 = x2 = round((x0 + x1 + x2) / 3.0, epsilonDigits) + * elif x1 - x0 < epsilon: # <<<<<<<<<<<<<< + * x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits) + * x2 = round(x2, epsilonDigits) +*/ + __pyx_t_6 = PyNumber_Subtract(__pyx_v_x1, __pyx_v_x0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 920, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_mstate_global->__pyx_n_u_epsilon); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 920, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_1 = PyObject_RichCompare(__pyx_t_6, __pyx_t_11, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 920, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 920, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":921 + * x0 = x1 = x2 = round((x0 + x1 + x2) / 3.0, epsilonDigits) + * elif x1 - x0 < epsilon: + * x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits) # <<<<<<<<<<<<<< + * x2 = round(x2, epsilonDigits) + * elif x2 - x1 < epsilon: +*/ + __pyx_t_11 = NULL; + __pyx_t_6 = PyNumber_Add(__pyx_v_x0, __pyx_v_x1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 921, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_6, __pyx_mstate_global->__pyx_float_2_0, 2.0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 921, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_epsilonDigits); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 921, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_11, __pyx_t_3, __pyx_t_6}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_builtin_round, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 921, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_DECREF_SET(__pyx_v_x0, __pyx_t_1); + __Pyx_INCREF(__pyx_t_1); + __Pyx_DECREF_SET(__pyx_v_x1, __pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":922 + * elif x1 - x0 < epsilon: + * x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits) + * x2 = round(x2, epsilonDigits) # <<<<<<<<<<<<<< + * elif x2 - x1 < epsilon: + * x0 = round(x0, epsilonDigits) +*/ + __pyx_t_6 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_epsilonDigits); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 922, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_6, __pyx_v_x2, __pyx_t_3}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_builtin_round, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 922, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __Pyx_DECREF_SET(__pyx_v_x2, __pyx_t_1); + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":920 + * if x1 - x0 < epsilon and x2 - x1 < epsilon: + * x0 = x1 = x2 = round((x0 + x1 + x2) / 3.0, epsilonDigits) + * elif x1 - x0 < epsilon: # <<<<<<<<<<<<<< + * x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits) + * x2 = round(x2, epsilonDigits) +*/ + goto __pyx_L7; + } + + /* "fontTools/misc/bezierTools.py":923 + * x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits) + * x2 = round(x2, epsilonDigits) + * elif x2 - x1 < epsilon: # <<<<<<<<<<<<<< + * x0 = round(x0, epsilonDigits) + * x1 = x2 = round((x1 + x2) / 2.0, epsilonDigits) +*/ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_x2, __pyx_v_x1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 923, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_epsilon); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 923, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = PyObject_RichCompare(__pyx_t_1, __pyx_t_3, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 923, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 923, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":924 + * x2 = round(x2, epsilonDigits) + * elif x2 - x1 < epsilon: + * x0 = round(x0, epsilonDigits) # <<<<<<<<<<<<<< + * x1 = x2 = round((x1 + x2) / 2.0, epsilonDigits) + * else: +*/ + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_epsilonDigits); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 924, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_v_x0, __pyx_t_1}; + __pyx_t_6 = __Pyx_PyObject_FastCall((PyObject*)__pyx_builtin_round, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 924, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + __Pyx_DECREF_SET(__pyx_v_x0, __pyx_t_6); + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":925 + * elif x2 - x1 < epsilon: + * x0 = round(x0, epsilonDigits) + * x1 = x2 = round((x1 + x2) / 2.0, epsilonDigits) # <<<<<<<<<<<<<< + * else: + * x0 = round(x0, epsilonDigits) +*/ + __pyx_t_1 = NULL; + __pyx_t_3 = PyNumber_Add(__pyx_v_x1, __pyx_v_x2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 925, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_11 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_3, __pyx_mstate_global->__pyx_float_2_0, 2.0, 0, 0); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 925, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_epsilonDigits); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 925, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_1, __pyx_t_11, __pyx_t_3}; + __pyx_t_6 = __Pyx_PyObject_FastCall((PyObject*)__pyx_builtin_round, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 925, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + __Pyx_INCREF(__pyx_t_6); + __Pyx_DECREF_SET(__pyx_v_x1, __pyx_t_6); + __Pyx_INCREF(__pyx_t_6); + __Pyx_DECREF_SET(__pyx_v_x2, __pyx_t_6); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":923 + * x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits) + * x2 = round(x2, epsilonDigits) + * elif x2 - x1 < epsilon: # <<<<<<<<<<<<<< + * x0 = round(x0, epsilonDigits) + * x1 = x2 = round((x1 + x2) / 2.0, epsilonDigits) +*/ + goto __pyx_L7; + } + + /* "fontTools/misc/bezierTools.py":927 + * x1 = x2 = round((x1 + x2) / 2.0, epsilonDigits) + * else: + * x0 = round(x0, epsilonDigits) # <<<<<<<<<<<<<< + * x1 = round(x1, epsilonDigits) + * x2 = round(x2, epsilonDigits) +*/ + /*else*/ { + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_mstate_global->__pyx_n_u_epsilonDigits); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 927, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_v_x0, __pyx_t_11}; + __pyx_t_6 = __Pyx_PyObject_FastCall((PyObject*)__pyx_builtin_round, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 927, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + __Pyx_DECREF_SET(__pyx_v_x0, __pyx_t_6); + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":928 + * else: + * x0 = round(x0, epsilonDigits) + * x1 = round(x1, epsilonDigits) # <<<<<<<<<<<<<< + * x2 = round(x2, epsilonDigits) + * return [x0, x1, x2] +*/ + __pyx_t_11 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_epsilonDigits); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 928, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_11, __pyx_v_x1, __pyx_t_3}; + __pyx_t_6 = __Pyx_PyObject_FastCall((PyObject*)__pyx_builtin_round, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 928, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + __Pyx_DECREF_SET(__pyx_v_x1, __pyx_t_6); + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":929 + * x0 = round(x0, epsilonDigits) + * x1 = round(x1, epsilonDigits) + * x2 = round(x2, epsilonDigits) # <<<<<<<<<<<<<< + * return [x0, x1, x2] + * else: +*/ + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_mstate_global->__pyx_n_u_epsilonDigits); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 929, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_v_x2, __pyx_t_11}; + __pyx_t_6 = __Pyx_PyObject_FastCall((PyObject*)__pyx_builtin_round, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 929, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + __Pyx_DECREF_SET(__pyx_v_x2, __pyx_t_6); + __pyx_t_6 = 0; + } + __pyx_L7:; + + /* "fontTools/misc/bezierTools.py":930 + * x1 = round(x1, epsilonDigits) + * x2 = round(x2, epsilonDigits) + * return [x0, x1, x2] # <<<<<<<<<<<<<< + * else: + * x = pow(sqrt(R2_Q3) + abs(R), 1 / 3.0) +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_6 = PyList_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 930, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_INCREF(__pyx_v_x0); + __Pyx_GIVEREF(__pyx_v_x0); + if (__Pyx_PyList_SET_ITEM(__pyx_t_6, 0, __pyx_v_x0) != (0)) __PYX_ERR(0, 930, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_x1); + __Pyx_GIVEREF(__pyx_v_x1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_6, 1, __pyx_v_x1) != (0)) __PYX_ERR(0, 930, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_x2); + __Pyx_GIVEREF(__pyx_v_x2); + if (__Pyx_PyList_SET_ITEM(__pyx_t_6, 2, __pyx_v_x2) != (0)) __PYX_ERR(0, 930, __pyx_L1_error); + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":908 + * x = round(-a1 / 3.0, epsilonDigits) + * return [x, x, x] + * elif R2_Q3 <= epsilon * 0.5: # <<<<<<<<<<<<<< + * # The epsilon * .5 above ensures that Q3 is not zero. + * theta = acos(max(min(R / sqrt(Q3), 1.0), -1.0)) +*/ + } + + /* "fontTools/misc/bezierTools.py":932 + * return [x0, x1, x2] + * else: + * x = pow(sqrt(R2_Q3) + abs(R), 1 / 3.0) # <<<<<<<<<<<<<< + * x = x + Q / x + * if R >= 0.0: +*/ + /*else*/ { + __pyx_t_11 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_sqrt); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 932, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_11); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_11); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_11, __pyx_v_R2_Q3}; + __pyx_t_6 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 932, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + __pyx_t_3 = __Pyx_PyNumber_Absolute(__pyx_v_R); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 932, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_11 = PyNumber_Add(__pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 932, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyFloat_FromDouble((1.0 / 3.0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 932, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = __Pyx_PyNumber_Power2(__pyx_t_11, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 932, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_x = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":933 + * else: + * x = pow(sqrt(R2_Q3) + abs(R), 1 / 3.0) + * x = x + Q / x # <<<<<<<<<<<<<< + * if R >= 0.0: + * x = -x +*/ + __pyx_t_6 = __Pyx_PyNumber_Divide(__pyx_v_Q, __pyx_v_x); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 933, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = PyNumber_Add(__pyx_v_x, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 933, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF_SET(__pyx_v_x, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":934 + * x = pow(sqrt(R2_Q3) + abs(R), 1 / 3.0) + * x = x + Q / x + * if R >= 0.0: # <<<<<<<<<<<<<< + * x = -x + * x = round(x - a1 / 3.0, epsilonDigits) +*/ + __pyx_t_3 = PyObject_RichCompare(__pyx_v_R, __pyx_mstate_global->__pyx_float_0_0, Py_GE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 934, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 934, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_4) { + + /* "fontTools/misc/bezierTools.py":935 + * x = x + Q / x + * if R >= 0.0: + * x = -x # <<<<<<<<<<<<<< + * x = round(x - a1 / 3.0, epsilonDigits) + * return [x] +*/ + __pyx_t_3 = PyNumber_Negative(__pyx_v_x); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 935, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF_SET(__pyx_v_x, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":934 + * x = pow(sqrt(R2_Q3) + abs(R), 1 / 3.0) + * x = x + Q / x + * if R >= 0.0: # <<<<<<<<<<<<<< + * x = -x + * x = round(x - a1 / 3.0, epsilonDigits) +*/ + } + + /* "fontTools/misc/bezierTools.py":936 + * if R >= 0.0: + * x = -x + * x = round(x - a1 / 3.0, epsilonDigits) # <<<<<<<<<<<<<< + * return [x] + * +*/ + __pyx_t_6 = NULL; + __pyx_t_11 = __Pyx_PyFloat_TrueDivideObjC(__pyx_v_a1, __pyx_mstate_global->__pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 936, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_1 = PyNumber_Subtract(__pyx_v_x, __pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 936, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_mstate_global->__pyx_n_u_epsilonDigits); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 936, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_6, __pyx_t_1, __pyx_t_11}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_builtin_round, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 936, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __Pyx_DECREF_SET(__pyx_v_x, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":937 + * x = -x + * x = round(x - a1 / 3.0, epsilonDigits) + * return [x] # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 937, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 0, __pyx_v_x) != (0)) __PYX_ERR(0, 937, __pyx_L1_error); + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + } + + /* "fontTools/misc/bezierTools.py":848 + * + * + * def solveCubic(a, b, c, d): # <<<<<<<<<<<<<< + * """Solve a cubic equation. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_AddTraceback("fontTools.misc.bezierTools.solveCubic", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_a1); + __Pyx_XDECREF(__pyx_v_a2); + __Pyx_XDECREF(__pyx_v_a3); + __Pyx_XDECREF(__pyx_v_Q); + __Pyx_XDECREF(__pyx_v_R); + __Pyx_XDECREF(__pyx_v_R2); + __Pyx_XDECREF(__pyx_v_Q3); + __Pyx_XDECREF(__pyx_v_R2_Q3); + __Pyx_XDECREF(__pyx_v_x); + __Pyx_XDECREF(__pyx_v_theta); + __Pyx_XDECREF(__pyx_v_rQ2); + __Pyx_XDECREF(__pyx_v_a1_3); + __Pyx_XDECREF(__pyx_v_x0); + __Pyx_XDECREF(__pyx_v_x1); + __Pyx_XDECREF(__pyx_v_x2); + __Pyx_XDECREF(__pyx_v_a); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":945 + * + * + * def calcQuadraticParameters(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * x2, y2 = pt2 + * x3, y3 = pt3 +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_51calcQuadraticParameters(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_50calcQuadraticParameters, "calcQuadraticParameters(pt1, pt2, pt3)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_51calcQuadraticParameters = {"calcQuadraticParameters", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_51calcQuadraticParameters, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_50calcQuadraticParameters}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_51calcQuadraticParameters(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcQuadraticParameters (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 945, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 945, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 945, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 945, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "calcQuadraticParameters", 0) < (0)) __PYX_ERR(0, 945, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 3; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("calcQuadraticParameters", 1, 3, 3, i); __PYX_ERR(0, 945, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 945, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 945, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 945, __pyx_L3_error) + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcQuadraticParameters", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 945, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticParameters", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_50calcQuadraticParameters(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_50calcQuadraticParameters(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3) { + PyObject *__pyx_v_x2 = NULL; + PyObject *__pyx_v_y2 = NULL; + PyObject *__pyx_v_x3 = NULL; + PyObject *__pyx_v_y3 = NULL; + PyObject *__pyx_v_cx = NULL; + PyObject *__pyx_v_cy = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *(*__pyx_t_4)(PyObject *); + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcQuadraticParameters", 0); + + /* "fontTools/misc/bezierTools.py":946 + * + * def calcQuadraticParameters(pt1, pt2, pt3): + * x2, y2 = pt2 # <<<<<<<<<<<<<< + * x3, y3 = pt3 + * cx, cy = pt1 +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_pt2))) || (PyList_CheckExact(__pyx_v_pt2))) { + PyObject* sequence = __pyx_v_pt2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 946, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 946, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 946, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 946, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 946, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 946, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 946, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 946, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_x2 = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_y2 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":947 + * def calcQuadraticParameters(pt1, pt2, pt3): + * x2, y2 = pt2 + * x3, y3 = pt3 # <<<<<<<<<<<<<< + * cx, cy = pt1 + * bx = (x2 - cx) * 2.0 +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_pt3))) || (PyList_CheckExact(__pyx_v_pt3))) { + PyObject* sequence = __pyx_v_pt3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 947, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 947, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 947, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 947, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 947, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 947, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 947, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 947, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_x3 = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_y3 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":948 + * x2, y2 = pt2 + * x3, y3 = pt3 + * cx, cy = pt1 # <<<<<<<<<<<<<< + * bx = (x2 - cx) * 2.0 + * by = (y2 - cy) * 2.0 +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_pt1))) || (PyList_CheckExact(__pyx_v_pt1))) { + PyObject* sequence = __pyx_v_pt1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 948, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 948, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 948, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 948, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 948, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 948, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 948, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 948, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_cx = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_cy = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":949 + * x3, y3 = pt3 + * cx, cy = pt1 + * bx = (x2 - cx) * 2.0 # <<<<<<<<<<<<<< + * by = (y2 - cy) * 2.0 + * ax = x3 - cx - bx +*/ + __pyx_t_2 = PyNumber_Subtract(__pyx_v_x2, __pyx_v_cx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 949, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_mstate_global->__pyx_float_2_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 949, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_bx = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":950 + * cx, cy = pt1 + * bx = (x2 - cx) * 2.0 + * by = (y2 - cy) * 2.0 # <<<<<<<<<<<<<< + * ax = x3 - cx - bx + * ay = y3 - cy - by +*/ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_y2, __pyx_v_cy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 950, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_mstate_global->__pyx_float_2_0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 950, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_by = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":951 + * bx = (x2 - cx) * 2.0 + * by = (y2 - cy) * 2.0 + * ax = x3 - cx - bx # <<<<<<<<<<<<<< + * ay = y3 - cy - by + * return (ax, ay), (bx, by), (cx, cy) +*/ + __pyx_t_2 = PyNumber_Subtract(__pyx_v_x3, __pyx_v_cx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 951, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_bx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 951, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_ax = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":952 + * by = (y2 - cy) * 2.0 + * ax = x3 - cx - bx + * ay = y3 - cy - by # <<<<<<<<<<<<<< + * return (ax, ay), (bx, by), (cx, cy) + * +*/ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_y3, __pyx_v_cy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 952, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_v_by); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 952, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_ay = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":953 + * ax = x3 - cx - bx + * ay = y3 - cy - by + * return (ax, ay), (bx, by), (cx, cy) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 953, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_ax); + __Pyx_GIVEREF(__pyx_v_ax); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_ax) != (0)) __PYX_ERR(0, 953, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_ay); + __Pyx_GIVEREF(__pyx_v_ay); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_ay) != (0)) __PYX_ERR(0, 953, __pyx_L1_error); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 953, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_bx); + __Pyx_GIVEREF(__pyx_v_bx); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_bx) != (0)) __PYX_ERR(0, 953, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_by); + __Pyx_GIVEREF(__pyx_v_by); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_by) != (0)) __PYX_ERR(0, 953, __pyx_L1_error); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 953, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_cx); + __Pyx_GIVEREF(__pyx_v_cx); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_cx) != (0)) __PYX_ERR(0, 953, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_cy); + __Pyx_GIVEREF(__pyx_v_cy); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_cy) != (0)) __PYX_ERR(0, 953, __pyx_L1_error); + __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 953, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2) != (0)) __PYX_ERR(0, 953, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_1) != (0)) __PYX_ERR(0, 953, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3) != (0)) __PYX_ERR(0, 953, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":945 + * + * + * def calcQuadraticParameters(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * x2, y2 = pt2 + * x3, y3 = pt3 +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticParameters", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_x2); + __Pyx_XDECREF(__pyx_v_y2); + __Pyx_XDECREF(__pyx_v_x3); + __Pyx_XDECREF(__pyx_v_y3); + __Pyx_XDECREF(__pyx_v_cx); + __Pyx_XDECREF(__pyx_v_cy); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":956 + * + * + * def calcCubicParameters(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * x2, y2 = pt2 + * x3, y3 = pt3 +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_53calcCubicParameters(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_52calcCubicParameters, "calcCubicParameters(pt1, pt2, pt3, pt4)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_53calcCubicParameters = {"calcCubicParameters", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_53calcCubicParameters, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_52calcCubicParameters}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_53calcCubicParameters(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_pt4 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcCubicParameters (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,&__pyx_mstate_global->__pyx_n_u_pt4,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 956, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 956, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 956, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 956, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 956, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "calcCubicParameters", 0) < (0)) __PYX_ERR(0, 956, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("calcCubicParameters", 1, 4, 4, i); __PYX_ERR(0, 956, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 956, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 956, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 956, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 956, __pyx_L3_error) + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_pt4 = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcCubicParameters", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 956, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicParameters", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_52calcCubicParameters(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_52calcCubicParameters(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4) { + PyObject *__pyx_v_x2 = NULL; + PyObject *__pyx_v_y2 = NULL; + PyObject *__pyx_v_x3 = NULL; + PyObject *__pyx_v_y3 = NULL; + PyObject *__pyx_v_x4 = NULL; + PyObject *__pyx_v_y4 = NULL; + PyObject *__pyx_v_dx = NULL; + PyObject *__pyx_v_dy = NULL; + PyObject *__pyx_v_cx = NULL; + PyObject *__pyx_v_cy = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *(*__pyx_t_4)(PyObject *); + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcCubicParameters", 0); + + /* "fontTools/misc/bezierTools.py":957 + * + * def calcCubicParameters(pt1, pt2, pt3, pt4): + * x2, y2 = pt2 # <<<<<<<<<<<<<< + * x3, y3 = pt3 + * x4, y4 = pt4 +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_pt2))) || (PyList_CheckExact(__pyx_v_pt2))) { + PyObject* sequence = __pyx_v_pt2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 957, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 957, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 957, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 957, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 957, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 957, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 957, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 957, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_x2 = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_y2 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":958 + * def calcCubicParameters(pt1, pt2, pt3, pt4): + * x2, y2 = pt2 + * x3, y3 = pt3 # <<<<<<<<<<<<<< + * x4, y4 = pt4 + * dx, dy = pt1 +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_pt3))) || (PyList_CheckExact(__pyx_v_pt3))) { + PyObject* sequence = __pyx_v_pt3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 958, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 958, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 958, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 958, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 958, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 958, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 958, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 958, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_x3 = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_y3 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":959 + * x2, y2 = pt2 + * x3, y3 = pt3 + * x4, y4 = pt4 # <<<<<<<<<<<<<< + * dx, dy = pt1 + * cx = (x2 - dx) * 3.0 +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_pt4))) || (PyList_CheckExact(__pyx_v_pt4))) { + PyObject* sequence = __pyx_v_pt4; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 959, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 959, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 959, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 959, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 959, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 959, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 959, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 959, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_x4 = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_y4 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":960 + * x3, y3 = pt3 + * x4, y4 = pt4 + * dx, dy = pt1 # <<<<<<<<<<<<<< + * cx = (x2 - dx) * 3.0 + * cy = (y2 - dy) * 3.0 +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_pt1))) || (PyList_CheckExact(__pyx_v_pt1))) { + PyObject* sequence = __pyx_v_pt1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 960, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 960, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 960, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 960, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 960, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 960, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 960, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 960, __pyx_L1_error) + __pyx_L10_unpacking_done:; + } + __pyx_v_dx = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_dy = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":961 + * x4, y4 = pt4 + * dx, dy = pt1 + * cx = (x2 - dx) * 3.0 # <<<<<<<<<<<<<< + * cy = (y2 - dy) * 3.0 + * bx = (x3 - x2) * 3.0 - cx +*/ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_x2, __pyx_v_dx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 961, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_mstate_global->__pyx_float_3_0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 961, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_cx = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":962 + * dx, dy = pt1 + * cx = (x2 - dx) * 3.0 + * cy = (y2 - dy) * 3.0 # <<<<<<<<<<<<<< + * bx = (x3 - x2) * 3.0 - cx + * by = (y3 - y2) * 3.0 - cy +*/ + __pyx_t_2 = PyNumber_Subtract(__pyx_v_y2, __pyx_v_dy); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 962, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_mstate_global->__pyx_float_3_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 962, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_cy = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":963 + * cx = (x2 - dx) * 3.0 + * cy = (y2 - dy) * 3.0 + * bx = (x3 - x2) * 3.0 - cx # <<<<<<<<<<<<<< + * by = (y3 - y2) * 3.0 - cy + * ax = x4 - dx - cx - bx +*/ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_x3, __pyx_v_x2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 963, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_mstate_global->__pyx_float_3_0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 963, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_cx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 963, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_bx = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":964 + * cy = (y2 - dy) * 3.0 + * bx = (x3 - x2) * 3.0 - cx + * by = (y3 - y2) * 3.0 - cy # <<<<<<<<<<<<<< + * ax = x4 - dx - cx - bx + * ay = y4 - dy - cy - by +*/ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_y3, __pyx_v_y2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 964, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_mstate_global->__pyx_float_3_0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 964, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_cy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 964, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_by = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":965 + * bx = (x3 - x2) * 3.0 - cx + * by = (y3 - y2) * 3.0 - cy + * ax = x4 - dx - cx - bx # <<<<<<<<<<<<<< + * ay = y4 - dy - cy - by + * return (ax, ay), (bx, by), (cx, cy), (dx, dy) +*/ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_x4, __pyx_v_dx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 965, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_v_cx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 965, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_bx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 965, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_ax = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":966 + * by = (y3 - y2) * 3.0 - cy + * ax = x4 - dx - cx - bx + * ay = y4 - dy - cy - by # <<<<<<<<<<<<<< + * return (ax, ay), (bx, by), (cx, cy), (dx, dy) + * +*/ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_y4, __pyx_v_dy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 966, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Subtract(__pyx_t_1, __pyx_v_cy); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 966, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Subtract(__pyx_t_2, __pyx_v_by); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 966, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_ay = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":967 + * ax = x4 - dx - cx - bx + * ay = y4 - dy - cy - by + * return (ax, ay), (bx, by), (cx, cy), (dx, dy) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 967, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_ax); + __Pyx_GIVEREF(__pyx_v_ax); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_ax) != (0)) __PYX_ERR(0, 967, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_ay); + __Pyx_GIVEREF(__pyx_v_ay); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_ay) != (0)) __PYX_ERR(0, 967, __pyx_L1_error); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 967, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_bx); + __Pyx_GIVEREF(__pyx_v_bx); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_bx) != (0)) __PYX_ERR(0, 967, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_by); + __Pyx_GIVEREF(__pyx_v_by); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_by) != (0)) __PYX_ERR(0, 967, __pyx_L1_error); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 967, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_cx); + __Pyx_GIVEREF(__pyx_v_cx); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_cx) != (0)) __PYX_ERR(0, 967, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_cy); + __Pyx_GIVEREF(__pyx_v_cy); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_cy) != (0)) __PYX_ERR(0, 967, __pyx_L1_error); + __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 967, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_dx); + __Pyx_GIVEREF(__pyx_v_dx); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_dx) != (0)) __PYX_ERR(0, 967, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_dy); + __Pyx_GIVEREF(__pyx_v_dy); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_dy) != (0)) __PYX_ERR(0, 967, __pyx_L1_error); + __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 967, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 967, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_2) != (0)) __PYX_ERR(0, 967, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_3) != (0)) __PYX_ERR(0, 967, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_5) != (0)) __PYX_ERR(0, 967, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_t_5 = 0; + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":956 + * + * + * def calcCubicParameters(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * x2, y2 = pt2 + * x3, y3 = pt3 +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicParameters", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_x2); + __Pyx_XDECREF(__pyx_v_y2); + __Pyx_XDECREF(__pyx_v_x3); + __Pyx_XDECREF(__pyx_v_y3); + __Pyx_XDECREF(__pyx_v_x4); + __Pyx_XDECREF(__pyx_v_y4); + __Pyx_XDECREF(__pyx_v_dx); + __Pyx_XDECREF(__pyx_v_dy); + __Pyx_XDECREF(__pyx_v_cx); + __Pyx_XDECREF(__pyx_v_cy); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":970 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals( +*/ + +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_4misc_11bezierTools_calcCubicParametersC(__pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4) { + __pyx_t_double_complex __pyx_v_a; + __pyx_t_double_complex __pyx_v_b; + __pyx_t_double_complex __pyx_v_c; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcCubicParametersC", 0); + + /* "fontTools/misc/bezierTools.py":982 + * ) + * def calcCubicParametersC(pt1, pt2, pt3, pt4): + * c = (pt2 - pt1) * 3.0 # <<<<<<<<<<<<<< + * b = (pt3 - pt2) * 3.0 - c + * a = pt4 - pt1 - c - b +*/ + __pyx_v_c = __Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_pt2, __pyx_v_pt1), __pyx_t_double_complex_from_parts(3.0, 0)); + + /* "fontTools/misc/bezierTools.py":983 + * def calcCubicParametersC(pt1, pt2, pt3, pt4): + * c = (pt2 - pt1) * 3.0 + * b = (pt3 - pt2) * 3.0 - c # <<<<<<<<<<<<<< + * a = pt4 - pt1 - c - b + * return (a, b, c, pt1) +*/ + __pyx_v_b = __Pyx_c_diff_double(__Pyx_c_prod_double(__Pyx_c_diff_double(__pyx_v_pt3, __pyx_v_pt2), __pyx_t_double_complex_from_parts(3.0, 0)), __pyx_v_c); + + /* "fontTools/misc/bezierTools.py":984 + * c = (pt2 - pt1) * 3.0 + * b = (pt3 - pt2) * 3.0 - c + * a = pt4 - pt1 - c - b # <<<<<<<<<<<<<< + * return (a, b, c, pt1) + * +*/ + __pyx_v_a = __Pyx_c_diff_double(__Pyx_c_diff_double(__Pyx_c_diff_double(__pyx_v_pt4, __pyx_v_pt1), __pyx_v_c), __pyx_v_b); + + /* "fontTools/misc/bezierTools.py":985 + * b = (pt3 - pt2) * 3.0 - c + * a = pt4 - pt1 - c - b + * return (a, b, c, pt1) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_a); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 985, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __pyx_PyComplex_FromComplex(__pyx_v_b); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 985, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __pyx_PyComplex_FromComplex(__pyx_v_c); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 985, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_v_pt1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 985, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 985, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 985, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2) != (0)) __PYX_ERR(0, 985, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3) != (0)) __PYX_ERR(0, 985, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4) != (0)) __PYX_ERR(0, 985, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_t_4 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":970 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals( +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicParametersC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":988 + * + * + * def calcQuadraticPoints(a, b, c): # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_55calcQuadraticPoints(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_54calcQuadraticPoints, "calcQuadraticPoints(a, b, c)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_55calcQuadraticPoints = {"calcQuadraticPoints", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_55calcQuadraticPoints, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_54calcQuadraticPoints}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_55calcQuadraticPoints(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_a = 0; + PyObject *__pyx_v_b = 0; + PyObject *__pyx_v_c = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcQuadraticPoints (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_a,&__pyx_mstate_global->__pyx_n_u_b,&__pyx_mstate_global->__pyx_n_u_c,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 988, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 988, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 988, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 988, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "calcQuadraticPoints", 0) < (0)) __PYX_ERR(0, 988, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 3; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("calcQuadraticPoints", 1, 3, 3, i); __PYX_ERR(0, 988, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 988, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 988, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 988, __pyx_L3_error) + } + __pyx_v_a = values[0]; + __pyx_v_b = values[1]; + __pyx_v_c = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcQuadraticPoints", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 988, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticPoints", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_54calcQuadraticPoints(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_c); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_54calcQuadraticPoints(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) { + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_cx = NULL; + PyObject *__pyx_v_cy = NULL; + PyObject *__pyx_v_x1 = NULL; + PyObject *__pyx_v_y1 = NULL; + PyObject *__pyx_v_x2 = NULL; + PyObject *__pyx_v_y2 = NULL; + PyObject *__pyx_v_x3 = NULL; + PyObject *__pyx_v_y3 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *(*__pyx_t_4)(PyObject *); + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcQuadraticPoints", 0); + + /* "fontTools/misc/bezierTools.py":989 + * + * def calcQuadraticPoints(a, b, c): + * ax, ay = a # <<<<<<<<<<<<<< + * bx, by = b + * cx, cy = c +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_a))) || (PyList_CheckExact(__pyx_v_a))) { + PyObject* sequence = __pyx_v_a; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 989, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 989, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 989, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 989, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 989, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 989, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 989, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 989, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_ax = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_ay = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":990 + * def calcQuadraticPoints(a, b, c): + * ax, ay = a + * bx, by = b # <<<<<<<<<<<<<< + * cx, cy = c + * x1 = cx +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_b))) || (PyList_CheckExact(__pyx_v_b))) { + PyObject* sequence = __pyx_v_b; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 990, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 990, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 990, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 990, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 990, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_b); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 990, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 990, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 990, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_bx = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_by = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":991 + * ax, ay = a + * bx, by = b + * cx, cy = c # <<<<<<<<<<<<<< + * x1 = cx + * y1 = cy +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_c))) || (PyList_CheckExact(__pyx_v_c))) { + PyObject* sequence = __pyx_v_c; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 991, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 991, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 991, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 991, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 991, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_c); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 991, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 991, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 991, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_cx = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_cy = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":992 + * bx, by = b + * cx, cy = c + * x1 = cx # <<<<<<<<<<<<<< + * y1 = cy + * x2 = (bx * 0.5) + cx +*/ + __Pyx_INCREF(__pyx_v_cx); + __pyx_v_x1 = __pyx_v_cx; + + /* "fontTools/misc/bezierTools.py":993 + * cx, cy = c + * x1 = cx + * y1 = cy # <<<<<<<<<<<<<< + * x2 = (bx * 0.5) + cx + * y2 = (by * 0.5) + cy +*/ + __Pyx_INCREF(__pyx_v_cy); + __pyx_v_y1 = __pyx_v_cy; + + /* "fontTools/misc/bezierTools.py":994 + * x1 = cx + * y1 = cy + * x2 = (bx * 0.5) + cx # <<<<<<<<<<<<<< + * y2 = (by * 0.5) + cy + * x3 = ax + bx + cx +*/ + __pyx_t_2 = PyNumber_Multiply(__pyx_v_bx, __pyx_mstate_global->__pyx_float_0_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 994, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_cx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 994, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_x2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":995 + * y1 = cy + * x2 = (bx * 0.5) + cx + * y2 = (by * 0.5) + cy # <<<<<<<<<<<<<< + * x3 = ax + bx + cx + * y3 = ay + by + cy +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_by, __pyx_mstate_global->__pyx_float_0_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 995, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_cy); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 995, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_y2 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":996 + * x2 = (bx * 0.5) + cx + * y2 = (by * 0.5) + cy + * x3 = ax + bx + cx # <<<<<<<<<<<<<< + * y3 = ay + by + cy + * return (x1, y1), (x2, y2), (x3, y3) +*/ + __pyx_t_2 = PyNumber_Add(__pyx_v_ax, __pyx_v_bx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 996, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_cx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 996, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_x3 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":997 + * y2 = (by * 0.5) + cy + * x3 = ax + bx + cx + * y3 = ay + by + cy # <<<<<<<<<<<<<< + * return (x1, y1), (x2, y2), (x3, y3) + * +*/ + __pyx_t_1 = PyNumber_Add(__pyx_v_ay, __pyx_v_by); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 997, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_cy); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 997, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_y3 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":998 + * x3 = ax + bx + cx + * y3 = ay + by + cy + * return (x1, y1), (x2, y2), (x3, y3) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 998, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_x1); + __Pyx_GIVEREF(__pyx_v_x1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_x1) != (0)) __PYX_ERR(0, 998, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y1); + __Pyx_GIVEREF(__pyx_v_y1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_y1) != (0)) __PYX_ERR(0, 998, __pyx_L1_error); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 998, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_x2); + __Pyx_GIVEREF(__pyx_v_x2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_x2) != (0)) __PYX_ERR(0, 998, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y2); + __Pyx_GIVEREF(__pyx_v_y2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_y2) != (0)) __PYX_ERR(0, 998, __pyx_L1_error); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 998, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_x3); + __Pyx_GIVEREF(__pyx_v_x3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x3) != (0)) __PYX_ERR(0, 998, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y3); + __Pyx_GIVEREF(__pyx_v_y3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_y3) != (0)) __PYX_ERR(0, 998, __pyx_L1_error); + __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 998, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2) != (0)) __PYX_ERR(0, 998, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_1) != (0)) __PYX_ERR(0, 998, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3) != (0)) __PYX_ERR(0, 998, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":988 + * + * + * def calcQuadraticPoints(a, b, c): # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcQuadraticPoints", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_cx); + __Pyx_XDECREF(__pyx_v_cy); + __Pyx_XDECREF(__pyx_v_x1); + __Pyx_XDECREF(__pyx_v_y1); + __Pyx_XDECREF(__pyx_v_x2); + __Pyx_XDECREF(__pyx_v_y2); + __Pyx_XDECREF(__pyx_v_x3); + __Pyx_XDECREF(__pyx_v_y3); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1001 + * + * + * def calcCubicPoints(a, b, c, d): # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_57calcCubicPoints(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_56calcCubicPoints, "calcCubicPoints(a, b, c, d)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_57calcCubicPoints = {"calcCubicPoints", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_57calcCubicPoints, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_56calcCubicPoints}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_57calcCubicPoints(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_a = 0; + PyObject *__pyx_v_b = 0; + PyObject *__pyx_v_c = 0; + PyObject *__pyx_v_d = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("calcCubicPoints (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_a,&__pyx_mstate_global->__pyx_n_u_b,&__pyx_mstate_global->__pyx_n_u_c,&__pyx_mstate_global->__pyx_n_u_d,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1001, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 1001, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1001, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1001, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1001, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "calcCubicPoints", 0) < (0)) __PYX_ERR(0, 1001, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("calcCubicPoints", 1, 4, 4, i); __PYX_ERR(0, 1001, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1001, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1001, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1001, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 1001, __pyx_L3_error) + } + __pyx_v_a = values[0]; + __pyx_v_b = values[1]; + __pyx_v_c = values[2]; + __pyx_v_d = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("calcCubicPoints", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 1001, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicPoints", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_56calcCubicPoints(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_c, __pyx_v_d); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_56calcCubicPoints(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) { + PyObject *__pyx_v_ax = NULL; + PyObject *__pyx_v_ay = NULL; + PyObject *__pyx_v_bx = NULL; + PyObject *__pyx_v_by = NULL; + PyObject *__pyx_v_cx = NULL; + PyObject *__pyx_v_cy = NULL; + PyObject *__pyx_v_dx = NULL; + PyObject *__pyx_v_dy = NULL; + PyObject *__pyx_v_x1 = NULL; + PyObject *__pyx_v_y1 = NULL; + PyObject *__pyx_v_x2 = NULL; + PyObject *__pyx_v_y2 = NULL; + PyObject *__pyx_v_x3 = NULL; + PyObject *__pyx_v_y3 = NULL; + PyObject *__pyx_v_x4 = NULL; + PyObject *__pyx_v_y4 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *(*__pyx_t_4)(PyObject *); + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcCubicPoints", 0); + + /* "fontTools/misc/bezierTools.py":1002 + * + * def calcCubicPoints(a, b, c, d): + * ax, ay = a # <<<<<<<<<<<<<< + * bx, by = b + * cx, cy = c +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_a))) || (PyList_CheckExact(__pyx_v_a))) { + PyObject* sequence = __pyx_v_a; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1002, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1002, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1002, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1002, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1002, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1002, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 1002, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1002, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_ax = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_ay = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1003 + * def calcCubicPoints(a, b, c, d): + * ax, ay = a + * bx, by = b # <<<<<<<<<<<<<< + * cx, cy = c + * dx, dy = d +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_b))) || (PyList_CheckExact(__pyx_v_b))) { + PyObject* sequence = __pyx_v_b; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1003, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1003, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1003, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1003, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1003, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_b); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1003, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 1003, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1003, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_bx = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_by = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1004 + * ax, ay = a + * bx, by = b + * cx, cy = c # <<<<<<<<<<<<<< + * dx, dy = d + * x1 = dx +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_c))) || (PyList_CheckExact(__pyx_v_c))) { + PyObject* sequence = __pyx_v_c; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1004, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1004, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1004, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1004, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1004, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_c); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1004, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 1004, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1004, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_cx = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_cy = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1005 + * bx, by = b + * cx, cy = c + * dx, dy = d # <<<<<<<<<<<<<< + * x1 = dx + * y1 = dy +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_d))) || (PyList_CheckExact(__pyx_v_d))) { + PyObject* sequence = __pyx_v_d; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1005, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1005, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1005, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1005, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1005, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_d); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1005, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 1005, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1005, __pyx_L1_error) + __pyx_L10_unpacking_done:; + } + __pyx_v_dx = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_dy = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1006 + * cx, cy = c + * dx, dy = d + * x1 = dx # <<<<<<<<<<<<<< + * y1 = dy + * x2 = (cx / 3.0) + dx +*/ + __Pyx_INCREF(__pyx_v_dx); + __pyx_v_x1 = __pyx_v_dx; + + /* "fontTools/misc/bezierTools.py":1007 + * dx, dy = d + * x1 = dx + * y1 = dy # <<<<<<<<<<<<<< + * x2 = (cx / 3.0) + dx + * y2 = (cy / 3.0) + dy +*/ + __Pyx_INCREF(__pyx_v_dy); + __pyx_v_y1 = __pyx_v_dy; + + /* "fontTools/misc/bezierTools.py":1008 + * x1 = dx + * y1 = dy + * x2 = (cx / 3.0) + dx # <<<<<<<<<<<<<< + * y2 = (cy / 3.0) + dy + * x3 = (bx + cx) / 3.0 + x2 +*/ + __pyx_t_1 = __Pyx_PyFloat_TrueDivideObjC(__pyx_v_cx, __pyx_mstate_global->__pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1008, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_dx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1008, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_x2 = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1009 + * y1 = dy + * x2 = (cx / 3.0) + dx + * y2 = (cy / 3.0) + dy # <<<<<<<<<<<<<< + * x3 = (bx + cx) / 3.0 + x2 + * y3 = (by + cy) / 3.0 + y2 +*/ + __pyx_t_2 = __Pyx_PyFloat_TrueDivideObjC(__pyx_v_cy, __pyx_mstate_global->__pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1009, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_dy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1009, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_y2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1010 + * x2 = (cx / 3.0) + dx + * y2 = (cy / 3.0) + dy + * x3 = (bx + cx) / 3.0 + x2 # <<<<<<<<<<<<<< + * y3 = (by + cy) / 3.0 + y2 + * x4 = ax + dx + cx + bx +*/ + __pyx_t_1 = PyNumber_Add(__pyx_v_bx, __pyx_v_cx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1010, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_1, __pyx_mstate_global->__pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1010, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_x2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1010, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_x3 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1011 + * y2 = (cy / 3.0) + dy + * x3 = (bx + cx) / 3.0 + x2 + * y3 = (by + cy) / 3.0 + y2 # <<<<<<<<<<<<<< + * x4 = ax + dx + cx + bx + * y4 = ay + dy + cy + by +*/ + __pyx_t_1 = PyNumber_Add(__pyx_v_by, __pyx_v_cy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1011, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyFloat_TrueDivideObjC(__pyx_t_1, __pyx_mstate_global->__pyx_float_3_0, 3.0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1011, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_y2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1011, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_y3 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1012 + * x3 = (bx + cx) / 3.0 + x2 + * y3 = (by + cy) / 3.0 + y2 + * x4 = ax + dx + cx + bx # <<<<<<<<<<<<<< + * y4 = ay + dy + cy + by + * return (x1, y1), (x2, y2), (x3, y3), (x4, y4) +*/ + __pyx_t_1 = PyNumber_Add(__pyx_v_ax, __pyx_v_dx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1012, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_cx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1012, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_bx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1012, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_x4 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1013 + * y3 = (by + cy) / 3.0 + y2 + * x4 = ax + dx + cx + bx + * y4 = ay + dy + cy + by # <<<<<<<<<<<<<< + * return (x1, y1), (x2, y2), (x3, y3), (x4, y4) + * +*/ + __pyx_t_1 = PyNumber_Add(__pyx_v_ay, __pyx_v_dy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1013, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_v_cy); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1013, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_v_by); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1013, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_y4 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1014 + * x4 = ax + dx + cx + bx + * y4 = ay + dy + cy + by + * return (x1, y1), (x2, y2), (x3, y3), (x4, y4) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1014, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_x1); + __Pyx_GIVEREF(__pyx_v_x1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_x1) != (0)) __PYX_ERR(0, 1014, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y1); + __Pyx_GIVEREF(__pyx_v_y1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_y1) != (0)) __PYX_ERR(0, 1014, __pyx_L1_error); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1014, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_x2); + __Pyx_GIVEREF(__pyx_v_x2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_x2) != (0)) __PYX_ERR(0, 1014, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y2); + __Pyx_GIVEREF(__pyx_v_y2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_y2) != (0)) __PYX_ERR(0, 1014, __pyx_L1_error); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1014, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_x3); + __Pyx_GIVEREF(__pyx_v_x3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x3) != (0)) __PYX_ERR(0, 1014, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y3); + __Pyx_GIVEREF(__pyx_v_y3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_y3) != (0)) __PYX_ERR(0, 1014, __pyx_L1_error); + __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1014, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_x4); + __Pyx_GIVEREF(__pyx_v_x4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_x4) != (0)) __PYX_ERR(0, 1014, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y4); + __Pyx_GIVEREF(__pyx_v_y4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_y4) != (0)) __PYX_ERR(0, 1014, __pyx_L1_error); + __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1014, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 1014, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_2) != (0)) __PYX_ERR(0, 1014, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_3) != (0)) __PYX_ERR(0, 1014, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_5) != (0)) __PYX_ERR(0, 1014, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_t_5 = 0; + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1001 + * + * + * def calcCubicPoints(a, b, c, d): # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicPoints", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_ax); + __Pyx_XDECREF(__pyx_v_ay); + __Pyx_XDECREF(__pyx_v_bx); + __Pyx_XDECREF(__pyx_v_by); + __Pyx_XDECREF(__pyx_v_cx); + __Pyx_XDECREF(__pyx_v_cy); + __Pyx_XDECREF(__pyx_v_dx); + __Pyx_XDECREF(__pyx_v_dy); + __Pyx_XDECREF(__pyx_v_x1); + __Pyx_XDECREF(__pyx_v_y1); + __Pyx_XDECREF(__pyx_v_x2); + __Pyx_XDECREF(__pyx_v_y2); + __Pyx_XDECREF(__pyx_v_x3); + __Pyx_XDECREF(__pyx_v_y3); + __Pyx_XDECREF(__pyx_v_x4); + __Pyx_XDECREF(__pyx_v_y4); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1017 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals( +*/ + +static CYTHON_INLINE PyObject *__pyx_f_9fontTools_4misc_11bezierTools_calcCubicPointsC(__pyx_t_double_complex __pyx_v_a, __pyx_t_double_complex __pyx_v_b, __pyx_t_double_complex __pyx_v_c, __pyx_t_double_complex __pyx_v_d) { + __pyx_t_double_complex __pyx_v_p2; + __pyx_t_double_complex __pyx_v_p3; + __pyx_t_double_complex __pyx_v_p4; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("calcCubicPointsC", 0); + + /* "fontTools/misc/bezierTools.py":1029 + * ) + * def calcCubicPointsC(a, b, c, d): + * p2 = c * (1 / 3) + d # <<<<<<<<<<<<<< + * p3 = (b + c) * (1 / 3) + p2 + * p4 = a + b + c + d +*/ + __pyx_v_p2 = __Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_v_c, __pyx_t_double_complex_from_parts((1.0 / 3.0), 0)), __pyx_v_d); + + /* "fontTools/misc/bezierTools.py":1030 + * def calcCubicPointsC(a, b, c, d): + * p2 = c * (1 / 3) + d + * p3 = (b + c) * (1 / 3) + p2 # <<<<<<<<<<<<<< + * p4 = a + b + c + d + * return (d, p2, p3, p4) +*/ + __pyx_v_p3 = __Pyx_c_sum_double(__Pyx_c_prod_double(__Pyx_c_sum_double(__pyx_v_b, __pyx_v_c), __pyx_t_double_complex_from_parts((1.0 / 3.0), 0)), __pyx_v_p2); + + /* "fontTools/misc/bezierTools.py":1031 + * p2 = c * (1 / 3) + d + * p3 = (b + c) * (1 / 3) + p2 + * p4 = a + b + c + d # <<<<<<<<<<<<<< + * return (d, p2, p3, p4) + * +*/ + __pyx_v_p4 = __Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_sum_double(__pyx_v_a, __pyx_v_b), __pyx_v_c), __pyx_v_d); + + /* "fontTools/misc/bezierTools.py":1032 + * p3 = (b + c) * (1 / 3) + p2 + * p4 = a + b + c + d + * return (d, p2, p3, p4) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_v_d); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1032, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __pyx_PyComplex_FromComplex(__pyx_v_p2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1032, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __pyx_PyComplex_FromComplex(__pyx_v_p3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1032, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __pyx_PyComplex_FromComplex(__pyx_v_p4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1032, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1032, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 1032, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2) != (0)) __PYX_ERR(0, 1032, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3) != (0)) __PYX_ERR(0, 1032, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4) != (0)) __PYX_ERR(0, 1032, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_t_4 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1017 + * + * + * @cython.cfunc # <<<<<<<<<<<<<< + * @cython.inline + * @cython.locals( +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools.calcCubicPointsC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1040 + * + * + * def linePointAtT(pt1, pt2, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a line. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_59linePointAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_58linePointAtT, "linePointAtT(pt1, pt2, t)\n\nFinds the point at time `t` on a line.\n\nArgs:\n pt1, pt2: Coordinates of the line as 2D tuples.\n t: The time along the line.\n\nReturns:\n A 2D tuple with the coordinates of the point."); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_59linePointAtT = {"linePointAtT", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_59linePointAtT, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_58linePointAtT}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_59linePointAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_t = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("linePointAtT (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_t,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1040, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1040, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1040, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1040, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "linePointAtT", 0) < (0)) __PYX_ERR(0, 1040, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 3; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("linePointAtT", 1, 3, 3, i); __PYX_ERR(0, 1040, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1040, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1040, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1040, __pyx_L3_error) + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_t = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("linePointAtT", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 1040, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.linePointAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_58linePointAtT(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_t); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_58linePointAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_t) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("linePointAtT", 0); + + /* "fontTools/misc/bezierTools.py":1050 + * A 2D tuple with the coordinates of the point. + * """ + * return ((pt1[0] * (1 - t) + pt2[0] * t), (pt1[1] * (1 - t) + pt2[1] * t)) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_pt1, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1050, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyLong_SubtractCObj(__pyx_mstate_global->__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1050, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1050, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_pt2, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1050, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_2, __pyx_v_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1050, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1050, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_pt1, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1050, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyLong_SubtractCObj(__pyx_mstate_global->__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1050, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyNumber_Multiply(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1050, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_pt2, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1050, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_3, __pyx_v_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1050, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Add(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1050, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1050, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2) != (0)) __PYX_ERR(0, 1050, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3) != (0)) __PYX_ERR(0, 1050, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1040 + * + * + * def linePointAtT(pt1, pt2, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a line. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("fontTools.misc.bezierTools.linePointAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1053 + * + * + * def quadraticPointAtT(pt1, pt2, pt3, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a quadratic curve. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_61quadraticPointAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_60quadraticPointAtT, "quadraticPointAtT(pt1, pt2, pt3, t)\n\nFinds the point at time `t` on a quadratic curve.\n\nArgs:\n pt1, pt2, pt3: Coordinates of the curve as 2D tuples.\n t: The time along the curve.\n\nReturns:\n A 2D tuple with the coordinates of the point."); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_61quadraticPointAtT = {"quadraticPointAtT", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_61quadraticPointAtT, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_60quadraticPointAtT}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_61quadraticPointAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_t = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("quadraticPointAtT (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,&__pyx_mstate_global->__pyx_n_u_t,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1053, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 1053, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1053, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1053, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1053, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "quadraticPointAtT", 0) < (0)) __PYX_ERR(0, 1053, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("quadraticPointAtT", 1, 4, 4, i); __PYX_ERR(0, 1053, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1053, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1053, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1053, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 1053, __pyx_L3_error) + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_t = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("quadraticPointAtT", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 1053, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.quadraticPointAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_60quadraticPointAtT(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_t); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_60quadraticPointAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_t) { + PyObject *__pyx_v_x = NULL; + PyObject *__pyx_v_y = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("quadraticPointAtT", 0); + + /* "fontTools/misc/bezierTools.py":1063 + * A 2D tuple with the coordinates of the point. + * """ + * x = (1 - t) * (1 - t) * pt1[0] + 2 * (1 - t) * t * pt2[0] + t * t * pt3[0] # <<<<<<<<<<<<<< + * y = (1 - t) * (1 - t) * pt1[1] + 2 * (1 - t) * t * pt2[1] + t * t * pt3[1] + * return (x, y) +*/ + __pyx_t_1 = __Pyx_PyLong_SubtractCObj(__pyx_mstate_global->__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1063, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyLong_SubtractCObj(__pyx_mstate_global->__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1063, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1063, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_pt1, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1063, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1063, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyLong_SubtractCObj(__pyx_mstate_global->__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1063, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyLong_MultiplyCObj(__pyx_mstate_global->__pyx_int_2, __pyx_t_2, 2, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1063, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_t_3, __pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1063, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_pt2, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1063, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyNumber_Multiply(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1063, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Add(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1063, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Multiply(__pyx_v_t, __pyx_v_t); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1063, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_pt3, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1063, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1063, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1063, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_x = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1064 + * """ + * x = (1 - t) * (1 - t) * pt1[0] + 2 * (1 - t) * t * pt2[0] + t * t * pt3[0] + * y = (1 - t) * (1 - t) * pt1[1] + 2 * (1 - t) * t * pt2[1] + t * t * pt3[1] # <<<<<<<<<<<<<< + * return (x, y) + * +*/ + __pyx_t_1 = __Pyx_PyLong_SubtractCObj(__pyx_mstate_global->__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1064, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyLong_SubtractCObj(__pyx_mstate_global->__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1064, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1064, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_pt1, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1064, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1064, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyLong_SubtractCObj(__pyx_mstate_global->__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1064, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyLong_MultiplyCObj(__pyx_mstate_global->__pyx_int_2, __pyx_t_2, 2, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1064, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_t_3, __pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1064, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_pt2, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1064, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyNumber_Multiply(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1064, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Add(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1064, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Multiply(__pyx_v_t, __pyx_v_t); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1064, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_pt3, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1064, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1064, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1064, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_y = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1065 + * x = (1 - t) * (1 - t) * pt1[0] + 2 * (1 - t) * t * pt2[0] + t * t * pt3[0] + * y = (1 - t) * (1 - t) * pt1[1] + 2 * (1 - t) * t * pt2[1] + t * t * pt3[1] + * return (x, y) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1065, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_x) != (0)) __PYX_ERR(0, 1065, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y); + __Pyx_GIVEREF(__pyx_v_y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_y) != (0)) __PYX_ERR(0, 1065, __pyx_L1_error); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1053 + * + * + * def quadraticPointAtT(pt1, pt2, pt3, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a quadratic curve. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("fontTools.misc.bezierTools.quadraticPointAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_x); + __Pyx_XDECREF(__pyx_v_y); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1068 + * + * + * def cubicPointAtT(pt1, pt2, pt3, pt4, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a cubic curve. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_63cubicPointAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_62cubicPointAtT, "cubicPointAtT(pt1, pt2, pt3, pt4, t)\n\nFinds the point at time `t` on a cubic curve.\n\nArgs:\n pt1, pt2, pt3, pt4: Coordinates of the curve as 2D tuples.\n t: The time along the curve.\n\nReturns:\n A 2D tuple with the coordinates of the point."); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_63cubicPointAtT = {"cubicPointAtT", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_63cubicPointAtT, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_62cubicPointAtT}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_63cubicPointAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_pt1 = 0; + PyObject *__pyx_v_pt2 = 0; + PyObject *__pyx_v_pt3 = 0; + PyObject *__pyx_v_pt4 = 0; + PyObject *__pyx_v_t = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("cubicPointAtT (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,&__pyx_mstate_global->__pyx_n_u_pt4,&__pyx_mstate_global->__pyx_n_u_t,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1068, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 5: + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 1068, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 1068, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1068, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1068, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1068, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "cubicPointAtT", 0) < (0)) __PYX_ERR(0, 1068, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 5; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("cubicPointAtT", 1, 5, 5, i); __PYX_ERR(0, 1068, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 5)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1068, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1068, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1068, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 1068, __pyx_L3_error) + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 1068, __pyx_L3_error) + } + __pyx_v_pt1 = values[0]; + __pyx_v_pt2 = values[1]; + __pyx_v_pt3 = values[2]; + __pyx_v_pt4 = values[3]; + __pyx_v_t = values[4]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("cubicPointAtT", 1, 5, 5, __pyx_nargs); __PYX_ERR(0, 1068, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.cubicPointAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_62cubicPointAtT(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4, __pyx_v_t); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_62cubicPointAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pt1, PyObject *__pyx_v_pt2, PyObject *__pyx_v_pt3, PyObject *__pyx_v_pt4, PyObject *__pyx_v_t) { + PyObject *__pyx_v_t2 = NULL; + PyObject *__pyx_v__1_t = NULL; + PyObject *__pyx_v__1_t_2 = NULL; + PyObject *__pyx_v_x = NULL; + PyObject *__pyx_v_y = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("cubicPointAtT", 0); + + /* "fontTools/misc/bezierTools.py":1078 + * A 2D tuple with the coordinates of the point. + * """ + * t2 = t * t # <<<<<<<<<<<<<< + * _1_t = 1 - t + * _1_t_2 = _1_t * _1_t +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_t, __pyx_v_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1078, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_t2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1079 + * """ + * t2 = t * t + * _1_t = 1 - t # <<<<<<<<<<<<<< + * _1_t_2 = _1_t * _1_t + * x = ( +*/ + __pyx_t_1 = __Pyx_PyLong_SubtractCObj(__pyx_mstate_global->__pyx_int_1, __pyx_v_t, 1, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1079, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v__1_t = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1080 + * t2 = t * t + * _1_t = 1 - t + * _1_t_2 = _1_t * _1_t # <<<<<<<<<<<<<< + * x = ( + * _1_t_2 * _1_t * pt1[0] +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v__1_t, __pyx_v__1_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1080, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v__1_t_2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1082 + * _1_t_2 = _1_t * _1_t + * x = ( + * _1_t_2 * _1_t * pt1[0] # <<<<<<<<<<<<<< + * + 3 * (_1_t_2 * t * pt2[0] + _1_t * t2 * pt3[0]) + * + t2 * t * pt4[0] +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v__1_t_2, __pyx_v__1_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1082, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_pt1, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1082, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1082, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1083 + * x = ( + * _1_t_2 * _1_t * pt1[0] + * + 3 * (_1_t_2 * t * pt2[0] + _1_t * t2 * pt3[0]) # <<<<<<<<<<<<<< + * + t2 * t * pt4[0] + * ) +*/ + __pyx_t_2 = PyNumber_Multiply(__pyx_v__1_t_2, __pyx_v_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1083, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_pt2, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1083, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = PyNumber_Multiply(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1083, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_v__1_t, __pyx_v_t2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1083, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_pt3, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1083, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1083, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1083, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyLong_MultiplyCObj(__pyx_mstate_global->__pyx_int_3, __pyx_t_2, 3, 0, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1083, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1083, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":1084 + * _1_t_2 * _1_t * pt1[0] + * + 3 * (_1_t_2 * t * pt2[0] + _1_t * t2 * pt3[0]) + * + t2 * t * pt4[0] # <<<<<<<<<<<<<< + * ) + * y = ( +*/ + __pyx_t_5 = PyNumber_Multiply(__pyx_v_t2, __pyx_v_t); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1084, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_pt4, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1084, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyNumber_Multiply(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1084, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Add(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1084, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_x = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1087 + * ) + * y = ( + * _1_t_2 * _1_t * pt1[1] # <<<<<<<<<<<<<< + * + 3 * (_1_t_2 * t * pt2[1] + _1_t * t2 * pt3[1]) + * + t2 * t * pt4[1] +*/ + __pyx_t_3 = PyNumber_Multiply(__pyx_v__1_t_2, __pyx_v__1_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1087, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_pt1, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1087, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1087, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1088 + * y = ( + * _1_t_2 * _1_t * pt1[1] + * + 3 * (_1_t_2 * t * pt2[1] + _1_t * t2 * pt3[1]) # <<<<<<<<<<<<<< + * + t2 * t * pt4[1] + * ) +*/ + __pyx_t_4 = PyNumber_Multiply(__pyx_v__1_t_2, __pyx_v_t); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1088, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_pt2, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1088, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = PyNumber_Multiply(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1088, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Multiply(__pyx_v__1_t, __pyx_v_t2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1088, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_pt3, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1088, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = PyNumber_Multiply(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1088, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Add(__pyx_t_5, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1088, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyLong_MultiplyCObj(__pyx_mstate_global->__pyx_int_3, __pyx_t_4, 3, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1088, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyNumber_Add(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1088, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1089 + * _1_t_2 * _1_t * pt1[1] + * + 3 * (_1_t_2 * t * pt2[1] + _1_t * t2 * pt3[1]) + * + t2 * t * pt4[1] # <<<<<<<<<<<<<< + * ) + * return (x, y) +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_t2, __pyx_v_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1089, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_pt4, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1089, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1089, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Add(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1089, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_v_y = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1091 + * + t2 * t * pt4[1] + * ) + * return (x, y) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1091, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_x) != (0)) __PYX_ERR(0, 1091, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y); + __Pyx_GIVEREF(__pyx_v_y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_y) != (0)) __PYX_ERR(0, 1091, __pyx_L1_error); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1068 + * + * + * def cubicPointAtT(pt1, pt2, pt3, pt4, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a cubic curve. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools.cubicPointAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_t2); + __Pyx_XDECREF(__pyx_v__1_t); + __Pyx_XDECREF(__pyx_v__1_t_2); + __Pyx_XDECREF(__pyx_v_x); + __Pyx_XDECREF(__pyx_v_y); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1094 + * + * + * @cython.returns(cython.complex) # <<<<<<<<<<<<<< + * @cython.locals( + * t=cython.double, +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_65cubicPointAtTC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_64cubicPointAtTC, "cubicPointAtTC(double complex pt1, double complex pt2, double complex pt3, double complex pt4, double t)\n\nFinds the point at time `t` on a cubic curve.\n\nArgs:\n pt1, pt2, pt3, pt4: Coordinates of the curve as complex numbers.\n t: The time along the curve.\n\nReturns:\n A complex number with the coordinates of the point."); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_65cubicPointAtTC = {"cubicPointAtTC", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_65cubicPointAtTC, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_64cubicPointAtTC}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_65cubicPointAtTC(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + __pyx_t_double_complex __pyx_v_pt1; + __pyx_t_double_complex __pyx_v_pt2; + __pyx_t_double_complex __pyx_v_pt3; + __pyx_t_double_complex __pyx_v_pt4; + double __pyx_v_t; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("cubicPointAtTC (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_pt1,&__pyx_mstate_global->__pyx_n_u_pt2,&__pyx_mstate_global->__pyx_n_u_pt3,&__pyx_mstate_global->__pyx_n_u_pt4,&__pyx_mstate_global->__pyx_n_u_t,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1094, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 5: + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 1094, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 1094, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1094, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1094, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1094, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "cubicPointAtTC", 0) < (0)) __PYX_ERR(0, 1094, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 5; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("cubicPointAtTC", 1, 5, 5, i); __PYX_ERR(0, 1094, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 5)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1094, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1094, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1094, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 1094, __pyx_L3_error) + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 1094, __pyx_L3_error) + } + __pyx_v_pt1 = __Pyx_PyComplex_As___pyx_t_double_complex(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1103, __pyx_L3_error) + __pyx_v_pt2 = __Pyx_PyComplex_As___pyx_t_double_complex(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1103, __pyx_L3_error) + __pyx_v_pt3 = __Pyx_PyComplex_As___pyx_t_double_complex(values[2]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1103, __pyx_L3_error) + __pyx_v_pt4 = __Pyx_PyComplex_As___pyx_t_double_complex(values[3]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1103, __pyx_L3_error) + __pyx_v_t = __Pyx_PyFloat_AsDouble(values[4]); if (unlikely((__pyx_v_t == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1103, __pyx_L3_error) + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("cubicPointAtTC", 1, 5, 5, __pyx_nargs); __PYX_ERR(0, 1094, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.cubicPointAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_64cubicPointAtTC(__pyx_self, __pyx_v_pt1, __pyx_v_pt2, __pyx_v_pt3, __pyx_v_pt4, __pyx_v_t); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_64cubicPointAtTC(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_double_complex __pyx_v_pt1, __pyx_t_double_complex __pyx_v_pt2, __pyx_t_double_complex __pyx_v_pt3, __pyx_t_double_complex __pyx_v_pt4, double __pyx_v_t) { + double __pyx_v_t2; + double __pyx_v__1_t; + double __pyx_v__1_t_2; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __pyx_t_double_complex __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("cubicPointAtTC", 0); + + /* "fontTools/misc/bezierTools.py":1113 + * A complex number with the coordinates of the point. + * """ + * t2 = t * t # <<<<<<<<<<<<<< + * _1_t = 1 - t + * _1_t_2 = _1_t * _1_t +*/ + __pyx_v_t2 = (__pyx_v_t * __pyx_v_t); + + /* "fontTools/misc/bezierTools.py":1114 + * """ + * t2 = t * t + * _1_t = 1 - t # <<<<<<<<<<<<<< + * _1_t_2 = _1_t * _1_t + * return _1_t_2 * _1_t * pt1 + 3 * (_1_t_2 * t * pt2 + _1_t * t2 * pt3) + t2 * t * pt4 +*/ + __pyx_v__1_t = (1.0 - __pyx_v_t); + + /* "fontTools/misc/bezierTools.py":1115 + * t2 = t * t + * _1_t = 1 - t + * _1_t_2 = _1_t * _1_t # <<<<<<<<<<<<<< + * return _1_t_2 * _1_t * pt1 + 3 * (_1_t_2 * t * pt2 + _1_t * t2 * pt3) + t2 * t * pt4 + * +*/ + __pyx_v__1_t_2 = (__pyx_v__1_t * __pyx_v__1_t); + + /* "fontTools/misc/bezierTools.py":1116 + * _1_t = 1 - t + * _1_t_2 = _1_t * _1_t + * return _1_t_2 * _1_t * pt1 + 3 * (_1_t_2 * t * pt2 + _1_t * t2 * pt3) + t2 * t * pt4 # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_c_sum_double(__Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts((__pyx_v__1_t_2 * __pyx_v__1_t), 0), __pyx_v_pt1), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts(3, 0), __Pyx_c_sum_double(__Pyx_c_prod_double(__pyx_t_double_complex_from_parts((__pyx_v__1_t_2 * __pyx_v_t), 0), __pyx_v_pt2), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts((__pyx_v__1_t * __pyx_v_t2), 0), __pyx_v_pt3)))), __Pyx_c_prod_double(__pyx_t_double_complex_from_parts((__pyx_v_t2 * __pyx_v_t), 0), __pyx_v_pt4)); + __pyx_t_2 = __pyx_PyComplex_FromComplex(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1116, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1094 + * + * + * @cython.returns(cython.complex) # <<<<<<<<<<<<<< + * @cython.locals( + * t=cython.double, +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("fontTools.misc.bezierTools.cubicPointAtTC", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1119 + * + * + * def segmentPointAtT(seg, t): # <<<<<<<<<<<<<< + * if len(seg) == 2: + * return linePointAtT(*seg, t) +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_67segmentPointAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_66segmentPointAtT, "segmentPointAtT(seg, t)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_67segmentPointAtT = {"segmentPointAtT", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_67segmentPointAtT, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_66segmentPointAtT}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_67segmentPointAtT(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_seg = 0; + PyObject *__pyx_v_t = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("segmentPointAtT (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_seg,&__pyx_mstate_global->__pyx_n_u_t,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1119, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1119, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1119, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "segmentPointAtT", 0) < (0)) __PYX_ERR(0, 1119, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("segmentPointAtT", 1, 2, 2, i); __PYX_ERR(0, 1119, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1119, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1119, __pyx_L3_error) + } + __pyx_v_seg = values[0]; + __pyx_v_t = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("segmentPointAtT", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 1119, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.segmentPointAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_66segmentPointAtT(__pyx_self, __pyx_v_seg, __pyx_v_t); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_66segmentPointAtT(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_seg, PyObject *__pyx_v_t) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + Py_ssize_t __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + size_t __pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("segmentPointAtT", 0); + + /* "fontTools/misc/bezierTools.py":1120 + * + * def segmentPointAtT(seg, t): + * if len(seg) == 2: # <<<<<<<<<<<<<< + * return linePointAtT(*seg, t) + * elif len(seg) == 3: +*/ + __pyx_t_1 = PyObject_Length(__pyx_v_seg); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1120, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 2); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1121 + * def segmentPointAtT(seg, t): + * if len(seg) == 2: + * return linePointAtT(*seg, t) # <<<<<<<<<<<<<< + * elif len(seg) == 3: + * return quadraticPointAtT(*seg, t) +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_linePointAtT); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1121, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_seg); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1121, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1121, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_t); + __Pyx_GIVEREF(__pyx_v_t); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_t) != (0)) __PYX_ERR(0, 1121, __pyx_L1_error); + __pyx_t_6 = PyNumber_Add(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1121, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1121, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1120 + * + * def segmentPointAtT(seg, t): + * if len(seg) == 2: # <<<<<<<<<<<<<< + * return linePointAtT(*seg, t) + * elif len(seg) == 3: +*/ + } + + /* "fontTools/misc/bezierTools.py":1122 + * if len(seg) == 2: + * return linePointAtT(*seg, t) + * elif len(seg) == 3: # <<<<<<<<<<<<<< + * return quadraticPointAtT(*seg, t) + * elif len(seg) == 4: +*/ + __pyx_t_1 = PyObject_Length(__pyx_v_seg); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1122, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 3); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1123 + * return linePointAtT(*seg, t) + * elif len(seg) == 3: + * return quadraticPointAtT(*seg, t) # <<<<<<<<<<<<<< + * elif len(seg) == 4: + * return cubicPointAtT(*seg, t) +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_quadraticPointAtT); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1123, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PySequence_Tuple(__pyx_v_seg); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1123, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1123, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_t); + __Pyx_GIVEREF(__pyx_v_t); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_t) != (0)) __PYX_ERR(0, 1123, __pyx_L1_error); + __pyx_t_4 = PyNumber_Add(__pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1123, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1123, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1122 + * if len(seg) == 2: + * return linePointAtT(*seg, t) + * elif len(seg) == 3: # <<<<<<<<<<<<<< + * return quadraticPointAtT(*seg, t) + * elif len(seg) == 4: +*/ + } + + /* "fontTools/misc/bezierTools.py":1124 + * elif len(seg) == 3: + * return quadraticPointAtT(*seg, t) + * elif len(seg) == 4: # <<<<<<<<<<<<<< + * return cubicPointAtT(*seg, t) + * raise ValueError("Unknown curve degree") +*/ + __pyx_t_1 = PyObject_Length(__pyx_v_seg); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1124, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 4); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1125 + * return quadraticPointAtT(*seg, t) + * elif len(seg) == 4: + * return cubicPointAtT(*seg, t) # <<<<<<<<<<<<<< + * raise ValueError("Unknown curve degree") + * +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_cubicPointAtT); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1125, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_seg); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1125, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1125, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_t); + __Pyx_GIVEREF(__pyx_v_t); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_t) != (0)) __PYX_ERR(0, 1125, __pyx_L1_error); + __pyx_t_6 = PyNumber_Add(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1125, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1125, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1124 + * elif len(seg) == 3: + * return quadraticPointAtT(*seg, t) + * elif len(seg) == 4: # <<<<<<<<<<<<<< + * return cubicPointAtT(*seg, t) + * raise ValueError("Unknown curve degree") +*/ + } + + /* "fontTools/misc/bezierTools.py":1126 + * elif len(seg) == 4: + * return cubicPointAtT(*seg, t) + * raise ValueError("Unknown curve degree") # <<<<<<<<<<<<<< + * + * +*/ + __pyx_t_6 = NULL; + __pyx_t_7 = 1; + { + PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_mstate_global->__pyx_kp_u_Unknown_curve_degree}; + __pyx_t_5 = __Pyx_PyObject_FastCall((PyObject*)(((PyTypeObject*)PyExc_ValueError)), __pyx_callargs+__pyx_t_7, (2-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1126, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + } + __Pyx_Raise(__pyx_t_5, 0, 0, 0); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __PYX_ERR(0, 1126, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1119 + * + * + * def segmentPointAtT(seg, t): # <<<<<<<<<<<<<< + * if len(seg) == 2: + * return linePointAtT(*seg, t) +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("fontTools.misc.bezierTools.segmentPointAtT", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1134 + * + * + * def _line_t_of_pt(s, e, pt): # <<<<<<<<<<<<<< + * sx, sy = s + * ex, ey = e +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_69_line_t_of_pt(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_68_line_t_of_pt, "_line_t_of_pt(s, e, pt)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_69_line_t_of_pt = {"_line_t_of_pt", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_69_line_t_of_pt, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_68_line_t_of_pt}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_69_line_t_of_pt(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_s = 0; + PyObject *__pyx_v_e = 0; + PyObject *__pyx_v_pt = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_line_t_of_pt (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_s,&__pyx_mstate_global->__pyx_n_u_e,&__pyx_mstate_global->__pyx_n_u_pt,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1134, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1134, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1134, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1134, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_line_t_of_pt", 0) < (0)) __PYX_ERR(0, 1134, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 3; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_line_t_of_pt", 1, 3, 3, i); __PYX_ERR(0, 1134, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1134, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1134, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1134, __pyx_L3_error) + } + __pyx_v_s = values[0]; + __pyx_v_e = values[1]; + __pyx_v_pt = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_line_t_of_pt", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 1134, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._line_t_of_pt", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_68_line_t_of_pt(__pyx_self, __pyx_v_s, __pyx_v_e, __pyx_v_pt); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_68_line_t_of_pt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_s, PyObject *__pyx_v_e, PyObject *__pyx_v_pt) { + PyObject *__pyx_v_sx = NULL; + PyObject *__pyx_v_sy = NULL; + PyObject *__pyx_v_ex = NULL; + PyObject *__pyx_v_ey = NULL; + PyObject *__pyx_v_px = NULL; + PyObject *__pyx_v_py = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *(*__pyx_t_4)(PyObject *); + int __pyx_t_5; + int __pyx_t_6; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_line_t_of_pt", 0); + + /* "fontTools/misc/bezierTools.py":1135 + * + * def _line_t_of_pt(s, e, pt): + * sx, sy = s # <<<<<<<<<<<<<< + * ex, ey = e + * px, py = pt +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_s))) || (PyList_CheckExact(__pyx_v_s))) { + PyObject* sequence = __pyx_v_s; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1135, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1135, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1135, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1135, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1135, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_s); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1135, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 1135, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1135, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_sx = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_sy = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1136 + * def _line_t_of_pt(s, e, pt): + * sx, sy = s + * ex, ey = e # <<<<<<<<<<<<<< + * px, py = pt + * if abs(sx - ex) < epsilon and abs(sy - ey) < epsilon: +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_e))) || (PyList_CheckExact(__pyx_v_e))) { + PyObject* sequence = __pyx_v_e; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1136, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1136, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1136, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_e); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 1136, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1136, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_ex = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_ey = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1137 + * sx, sy = s + * ex, ey = e + * px, py = pt # <<<<<<<<<<<<<< + * if abs(sx - ex) < epsilon and abs(sy - ey) < epsilon: + * # Line is a point! +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_pt))) || (PyList_CheckExact(__pyx_v_pt))) { + PyObject* sequence = __pyx_v_pt; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1137, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1137, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1137, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1137, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1137, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_pt); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1137, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 1137, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1137, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_px = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_py = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1138 + * ex, ey = e + * px, py = pt + * if abs(sx - ex) < epsilon and abs(sy - ey) < epsilon: # <<<<<<<<<<<<<< + * # Line is a point! + * return -1 +*/ + __pyx_t_2 = PyNumber_Subtract(__pyx_v_sx, __pyx_v_ex); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1138, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyNumber_Absolute(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1138, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_epsilon); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1138, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1138, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(0, 1138, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + } else { + __pyx_t_5 = __pyx_t_6; + goto __pyx_L10_bool_binop_done; + } + __pyx_t_3 = PyNumber_Subtract(__pyx_v_sy, __pyx_v_ey); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1138, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyNumber_Absolute(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1138, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_epsilon); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1138, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_t_3, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1138, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(0, 1138, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = __pyx_t_6; + __pyx_L10_bool_binop_done:; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1140 + * if abs(sx - ex) < epsilon and abs(sy - ey) < epsilon: + * # Line is a point! + * return -1 # <<<<<<<<<<<<<< + * # Use the largest + * if abs(sx - ex) > abs(sy - ey): +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_mstate_global->__pyx_int_neg_1); + __pyx_r = __pyx_mstate_global->__pyx_int_neg_1; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1138 + * ex, ey = e + * px, py = pt + * if abs(sx - ex) < epsilon and abs(sy - ey) < epsilon: # <<<<<<<<<<<<<< + * # Line is a point! + * return -1 +*/ + } + + /* "fontTools/misc/bezierTools.py":1142 + * return -1 + * # Use the largest + * if abs(sx - ex) > abs(sy - ey): # <<<<<<<<<<<<<< + * return (px - sx) / (ex - sx) + * else: +*/ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_sx, __pyx_v_ex); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyNumber_Absolute(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Subtract(__pyx_v_sy, __pyx_v_ey); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyNumber_Absolute(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_t_2, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1142, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1142, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1143 + * # Use the largest + * if abs(sx - ex) > abs(sy - ey): + * return (px - sx) / (ex - sx) # <<<<<<<<<<<<<< + * else: + * return (py - sy) / (ey - sy) +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyNumber_Subtract(__pyx_v_px, __pyx_v_sx); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1143, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Subtract(__pyx_v_ex, __pyx_v_sx); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1143, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1143, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1142 + * return -1 + * # Use the largest + * if abs(sx - ex) > abs(sy - ey): # <<<<<<<<<<<<<< + * return (px - sx) / (ex - sx) + * else: +*/ + } + + /* "fontTools/misc/bezierTools.py":1145 + * return (px - sx) / (ex - sx) + * else: + * return (py - sy) / (ey - sy) # <<<<<<<<<<<<<< + * + * +*/ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = PyNumber_Subtract(__pyx_v_py, __pyx_v_sy); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1145, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyNumber_Subtract(__pyx_v_ey, __pyx_v_sy); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1145, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyNumber_Divide(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1145, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + } + + /* "fontTools/misc/bezierTools.py":1134 + * + * + * def _line_t_of_pt(s, e, pt): # <<<<<<<<<<<<<< + * sx, sy = s + * ex, ey = e +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("fontTools.misc.bezierTools._line_t_of_pt", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_sx); + __Pyx_XDECREF(__pyx_v_sy); + __Pyx_XDECREF(__pyx_v_ex); + __Pyx_XDECREF(__pyx_v_ey); + __Pyx_XDECREF(__pyx_v_px); + __Pyx_XDECREF(__pyx_v_py); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1148 + * + * + * def _both_points_are_on_same_side_of_origin(a, b, origin): # <<<<<<<<<<<<<< + * xDiff = (a[0] - origin[0]) * (b[0] - origin[0]) + * yDiff = (a[1] - origin[1]) * (b[1] - origin[1]) +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_71_both_points_are_on_same_side_of_origin(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_70_both_points_are_on_same_side_of_origin, "_both_points_are_on_same_side_of_origin(a, b, origin)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_71_both_points_are_on_same_side_of_origin = {"_both_points_are_on_same_side_of_origin", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_71_both_points_are_on_same_side_of_origin, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_70_both_points_are_on_same_side_of_origin}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_71_both_points_are_on_same_side_of_origin(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_a = 0; + PyObject *__pyx_v_b = 0; + PyObject *__pyx_v_origin = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_both_points_are_on_same_side_of_origin (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_a,&__pyx_mstate_global->__pyx_n_u_b,&__pyx_mstate_global->__pyx_n_u_origin,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1148, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1148, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1148, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1148, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_both_points_are_on_same_side_of_origin", 0) < (0)) __PYX_ERR(0, 1148, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 3; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_both_points_are_on_same_side_of_origin", 1, 3, 3, i); __PYX_ERR(0, 1148, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1148, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1148, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1148, __pyx_L3_error) + } + __pyx_v_a = values[0]; + __pyx_v_b = values[1]; + __pyx_v_origin = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_both_points_are_on_same_side_of_origin", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 1148, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._both_points_are_on_same_side_of_origin", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_70_both_points_are_on_same_side_of_origin(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_origin); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_70_both_points_are_on_same_side_of_origin(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_origin) { + PyObject *__pyx_v_xDiff = NULL; + PyObject *__pyx_v_yDiff = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_t_6; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_both_points_are_on_same_side_of_origin", 0); + + /* "fontTools/misc/bezierTools.py":1149 + * + * def _both_points_are_on_same_side_of_origin(a, b, origin): + * xDiff = (a[0] - origin[0]) * (b[0] - origin[0]) # <<<<<<<<<<<<<< + * yDiff = (a[1] - origin[1]) * (b[1] - origin[1]) + * return not (xDiff <= 0.0 and yDiff <= 0.0) +*/ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_a, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_origin, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Subtract(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_b, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_origin, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = PyNumber_Subtract(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1149, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_xDiff = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1150 + * def _both_points_are_on_same_side_of_origin(a, b, origin): + * xDiff = (a[0] - origin[0]) * (b[0] - origin[0]) + * yDiff = (a[1] - origin[1]) * (b[1] - origin[1]) # <<<<<<<<<<<<<< + * return not (xDiff <= 0.0 and yDiff <= 0.0) + * +*/ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_a, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1150, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_origin, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1150, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyNumber_Subtract(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1150, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_b, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1150, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_origin, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1150, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Subtract(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1150, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1150, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_yDiff = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1151 + * xDiff = (a[0] - origin[0]) * (b[0] - origin[0]) + * yDiff = (a[1] - origin[1]) * (b[1] - origin[1]) + * return not (xDiff <= 0.0 and yDiff <= 0.0) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyObject_RichCompare(__pyx_v_xDiff, __pyx_mstate_global->__pyx_float_0_0, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1151, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(0, 1151, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_6) { + } else { + __pyx_t_5 = __pyx_t_6; + goto __pyx_L3_bool_binop_done; + } + __pyx_t_1 = PyObject_RichCompare(__pyx_v_yDiff, __pyx_mstate_global->__pyx_float_0_0, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1151, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(0, 1151, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = __pyx_t_6; + __pyx_L3_bool_binop_done:; + __pyx_t_1 = __Pyx_PyBool_FromLong((!__pyx_t_5)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1151, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1148 + * + * + * def _both_points_are_on_same_side_of_origin(a, b, origin): # <<<<<<<<<<<<<< + * xDiff = (a[0] - origin[0]) * (b[0] - origin[0]) + * yDiff = (a[1] - origin[1]) * (b[1] - origin[1]) +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("fontTools.misc.bezierTools._both_points_are_on_same_side_of_origin", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_xDiff); + __Pyx_XDECREF(__pyx_v_yDiff); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1154 + * + * + * def lineLineIntersections(s1, e1, s2, e2): # <<<<<<<<<<<<<< + * """Finds intersections between two line segments. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_73lineLineIntersections(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_72lineLineIntersections, "lineLineIntersections(s1, e1, s2, e2)\n\nFinds intersections between two line segments.\n\nArgs:\n s1, e1: Coordinates of the first line as 2D tuples.\n s2, e2: Coordinates of the second line as 2D tuples.\n\nReturns:\n A list of ``Intersection`` objects, each object having ``pt``, ``t1``\n and ``t2`` attributes containing the intersection point, time on first\n segment and time on second segment respectively.\n\nExamples::\n\n >>> a = lineLineIntersections( (310,389), (453, 222), (289, 251), (447, 367))\n >>> len(a)\n 1\n >>> intersection = a[0]\n >>> intersection.pt\n (374.44882952482897, 313.73458370177315)\n >>> (intersection.t1, intersection.t2)\n (0.45069111555824465, 0.5408153767394238)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_73lineLineIntersections = {"lineLineIntersections", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_73lineLineIntersections, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_72lineLineIntersections}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_73lineLineIntersections(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_s1 = 0; + PyObject *__pyx_v_e1 = 0; + PyObject *__pyx_v_s2 = 0; + PyObject *__pyx_v_e2 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("lineLineIntersections (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_s1,&__pyx_mstate_global->__pyx_n_u_e1,&__pyx_mstate_global->__pyx_n_u_s2,&__pyx_mstate_global->__pyx_n_u_e2,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1154, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 1154, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1154, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1154, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1154, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "lineLineIntersections", 0) < (0)) __PYX_ERR(0, 1154, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("lineLineIntersections", 1, 4, 4, i); __PYX_ERR(0, 1154, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1154, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1154, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1154, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 1154, __pyx_L3_error) + } + __pyx_v_s1 = values[0]; + __pyx_v_e1 = values[1]; + __pyx_v_s2 = values[2]; + __pyx_v_e2 = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("lineLineIntersections", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 1154, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.lineLineIntersections", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_72lineLineIntersections(__pyx_self, __pyx_v_s1, __pyx_v_e1, __pyx_v_s2, __pyx_v_e2); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_72lineLineIntersections(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_s1, PyObject *__pyx_v_e1, PyObject *__pyx_v_s2, PyObject *__pyx_v_e2) { + PyObject *__pyx_v_s1x = NULL; + PyObject *__pyx_v_s1y = NULL; + PyObject *__pyx_v_e1x = NULL; + PyObject *__pyx_v_e1y = NULL; + PyObject *__pyx_v_s2x = NULL; + PyObject *__pyx_v_s2y = NULL; + PyObject *__pyx_v_e2x = NULL; + PyObject *__pyx_v_e2y = NULL; + PyObject *__pyx_v_x = NULL; + PyObject *__pyx_v_slope34 = NULL; + PyObject *__pyx_v_y = NULL; + PyObject *__pyx_v_pt = NULL; + PyObject *__pyx_v_slope12 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *(*__pyx_t_4)(PyObject *); + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + size_t __pyx_t_7; + int __pyx_t_8; + int __pyx_t_9; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("lineLineIntersections", 0); + + /* "fontTools/misc/bezierTools.py":1177 + * (0.45069111555824465, 0.5408153767394238) + * """ + * s1x, s1y = s1 # <<<<<<<<<<<<<< + * e1x, e1y = e1 + * s2x, s2y = s2 +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_s1))) || (PyList_CheckExact(__pyx_v_s1))) { + PyObject* sequence = __pyx_v_s1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1177, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1177, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1177, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1177, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1177, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_s1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1177, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 1177, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1177, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_s1x = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_s1y = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1178 + * """ + * s1x, s1y = s1 + * e1x, e1y = e1 # <<<<<<<<<<<<<< + * s2x, s2y = s2 + * e2x, e2y = e2 +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_e1))) || (PyList_CheckExact(__pyx_v_e1))) { + PyObject* sequence = __pyx_v_e1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1178, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1178, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1178, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1178, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1178, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_e1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1178, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 1178, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1178, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_e1x = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_e1y = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1179 + * s1x, s1y = s1 + * e1x, e1y = e1 + * s2x, s2y = s2 # <<<<<<<<<<<<<< + * e2x, e2y = e2 + * if ( +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_s2))) || (PyList_CheckExact(__pyx_v_s2))) { + PyObject* sequence = __pyx_v_s2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1179, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_s2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1179, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 1179, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1179, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_v_s2x = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_s2y = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1180 + * e1x, e1y = e1 + * s2x, s2y = s2 + * e2x, e2y = e2 # <<<<<<<<<<<<<< + * if ( + * math.isclose(s2x, e2x) and math.isclose(s1x, e1x) and not math.isclose(s1x, s2x) +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_e2))) || (PyList_CheckExact(__pyx_v_e2))) { + PyObject* sequence = __pyx_v_e2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1180, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1180, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1180, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1180, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1180, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_e2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1180, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 1180, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1180, __pyx_L1_error) + __pyx_L10_unpacking_done:; + } + __pyx_v_e2x = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_e2y = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1182 + * e2x, e2y = e2 + * if ( + * math.isclose(s2x, e2x) and math.isclose(s1x, e1x) and not math.isclose(s1x, s2x) # <<<<<<<<<<<<<< + * ): # Parallel vertical + * return [] +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_isclose); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_6); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_6, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_v_s2x, __pyx_v_e2x}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_6, __pyx_callargs+__pyx_t_7, (3-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_8) { + } else { + __pyx_t_5 = __pyx_t_8; + goto __pyx_L12_bool_binop_done; + } + __pyx_t_6 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_isclose); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_6); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_6, __pyx_v_s1x, __pyx_v_e1x}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_7, (3-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_8) { + } else { + __pyx_t_5 = __pyx_t_8; + goto __pyx_L12_bool_binop_done; + } + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_isclose); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_3); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_v_s1x, __pyx_v_s2x}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_7, (3-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 1182, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_9 = (!__pyx_t_8); + __pyx_t_5 = __pyx_t_9; + __pyx_L12_bool_binop_done:; + + /* "fontTools/misc/bezierTools.py":1181 + * s2x, s2y = s2 + * e2x, e2y = e2 + * if ( # <<<<<<<<<<<<<< + * math.isclose(s2x, e2x) and math.isclose(s1x, e1x) and not math.isclose(s1x, s2x) + * ): # Parallel vertical +*/ + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1184 + * math.isclose(s2x, e2x) and math.isclose(s1x, e1x) and not math.isclose(s1x, s2x) + * ): # Parallel vertical + * return [] # <<<<<<<<<<<<<< + * if ( + * math.isclose(s2y, e2y) and math.isclose(s1y, e1y) and not math.isclose(s1y, s2y) +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1184, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1181 + * s2x, s2y = s2 + * e2x, e2y = e2 + * if ( # <<<<<<<<<<<<<< + * math.isclose(s2x, e2x) and math.isclose(s1x, e1x) and not math.isclose(s1x, s2x) + * ): # Parallel vertical +*/ + } + + /* "fontTools/misc/bezierTools.py":1186 + * return [] + * if ( + * math.isclose(s2y, e2y) and math.isclose(s1y, e1y) and not math.isclose(s1y, s2y) # <<<<<<<<<<<<<< + * ): # Parallel horizontal + * return [] +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1186, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_isclose); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1186, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_6); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_6, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_v_s2y, __pyx_v_e2y}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_6, __pyx_callargs+__pyx_t_7, (3-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1186, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_9 < 0))) __PYX_ERR(0, 1186, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_9) { + } else { + __pyx_t_5 = __pyx_t_9; + goto __pyx_L16_bool_binop_done; + } + __pyx_t_6 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1186, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_isclose); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1186, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_6); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_6, __pyx_v_s1y, __pyx_v_e1y}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_7, (3-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1186, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_9 < 0))) __PYX_ERR(0, 1186, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_9) { + } else { + __pyx_t_5 = __pyx_t_9; + goto __pyx_L16_bool_binop_done; + } + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1186, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_isclose); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1186, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_3); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_v_s1y, __pyx_v_s2y}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_7, (3-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1186, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_9 < 0))) __PYX_ERR(0, 1186, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_8 = (!__pyx_t_9); + __pyx_t_5 = __pyx_t_8; + __pyx_L16_bool_binop_done:; + + /* "fontTools/misc/bezierTools.py":1185 + * ): # Parallel vertical + * return [] + * if ( # <<<<<<<<<<<<<< + * math.isclose(s2y, e2y) and math.isclose(s1y, e1y) and not math.isclose(s1y, s2y) + * ): # Parallel horizontal +*/ + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1188 + * math.isclose(s2y, e2y) and math.isclose(s1y, e1y) and not math.isclose(s1y, s2y) + * ): # Parallel horizontal + * return [] # <<<<<<<<<<<<<< + * if math.isclose(s2x, e2x) and math.isclose(s2y, e2y): # Line segment is tiny + * return [] +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1188, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1185 + * ): # Parallel vertical + * return [] + * if ( # <<<<<<<<<<<<<< + * math.isclose(s2y, e2y) and math.isclose(s1y, e1y) and not math.isclose(s1y, s2y) + * ): # Parallel horizontal +*/ + } + + /* "fontTools/misc/bezierTools.py":1189 + * ): # Parallel horizontal + * return [] + * if math.isclose(s2x, e2x) and math.isclose(s2y, e2y): # Line segment is tiny # <<<<<<<<<<<<<< + * return [] + * if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1189, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_isclose); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1189, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_6); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_6, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_v_s2x, __pyx_v_e2x}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_6, __pyx_callargs+__pyx_t_7, (3-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1189, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 1189, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_8) { + } else { + __pyx_t_5 = __pyx_t_8; + goto __pyx_L20_bool_binop_done; + } + __pyx_t_6 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1189, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_isclose); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1189, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_6); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_6, __pyx_v_s2y, __pyx_v_e2y}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_7, (3-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1189, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 1189, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = __pyx_t_8; + __pyx_L20_bool_binop_done:; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1190 + * return [] + * if math.isclose(s2x, e2x) and math.isclose(s2y, e2y): # Line segment is tiny + * return [] # <<<<<<<<<<<<<< + * if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny + * return [] +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1190, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1189 + * ): # Parallel horizontal + * return [] + * if math.isclose(s2x, e2x) and math.isclose(s2y, e2y): # Line segment is tiny # <<<<<<<<<<<<<< + * return [] + * if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny +*/ + } + + /* "fontTools/misc/bezierTools.py":1191 + * if math.isclose(s2x, e2x) and math.isclose(s2y, e2y): # Line segment is tiny + * return [] + * if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny # <<<<<<<<<<<<<< + * return [] + * if math.isclose(e1x, s1x): +*/ + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1191, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_isclose); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1191, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_3); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_3, __pyx_v_s1x, __pyx_v_e1x}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_7, (3-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1191, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 1191, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_8) { + } else { + __pyx_t_5 = __pyx_t_8; + goto __pyx_L23_bool_binop_done; + } + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1191, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_isclose); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1191, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_6); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_6, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_v_s1y, __pyx_v_e1y}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_6, __pyx_callargs+__pyx_t_7, (3-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1191, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 1191, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = __pyx_t_8; + __pyx_L23_bool_binop_done:; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1192 + * return [] + * if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny + * return [] # <<<<<<<<<<<<<< + * if math.isclose(e1x, s1x): + * x = s1x +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1192, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1191 + * if math.isclose(s2x, e2x) and math.isclose(s2y, e2y): # Line segment is tiny + * return [] + * if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny # <<<<<<<<<<<<<< + * return [] + * if math.isclose(e1x, s1x): +*/ + } + + /* "fontTools/misc/bezierTools.py":1193 + * if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny + * return [] + * if math.isclose(e1x, s1x): # <<<<<<<<<<<<<< + * x = s1x + * slope34 = (e2y - s2y) / (e2x - s2x) +*/ + __pyx_t_6 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1193, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_isclose); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1193, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_6); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_6, __pyx_v_e1x, __pyx_v_s1x}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_7, (3-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1193, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1193, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1194 + * return [] + * if math.isclose(e1x, s1x): + * x = s1x # <<<<<<<<<<<<<< + * slope34 = (e2y - s2y) / (e2x - s2x) + * y = slope34 * (x - s2x) + s2y +*/ + __Pyx_INCREF(__pyx_v_s1x); + __pyx_v_x = __pyx_v_s1x; + + /* "fontTools/misc/bezierTools.py":1195 + * if math.isclose(e1x, s1x): + * x = s1x + * slope34 = (e2y - s2y) / (e2x - s2x) # <<<<<<<<<<<<<< + * y = slope34 * (x - s2x) + s2y + * pt = (x, y) +*/ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_e2y, __pyx_v_s2y); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1195, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyNumber_Subtract(__pyx_v_e2x, __pyx_v_s2x); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1195, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1195, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_slope34 = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":1196 + * x = s1x + * slope34 = (e2y - s2y) / (e2x - s2x) + * y = slope34 * (x - s2x) + s2y # <<<<<<<<<<<<<< + * pt = (x, y) + * return [ +*/ + __pyx_t_6 = PyNumber_Subtract(__pyx_v_x, __pyx_v_s2x); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1196, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = PyNumber_Multiply(__pyx_v_slope34, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1196, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyNumber_Add(__pyx_t_3, __pyx_v_s2y); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1196, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_y = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":1197 + * slope34 = (e2y - s2y) / (e2x - s2x) + * y = slope34 * (x - s2x) + s2y + * pt = (x, y) # <<<<<<<<<<<<<< + * return [ + * Intersection( +*/ + __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1197, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_v_x) != (0)) __PYX_ERR(0, 1197, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y); + __Pyx_GIVEREF(__pyx_v_y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_v_y) != (0)) __PYX_ERR(0, 1197, __pyx_L1_error); + __pyx_v_pt = ((PyObject*)__pyx_t_6); + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":1198 + * y = slope34 * (x - s2x) + s2y + * pt = (x, y) + * return [ # <<<<<<<<<<<<<< + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) +*/ + __Pyx_XDECREF(__pyx_r); + + /* "fontTools/misc/bezierTools.py":1199 + * pt = (x, y) + * return [ + * Intersection( # <<<<<<<<<<<<<< + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + * ) +*/ + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_Intersection); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1199, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/misc/bezierTools.py":1200 + * return [ + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) # <<<<<<<<<<<<<< + * ) + * ] +*/ + __pyx_t_10 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_mstate_global->__pyx_n_u_line_t_of_pt); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1200, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_11))) { + __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_11); + assert(__pyx_t_10); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_11); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_11, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_10, __pyx_v_s1, __pyx_v_e1, __pyx_v_pt}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_11, __pyx_callargs+__pyx_t_7, (4-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1200, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __pyx_t_10 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_12, __pyx_mstate_global->__pyx_n_u_line_t_of_pt); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1200, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_12))) { + __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_12); + assert(__pyx_t_10); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_12); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_12, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_10, __pyx_v_s2, __pyx_v_e2, __pyx_v_pt}; + __pyx_t_11 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_12, __pyx_callargs+__pyx_t_7, (4-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1200, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + } + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_3); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[2 + ((CYTHON_VECTORCALL) ? 3 : 0)] = {__pyx_t_3, NULL}; + __pyx_t_12 = __Pyx_MakeVectorcallBuilderKwds(3); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1199, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_pt, __pyx_v_pt, __pyx_t_12, __pyx_callargs+1, 0) < (0)) __PYX_ERR(0, 1199, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_t1, __pyx_t_2, __pyx_t_12, __pyx_callargs+1, 1) < (0)) __PYX_ERR(0, 1199, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_t2, __pyx_t_11, __pyx_t_12, __pyx_callargs+1, 2) < (0)) __PYX_ERR(0, 1199, __pyx_L1_error) + __pyx_t_6 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_7, (1-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_12); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1199, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + + /* "fontTools/misc/bezierTools.py":1198 + * y = slope34 * (x - s2x) + s2y + * pt = (x, y) + * return [ # <<<<<<<<<<<<<< + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) +*/ + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1198, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_t_6) != (0)) __PYX_ERR(0, 1198, __pyx_L1_error); + __pyx_t_6 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1193 + * if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny + * return [] + * if math.isclose(e1x, s1x): # <<<<<<<<<<<<<< + * x = s1x + * slope34 = (e2y - s2y) / (e2x - s2x) +*/ + } + + /* "fontTools/misc/bezierTools.py":1203 + * ) + * ] + * if math.isclose(s2x, e2x): # <<<<<<<<<<<<<< + * x = s2x + * slope12 = (e1y - s1y) / (e1x - s1x) +*/ + __pyx_t_6 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_12, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1203, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_12, __pyx_mstate_global->__pyx_n_u_isclose); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1203, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_11))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_11); + assert(__pyx_t_6); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_11); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_11, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_6, __pyx_v_s2x, __pyx_v_e2x}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_11, __pyx_callargs+__pyx_t_7, (3-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1203, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1203, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1204 + * ] + * if math.isclose(s2x, e2x): + * x = s2x # <<<<<<<<<<<<<< + * slope12 = (e1y - s1y) / (e1x - s1x) + * y = slope12 * (x - s1x) + s1y +*/ + __Pyx_INCREF(__pyx_v_s2x); + __pyx_v_x = __pyx_v_s2x; + + /* "fontTools/misc/bezierTools.py":1205 + * if math.isclose(s2x, e2x): + * x = s2x + * slope12 = (e1y - s1y) / (e1x - s1x) # <<<<<<<<<<<<<< + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) +*/ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_e1y, __pyx_v_s1y); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1205, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_11 = PyNumber_Subtract(__pyx_v_e1x, __pyx_v_s1x); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1205, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_6 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_t_11); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1205, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __pyx_v_slope12 = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":1206 + * x = s2x + * slope12 = (e1y - s1y) / (e1x - s1x) + * y = slope12 * (x - s1x) + s1y # <<<<<<<<<<<<<< + * pt = (x, y) + * return [ +*/ + __pyx_t_6 = PyNumber_Subtract(__pyx_v_x, __pyx_v_s1x); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1206, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_11 = PyNumber_Multiply(__pyx_v_slope12, __pyx_t_6); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1206, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyNumber_Add(__pyx_t_11, __pyx_v_s1y); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1206, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __pyx_v_y = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":1207 + * slope12 = (e1y - s1y) / (e1x - s1x) + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) # <<<<<<<<<<<<<< + * return [ + * Intersection( +*/ + __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1207, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_v_x) != (0)) __PYX_ERR(0, 1207, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y); + __Pyx_GIVEREF(__pyx_v_y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_v_y) != (0)) __PYX_ERR(0, 1207, __pyx_L1_error); + __pyx_v_pt = ((PyObject*)__pyx_t_6); + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":1208 + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) + * return [ # <<<<<<<<<<<<<< + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) +*/ + __Pyx_XDECREF(__pyx_r); + + /* "fontTools/misc/bezierTools.py":1209 + * pt = (x, y) + * return [ + * Intersection( # <<<<<<<<<<<<<< + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + * ) +*/ + __pyx_t_11 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_Intersection); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1209, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/misc/bezierTools.py":1210 + * return [ + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) # <<<<<<<<<<<<<< + * ) + * ] +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_line_t_of_pt); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1210, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_2, __pyx_v_s1, __pyx_v_e1, __pyx_v_pt}; + __pyx_t_12 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_7, (4-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1210, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + } + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_line_t_of_pt); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1210, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_10))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_10); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_10); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_10, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_2, __pyx_v_s2, __pyx_v_e2, __pyx_v_pt}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_10, __pyx_callargs+__pyx_t_7, (4-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1210, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_11); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_11); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[2 + ((CYTHON_VECTORCALL) ? 3 : 0)] = {__pyx_t_11, NULL}; + __pyx_t_10 = __Pyx_MakeVectorcallBuilderKwds(3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1209, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_pt, __pyx_v_pt, __pyx_t_10, __pyx_callargs+1, 0) < (0)) __PYX_ERR(0, 1209, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_t1, __pyx_t_12, __pyx_t_10, __pyx_callargs+1, 1) < (0)) __PYX_ERR(0, 1209, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_t2, __pyx_t_3, __pyx_t_10, __pyx_callargs+1, 2) < (0)) __PYX_ERR(0, 1209, __pyx_L1_error) + __pyx_t_6 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_7, (1-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1209, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + + /* "fontTools/misc/bezierTools.py":1208 + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) + * return [ # <<<<<<<<<<<<<< + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) +*/ + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1208, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_6); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_t_6) != (0)) __PYX_ERR(0, 1208, __pyx_L1_error); + __pyx_t_6 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1203 + * ) + * ] + * if math.isclose(s2x, e2x): # <<<<<<<<<<<<<< + * x = s2x + * slope12 = (e1y - s1y) / (e1x - s1x) +*/ + } + + /* "fontTools/misc/bezierTools.py":1214 + * ] + * + * slope12 = (e1y - s1y) / (e1x - s1x) # <<<<<<<<<<<<<< + * slope34 = (e2y - s2y) / (e2x - s2x) + * if math.isclose(slope12, slope34): +*/ + __pyx_t_1 = PyNumber_Subtract(__pyx_v_e1y, __pyx_v_s1y); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1214, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = PyNumber_Subtract(__pyx_v_e1x, __pyx_v_s1x); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1214, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_10 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_t_6); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1214, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_v_slope12 = __pyx_t_10; + __pyx_t_10 = 0; + + /* "fontTools/misc/bezierTools.py":1215 + * + * slope12 = (e1y - s1y) / (e1x - s1x) + * slope34 = (e2y - s2y) / (e2x - s2x) # <<<<<<<<<<<<<< + * if math.isclose(slope12, slope34): + * return [] +*/ + __pyx_t_10 = PyNumber_Subtract(__pyx_v_e2y, __pyx_v_s2y); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1215, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_6 = PyNumber_Subtract(__pyx_v_e2x, __pyx_v_s2x); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1215, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_1 = __Pyx_PyNumber_Divide(__pyx_t_10, __pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1215, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_v_slope34 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1216 + * slope12 = (e1y - s1y) / (e1x - s1x) + * slope34 = (e2y - s2y) / (e2x - s2x) + * if math.isclose(slope12, slope34): # <<<<<<<<<<<<<< + * return [] + * x = (slope12 * s1x - s1y - slope34 * s2x + s2y) / (slope12 - slope34) +*/ + __pyx_t_6 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1216, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_isclose); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1216, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_6); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_6, __pyx_v_slope12, __pyx_v_slope34}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_7, (3-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1216, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1216, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1217 + * slope34 = (e2y - s2y) / (e2x - s2x) + * if math.isclose(slope12, slope34): + * return [] # <<<<<<<<<<<<<< + * x = (slope12 * s1x - s1y - slope34 * s2x + s2y) / (slope12 - slope34) + * y = slope12 * (x - s1x) + s1y +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1217, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1216 + * slope12 = (e1y - s1y) / (e1x - s1x) + * slope34 = (e2y - s2y) / (e2x - s2x) + * if math.isclose(slope12, slope34): # <<<<<<<<<<<<<< + * return [] + * x = (slope12 * s1x - s1y - slope34 * s2x + s2y) / (slope12 - slope34) +*/ + } + + /* "fontTools/misc/bezierTools.py":1218 + * if math.isclose(slope12, slope34): + * return [] + * x = (slope12 * s1x - s1y - slope34 * s2x + s2y) / (slope12 - slope34) # <<<<<<<<<<<<<< + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) +*/ + __pyx_t_1 = PyNumber_Multiply(__pyx_v_slope12, __pyx_v_s1x); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyNumber_Subtract(__pyx_t_1, __pyx_v_s1y); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Multiply(__pyx_v_slope34, __pyx_v_s2x); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = PyNumber_Subtract(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyNumber_Add(__pyx_t_6, __pyx_v_s2y); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyNumber_Subtract(__pyx_v_slope12, __pyx_v_slope34); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_v_x = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1219 + * return [] + * x = (slope12 * s1x - s1y - slope34 * s2x + s2y) / (slope12 - slope34) + * y = slope12 * (x - s1x) + s1y # <<<<<<<<<<<<<< + * pt = (x, y) + * if _both_points_are_on_same_side_of_origin( +*/ + __pyx_t_3 = PyNumber_Subtract(__pyx_v_x, __pyx_v_s1x); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1219, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = PyNumber_Multiply(__pyx_v_slope12, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1219, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyNumber_Add(__pyx_t_6, __pyx_v_s1y); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1219, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_v_y = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1220 + * x = (slope12 * s1x - s1y - slope34 * s2x + s2y) / (slope12 - slope34) + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) # <<<<<<<<<<<<<< + * if _both_points_are_on_same_side_of_origin( + * pt, e1, s1 +*/ + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1220, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_x); + __Pyx_GIVEREF(__pyx_v_x); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x) != (0)) __PYX_ERR(0, 1220, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_y); + __Pyx_GIVEREF(__pyx_v_y); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_y) != (0)) __PYX_ERR(0, 1220, __pyx_L1_error); + __pyx_v_pt = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1221 + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) + * if _both_points_are_on_same_side_of_origin( # <<<<<<<<<<<<<< + * pt, e1, s1 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): +*/ + __pyx_t_6 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_both_points_are_on_same_side_of); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1221, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/misc/bezierTools.py":1222 + * pt = (x, y) + * if _both_points_are_on_same_side_of_origin( + * pt, e1, s1 # <<<<<<<<<<<<<< + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): + * return [ +*/ + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_6); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_6, __pyx_v_pt, __pyx_v_e1, __pyx_v_s1}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_7, (4-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1221, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + + /* "fontTools/misc/bezierTools.py":1221 + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) + * if _both_points_are_on_same_side_of_origin( # <<<<<<<<<<<<<< + * pt, e1, s1 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): +*/ + __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 1221, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_8) { + } else { + __pyx_t_5 = __pyx_t_8; + goto __pyx_L29_bool_binop_done; + } + + /* "fontTools/misc/bezierTools.py":1223 + * if _both_points_are_on_same_side_of_origin( + * pt, e1, s1 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): # <<<<<<<<<<<<<< + * return [ + * Intersection( +*/ + __pyx_t_1 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_both_points_are_on_same_side_of); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1223, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_6); + assert(__pyx_t_1); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_6, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_1, __pyx_v_pt, __pyx_v_s2, __pyx_v_e2}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_6, __pyx_callargs+__pyx_t_7, (4-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1223, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 1223, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_5 = __pyx_t_8; + __pyx_L29_bool_binop_done:; + + /* "fontTools/misc/bezierTools.py":1221 + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) + * if _both_points_are_on_same_side_of_origin( # <<<<<<<<<<<<<< + * pt, e1, s1 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): +*/ + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1224 + * pt, e1, s1 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): + * return [ # <<<<<<<<<<<<<< + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) +*/ + __Pyx_XDECREF(__pyx_r); + + /* "fontTools/misc/bezierTools.py":1225 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): + * return [ + * Intersection( # <<<<<<<<<<<<<< + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + * ) +*/ + __pyx_t_6 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_Intersection); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1225, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/misc/bezierTools.py":1226 + * return [ + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) # <<<<<<<<<<<<<< + * ) + * ] +*/ + __pyx_t_12 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_mstate_global->__pyx_n_u_line_t_of_pt); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1226, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_11))) { + __pyx_t_12 = PyMethod_GET_SELF(__pyx_t_11); + assert(__pyx_t_12); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_11); + __Pyx_INCREF(__pyx_t_12); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_11, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_12, __pyx_v_s1, __pyx_v_e1, __pyx_v_pt}; + __pyx_t_10 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_11, __pyx_callargs+__pyx_t_7, (4-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1226, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + } + __pyx_t_12 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_line_t_of_pt); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1226, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_12 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_12); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_12); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_12, __pyx_v_s2, __pyx_v_e2, __pyx_v_pt}; + __pyx_t_11 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_7, (4-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1226, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + } + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_6); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[2 + ((CYTHON_VECTORCALL) ? 3 : 0)] = {__pyx_t_6, NULL}; + __pyx_t_2 = __Pyx_MakeVectorcallBuilderKwds(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1225, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_pt, __pyx_v_pt, __pyx_t_2, __pyx_callargs+1, 0) < (0)) __PYX_ERR(0, 1225, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_t1, __pyx_t_10, __pyx_t_2, __pyx_callargs+1, 1) < (0)) __PYX_ERR(0, 1225, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_t2, __pyx_t_11, __pyx_t_2, __pyx_callargs+1, 2) < (0)) __PYX_ERR(0, 1225, __pyx_L1_error) + __pyx_t_3 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_7, (1-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_2); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1225, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + + /* "fontTools/misc/bezierTools.py":1224 + * pt, e1, s1 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): + * return [ # <<<<<<<<<<<<<< + * Intersection( + * pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) +*/ + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1224, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyList_SET_ITEM(__pyx_t_1, 0, __pyx_t_3) != (0)) __PYX_ERR(0, 1224, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1221 + * y = slope12 * (x - s1x) + s1y + * pt = (x, y) + * if _both_points_are_on_same_side_of_origin( # <<<<<<<<<<<<<< + * pt, e1, s1 + * ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): +*/ + } + + /* "fontTools/misc/bezierTools.py":1229 + * ) + * ] + * return [] # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1229, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1154 + * + * + * def lineLineIntersections(s1, e1, s2, e2): # <<<<<<<<<<<<<< + * """Finds intersections between two line segments. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_AddTraceback("fontTools.misc.bezierTools.lineLineIntersections", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_s1x); + __Pyx_XDECREF(__pyx_v_s1y); + __Pyx_XDECREF(__pyx_v_e1x); + __Pyx_XDECREF(__pyx_v_e1y); + __Pyx_XDECREF(__pyx_v_s2x); + __Pyx_XDECREF(__pyx_v_s2y); + __Pyx_XDECREF(__pyx_v_e2x); + __Pyx_XDECREF(__pyx_v_e2y); + __Pyx_XDECREF(__pyx_v_x); + __Pyx_XDECREF(__pyx_v_slope34); + __Pyx_XDECREF(__pyx_v_y); + __Pyx_XDECREF(__pyx_v_pt); + __Pyx_XDECREF(__pyx_v_slope12); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1232 + * + * + * def _alignment_transformation(segment): # <<<<<<<<<<<<<< + * # Returns a transformation which aligns a segment horizontally at the + * # origin. Apply this transformation to curves and root-find to find +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_75_alignment_transformation(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_74_alignment_transformation, "_alignment_transformation(segment)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_75_alignment_transformation = {"_alignment_transformation", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_75_alignment_transformation, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_74_alignment_transformation}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_75_alignment_transformation(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_segment = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_alignment_transformation (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_segment,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1232, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1232, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_alignment_transformation", 0) < (0)) __PYX_ERR(0, 1232, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_alignment_transformation", 1, 1, 1, i); __PYX_ERR(0, 1232, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1232, __pyx_L3_error) + } + __pyx_v_segment = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_alignment_transformation", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 1232, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._alignment_transformation", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_74_alignment_transformation(__pyx_self, __pyx_v_segment); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_74_alignment_transformation(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_segment) { + PyObject *__pyx_v_start = NULL; + PyObject *__pyx_v_end = NULL; + PyObject *__pyx_v_angle = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + size_t __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_alignment_transformation", 0); + + /* "fontTools/misc/bezierTools.py":1236 + * # origin. Apply this transformation to curves and root-find to find + * # intersections with the segment. + * start = segment[0] # <<<<<<<<<<<<<< + * end = segment[-1] + * angle = math.atan2(end[1] - start[1], end[0] - start[0]) +*/ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_segment, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1236, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_start = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1237 + * # intersections with the segment. + * start = segment[0] + * end = segment[-1] # <<<<<<<<<<<<<< + * angle = math.atan2(end[1] - start[1], end[0] - start[0]) + * return Identity.rotate(-angle).translate(-start[0], -start[1]) +*/ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_segment, -1L, long, 1, __Pyx_PyLong_From_long, 0, 1, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1237, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_end = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1238 + * start = segment[0] + * end = segment[-1] + * angle = math.atan2(end[1] - start[1], end[0] - start[0]) # <<<<<<<<<<<<<< + * return Identity.rotate(-angle).translate(-start[0], -start[1]) + * +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_atan2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_end, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_start, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = PyNumber_Subtract(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_end, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_start, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = PyNumber_Subtract(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_8 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_4); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_4, __pyx__function); + __pyx_t_8 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_t_6, __pyx_t_7}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_4, __pyx_callargs+__pyx_t_8, (3-__pyx_t_8) | (__pyx_t_8*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_v_angle = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1239 + * end = segment[-1] + * angle = math.atan2(end[1] - start[1], end[0] - start[0]) + * return Identity.rotate(-angle).translate(-start[0], -start[1]) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_6 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_Identity); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_rotate); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Negative(__pyx_v_angle); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_8 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_6); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_8 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_t_2}; + __pyx_t_7 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_8, (2-__pyx_t_8) | (__pyx_t_8*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + } + __pyx_t_4 = __pyx_t_7; + __Pyx_INCREF(__pyx_t_4); + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_start, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyNumber_Negative(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_start, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = PyNumber_Negative(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_8 = 0; + { + PyObject *__pyx_callargs[3] = {__pyx_t_4, __pyx_t_2, __pyx_t_6}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_translate, __pyx_callargs+__pyx_t_8, (3-__pyx_t_8) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1232 + * + * + * def _alignment_transformation(segment): # <<<<<<<<<<<<<< + * # Returns a transformation which aligns a segment horizontally at the + * # origin. Apply this transformation to curves and root-find to find +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("fontTools.misc.bezierTools._alignment_transformation", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_start); + __Pyx_XDECREF(__pyx_v_end); + __Pyx_XDECREF(__pyx_v_angle); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1242 + * + * + * def _curve_line_intersections_t(curve, line): # <<<<<<<<<<<<<< + * aligned_curve = _alignment_transformation(line).transformPoints(curve) + * if len(curve) == 3: +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_77_curve_line_intersections_t(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_76_curve_line_intersections_t, "_curve_line_intersections_t(curve, line)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_77_curve_line_intersections_t = {"_curve_line_intersections_t", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_77_curve_line_intersections_t, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_76_curve_line_intersections_t}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_77_curve_line_intersections_t(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_curve = 0; + PyObject *__pyx_v_line = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_curve_line_intersections_t (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_curve,&__pyx_mstate_global->__pyx_n_u_line,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1242, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1242, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1242, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_curve_line_intersections_t", 0) < (0)) __PYX_ERR(0, 1242, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_curve_line_intersections_t", 1, 2, 2, i); __PYX_ERR(0, 1242, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1242, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1242, __pyx_L3_error) + } + __pyx_v_curve = values[0]; + __pyx_v_line = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_curve_line_intersections_t", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 1242, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_line_intersections_t", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_76_curve_line_intersections_t(__pyx_self, __pyx_v_curve, __pyx_v_line); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_27_curve_line_intersections_t_2generator4(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/misc/bezierTools.py":1252 + * else: + * raise ValueError("Unknown curve degree") + * return sorted(i for i in intersections if 0.0 <= i <= 1) # <<<<<<<<<<<<<< + * + * +*/ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_27_curve_line_intersections_t_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("genexpr", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr(__pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr, __pyx_mstate_global->__pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 1252, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_genexpr_arg_0 = __pyx_genexpr_arg_0; + __Pyx_INCREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_4misc_11bezierTools_27_curve_line_intersections_t_2generator4, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[4]), (PyObject *) __pyx_cur_scope, __pyx_mstate_global->__pyx_n_u_genexpr, __pyx_mstate_global->__pyx_n_u_curve_line_intersections_t_loca, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools); if (unlikely(!gen)) __PYX_ERR(0, 1252, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_line_intersections_t.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_27_curve_line_intersections_t_2generator4(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *(*__pyx_t_3)(PyObject *); + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("genexpr", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 1252, __pyx_L1_error) + __pyx_r = PyList_New(0); if (unlikely(!__pyx_r)) __PYX_ERR(0, 1252, __pyx_L1_error) + __Pyx_GOTREF(__pyx_r); + if (unlikely(!__pyx_cur_scope->__pyx_genexpr_arg_0)) { __Pyx_RaiseUnboundLocalError(".0"); __PYX_ERR(0, 1252, __pyx_L1_error) } + if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) { + __pyx_t_1 = __pyx_cur_scope->__pyx_genexpr_arg_0; __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = 0; + __pyx_t_3 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_genexpr_arg_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1252, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1252, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_3)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1252, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(__pyx_t_1, __pyx_t_2, __Pyx_ReferenceSharing_OwnStrongReference); + ++__pyx_t_2; + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1252, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = __Pyx_NewRef(PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2)); + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); + #endif + ++__pyx_t_2; + } + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1252, __pyx_L1_error) + } else { + __pyx_t_4 = __pyx_t_3(__pyx_t_1); + if (unlikely(!__pyx_t_4)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 1252, __pyx_L1_error) + PyErr_Clear(); + } + break; + } + } + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_i); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_i, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + __pyx_t_4 = 0; + __pyx_t_4 = PyObject_RichCompare(__pyx_mstate_global->__pyx_float_0_0, __pyx_cur_scope->__pyx_v_i, Py_LE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1252, __pyx_L1_error) + if (__Pyx_PyObject_IsTrue(__pyx_t_4)) { + __Pyx_DECREF(__pyx_t_4); + __pyx_t_4 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_i, __pyx_mstate_global->__pyx_int_1, Py_LE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1252, __pyx_L1_error) + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1252, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_5) { + if (unlikely(__Pyx_ListComp_Append(__pyx_r, (PyObject*)__pyx_cur_scope->__pyx_v_i))) __PYX_ERR(0, 1252, __pyx_L1_error) + } + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_r); __pyx_r = 0; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + if (__Pyx_PyErr_Occurred()) { + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1242 + * + * + * def _curve_line_intersections_t(curve, line): # <<<<<<<<<<<<<< + * aligned_curve = _alignment_transformation(line).transformPoints(curve) + * if len(curve) == 3: +*/ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_76_curve_line_intersections_t(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve, PyObject *__pyx_v_line) { + PyObject *__pyx_v_aligned_curve = NULL; + PyObject *__pyx_v_a = NULL; + PyObject *__pyx_v_b = NULL; + PyObject *__pyx_v_c = NULL; + PyObject *__pyx_v_intersections = NULL; + PyObject *__pyx_v_d = NULL; + PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_27_curve_line_intersections_t_2generator4 = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + size_t __pyx_t_6; + Py_ssize_t __pyx_t_7; + int __pyx_t_8; + PyObject *(*__pyx_t_9)(PyObject *); + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_curve_line_intersections_t", 0); + + /* "fontTools/misc/bezierTools.py":1243 + * + * def _curve_line_intersections_t(curve, line): + * aligned_curve = _alignment_transformation(line).transformPoints(curve) # <<<<<<<<<<<<<< + * if len(curve) == 3: + * a, b, c = calcQuadraticParameters(*aligned_curve) +*/ + __pyx_t_4 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_alignment_transformation); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1243, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5); + assert(__pyx_t_4); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_5, __pyx__function); + __pyx_t_6 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_v_line}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_5, __pyx_callargs+__pyx_t_6, (2-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1243, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __pyx_t_2 = __pyx_t_3; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_6 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_v_curve}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_transformPoints, __pyx_callargs+__pyx_t_6, (2-__pyx_t_6) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1243, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_v_aligned_curve = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1244 + * def _curve_line_intersections_t(curve, line): + * aligned_curve = _alignment_transformation(line).transformPoints(curve) + * if len(curve) == 3: # <<<<<<<<<<<<<< + * a, b, c = calcQuadraticParameters(*aligned_curve) + * intersections = solveQuadratic(a[1], b[1], c[1]) +*/ + __pyx_t_7 = PyObject_Length(__pyx_v_curve); if (unlikely(__pyx_t_7 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1244, __pyx_L1_error) + __pyx_t_8 = (__pyx_t_7 == 3); + if (__pyx_t_8) { + + /* "fontTools/misc/bezierTools.py":1245 + * aligned_curve = _alignment_transformation(line).transformPoints(curve) + * if len(curve) == 3: + * a, b, c = calcQuadraticParameters(*aligned_curve) # <<<<<<<<<<<<<< + * intersections = solveQuadratic(a[1], b[1], c[1]) + * elif len(curve) == 4: +*/ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_calcQuadraticParameters); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_aligned_curve); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_2))) || (PyList_CheckExact(__pyx_t_2))) { + PyObject* sequence = __pyx_t_2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 3)) { + if (size > 3) __Pyx_RaiseTooManyValuesError(3); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1245, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_3); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 2); + __Pyx_INCREF(__pyx_t_5); + } else { + __pyx_t_3 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_3); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_5 = __Pyx_PyList_GetItemRefFast(sequence, 2, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_5); + } + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __Pyx_PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_9 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); + index = 0; __pyx_t_3 = __pyx_t_9(__pyx_t_4); if (unlikely(!__pyx_t_3)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 1; __pyx_t_1 = __pyx_t_9(__pyx_t_4); if (unlikely(!__pyx_t_1)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 2; __pyx_t_5 = __pyx_t_9(__pyx_t_4); if (unlikely(!__pyx_t_5)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_5); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_4), 3) < (0)) __PYX_ERR(0, 1245, __pyx_L1_error) + __pyx_t_9 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L5_unpacking_done; + __pyx_L4_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_9 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1245, __pyx_L1_error) + __pyx_L5_unpacking_done:; + } + __pyx_v_a = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_b = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_c = __pyx_t_5; + __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":1246 + * if len(curve) == 3: + * a, b, c = calcQuadraticParameters(*aligned_curve) + * intersections = solveQuadratic(a[1], b[1], c[1]) # <<<<<<<<<<<<<< + * elif len(curve) == 4: + * a, b, c, d = calcCubicParameters(*aligned_curve) +*/ + __pyx_t_5 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_solveQuadratic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1246, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_a, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1246, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_b, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1246, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_c, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1246, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_6 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_5); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_6 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_5, __pyx_t_3, __pyx_t_4, __pyx_t_10}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_6, (4-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1246, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __pyx_v_intersections = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1244 + * def _curve_line_intersections_t(curve, line): + * aligned_curve = _alignment_transformation(line).transformPoints(curve) + * if len(curve) == 3: # <<<<<<<<<<<<<< + * a, b, c = calcQuadraticParameters(*aligned_curve) + * intersections = solveQuadratic(a[1], b[1], c[1]) +*/ + goto __pyx_L3; + } + + /* "fontTools/misc/bezierTools.py":1247 + * a, b, c = calcQuadraticParameters(*aligned_curve) + * intersections = solveQuadratic(a[1], b[1], c[1]) + * elif len(curve) == 4: # <<<<<<<<<<<<<< + * a, b, c, d = calcCubicParameters(*aligned_curve) + * intersections = solveCubic(a[1], b[1], c[1], d[1]) +*/ + __pyx_t_7 = PyObject_Length(__pyx_v_curve); if (unlikely(__pyx_t_7 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1247, __pyx_L1_error) + __pyx_t_8 = (__pyx_t_7 == 4); + if (likely(__pyx_t_8)) { + + /* "fontTools/misc/bezierTools.py":1248 + * intersections = solveQuadratic(a[1], b[1], c[1]) + * elif len(curve) == 4: + * a, b, c, d = calcCubicParameters(*aligned_curve) # <<<<<<<<<<<<<< + * intersections = solveCubic(a[1], b[1], c[1], d[1]) + * else: +*/ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_calcCubicParameters); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1248, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_Tuple(__pyx_v_aligned_curve); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1248, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_1, NULL); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1248, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_10))) || (PyList_CheckExact(__pyx_t_10))) { + PyObject* sequence = __pyx_t_10; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1248, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 2); + __Pyx_INCREF(__pyx_t_4); + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 3); + __Pyx_INCREF(__pyx_t_3); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1248, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1248, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(sequence, 2, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1248, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_4); + __pyx_t_3 = __Pyx_PyList_GetItemRefFast(sequence, 3, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1248, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_3); + } + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_1,&__pyx_t_2,&__pyx_t_4,&__pyx_t_3}; + for (i=0; i < 4; i++) { + PyObject* item = __Pyx_PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 1248, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + } else { + Py_ssize_t index = -1; + PyObject** temps[4] = {&__pyx_t_1,&__pyx_t_2,&__pyx_t_4,&__pyx_t_3}; + __pyx_t_5 = PyObject_GetIter(__pyx_t_10); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1248, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_9 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_5); + for (index=0; index < 4; index++) { + PyObject* item = __pyx_t_9(__pyx_t_5); if (unlikely(!item)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(item); + *(temps[index]) = item; + } + if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_5), 4) < (0)) __PYX_ERR(0, 1248, __pyx_L1_error) + __pyx_t_9 = NULL; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L7_unpacking_done; + __pyx_L6_unpacking_failed:; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_9 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1248, __pyx_L1_error) + __pyx_L7_unpacking_done:; + } + __pyx_v_a = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_b = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_c = __pyx_t_4; + __pyx_t_4 = 0; + __pyx_v_d = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1249 + * elif len(curve) == 4: + * a, b, c, d = calcCubicParameters(*aligned_curve) + * intersections = solveCubic(a[1], b[1], c[1], d[1]) # <<<<<<<<<<<<<< + * else: + * raise ValueError("Unknown curve degree") +*/ + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_solveCubic); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1249, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_a, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1249, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_b, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1249, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_c, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1249, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_11 = __Pyx_GetItemInt(__pyx_v_d, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_OwnStrongReference); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1249, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_6 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4); + assert(__pyx_t_3); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_4, __pyx__function); + __pyx_t_6 = 0; + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_3, __pyx_t_2, __pyx_t_1, __pyx_t_5, __pyx_t_11}; + __pyx_t_10 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_4, __pyx_callargs+__pyx_t_6, (5-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1249, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + } + __pyx_v_intersections = __pyx_t_10; + __pyx_t_10 = 0; + + /* "fontTools/misc/bezierTools.py":1247 + * a, b, c = calcQuadraticParameters(*aligned_curve) + * intersections = solveQuadratic(a[1], b[1], c[1]) + * elif len(curve) == 4: # <<<<<<<<<<<<<< + * a, b, c, d = calcCubicParameters(*aligned_curve) + * intersections = solveCubic(a[1], b[1], c[1], d[1]) +*/ + goto __pyx_L3; + } + + /* "fontTools/misc/bezierTools.py":1251 + * intersections = solveCubic(a[1], b[1], c[1], d[1]) + * else: + * raise ValueError("Unknown curve degree") # <<<<<<<<<<<<<< + * return sorted(i for i in intersections if 0.0 <= i <= 1) + * +*/ + /*else*/ { + __pyx_t_4 = NULL; + __pyx_t_6 = 1; + { + PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_mstate_global->__pyx_kp_u_Unknown_curve_degree}; + __pyx_t_10 = __Pyx_PyObject_FastCall((PyObject*)(((PyTypeObject*)PyExc_ValueError)), __pyx_callargs+__pyx_t_6, (2-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + } + __Pyx_Raise(__pyx_t_10, 0, 0, 0); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __PYX_ERR(0, 1251, __pyx_L1_error) + } + __pyx_L3:; + + /* "fontTools/misc/bezierTools.py":1252 + * else: + * raise ValueError("Unknown curve degree") + * return sorted(i for i in intersections if 0.0 <= i <= 1) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_10 = __pyx_pf_9fontTools_4misc_11bezierTools_27_curve_line_intersections_t_genexpr(NULL, __pyx_v_intersections); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1252, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_4 = __Pyx_Generator_GetInlinedResult(__pyx_t_10); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1252, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely((PyList_Sort(__pyx_t_4) < 0))) __PYX_ERR(0, 1252, __pyx_L1_error) + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1242 + * + * + * def _curve_line_intersections_t(curve, line): # <<<<<<<<<<<<<< + * aligned_curve = _alignment_transformation(line).transformPoints(curve) + * if len(curve) == 3: +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_line_intersections_t", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_aligned_curve); + __Pyx_XDECREF(__pyx_v_a); + __Pyx_XDECREF(__pyx_v_b); + __Pyx_XDECREF(__pyx_v_c); + __Pyx_XDECREF(__pyx_v_intersections); + __Pyx_XDECREF(__pyx_v_d); + __Pyx_XDECREF(__pyx_gb_9fontTools_4misc_11bezierTools_27_curve_line_intersections_t_2generator4); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1255 + * + * + * def curveLineIntersections(curve, line): # <<<<<<<<<<<<<< + * """Finds intersections between a curve and a line. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_79curveLineIntersections(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_78curveLineIntersections, "curveLineIntersections(curve, line)\n\nFinds intersections between a curve and a line.\n\nArgs:\n curve: List of coordinates of the curve segment as 2D tuples.\n line: List of coordinates of the line segment as 2D tuples.\n\nReturns:\n A list of ``Intersection`` objects, each object having ``pt``, ``t1``\n and ``t2`` attributes containing the intersection point, time on first\n segment and time on second segment respectively.\n\nExamples::\n >>> curve = [ (100, 240), (30, 60), (210, 230), (160, 30) ]\n >>> line = [ (25, 260), (230, 20) ]\n >>> intersections = curveLineIntersections(curve, line)\n >>> len(intersections)\n 3\n >>> intersections[0].pt\n (84.9000930760723, 189.87306176459828)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_79curveLineIntersections = {"curveLineIntersections", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_79curveLineIntersections, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_78curveLineIntersections}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_79curveLineIntersections(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_curve = 0; + PyObject *__pyx_v_line = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("curveLineIntersections (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_curve,&__pyx_mstate_global->__pyx_n_u_line,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1255, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1255, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1255, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "curveLineIntersections", 0) < (0)) __PYX_ERR(0, 1255, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("curveLineIntersections", 1, 2, 2, i); __PYX_ERR(0, 1255, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1255, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1255, __pyx_L3_error) + } + __pyx_v_curve = values[0]; + __pyx_v_line = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("curveLineIntersections", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 1255, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.curveLineIntersections", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_78curveLineIntersections(__pyx_self, __pyx_v_curve, __pyx_v_line); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_78curveLineIntersections(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve, PyObject *__pyx_v_line) { + PyObject *__pyx_v_pointFinder = NULL; + PyObject *__pyx_v_intersections = NULL; + PyObject *__pyx_v_t = NULL; + PyObject *__pyx_v_pt = NULL; + PyObject *__pyx_v_line_t = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + Py_ssize_t __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + size_t __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + PyObject *(*__pyx_t_7)(PyObject *); + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_t_10; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("curveLineIntersections", 0); + + /* "fontTools/misc/bezierTools.py":1276 + * (84.9000930760723, 189.87306176459828) + * """ + * if len(curve) == 3: # <<<<<<<<<<<<<< + * pointFinder = quadraticPointAtT + * elif len(curve) == 4: +*/ + __pyx_t_1 = PyObject_Length(__pyx_v_curve); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1276, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 3); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1277 + * """ + * if len(curve) == 3: + * pointFinder = quadraticPointAtT # <<<<<<<<<<<<<< + * elif len(curve) == 4: + * pointFinder = cubicPointAtT +*/ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_quadraticPointAtT); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1277, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_pointFinder = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1276 + * (84.9000930760723, 189.87306176459828) + * """ + * if len(curve) == 3: # <<<<<<<<<<<<<< + * pointFinder = quadraticPointAtT + * elif len(curve) == 4: +*/ + goto __pyx_L3; + } + + /* "fontTools/misc/bezierTools.py":1278 + * if len(curve) == 3: + * pointFinder = quadraticPointAtT + * elif len(curve) == 4: # <<<<<<<<<<<<<< + * pointFinder = cubicPointAtT + * else: +*/ + __pyx_t_1 = PyObject_Length(__pyx_v_curve); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1278, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 4); + if (likely(__pyx_t_2)) { + + /* "fontTools/misc/bezierTools.py":1279 + * pointFinder = quadraticPointAtT + * elif len(curve) == 4: + * pointFinder = cubicPointAtT # <<<<<<<<<<<<<< + * else: + * raise ValueError("Unknown curve degree") +*/ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_cubicPointAtT); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1279, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_pointFinder = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1278 + * if len(curve) == 3: + * pointFinder = quadraticPointAtT + * elif len(curve) == 4: # <<<<<<<<<<<<<< + * pointFinder = cubicPointAtT + * else: +*/ + goto __pyx_L3; + } + + /* "fontTools/misc/bezierTools.py":1281 + * pointFinder = cubicPointAtT + * else: + * raise ValueError("Unknown curve degree") # <<<<<<<<<<<<<< + * intersections = [] + * for t in _curve_line_intersections_t(curve, line): +*/ + /*else*/ { + __pyx_t_4 = NULL; + __pyx_t_5 = 1; + { + PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_mstate_global->__pyx_kp_u_Unknown_curve_degree}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)(((PyTypeObject*)PyExc_ValueError)), __pyx_callargs+__pyx_t_5, (2-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1281, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 1281, __pyx_L1_error) + } + __pyx_L3:; + + /* "fontTools/misc/bezierTools.py":1282 + * else: + * raise ValueError("Unknown curve degree") + * intersections = [] # <<<<<<<<<<<<<< + * for t in _curve_line_intersections_t(curve, line): + * pt = pointFinder(*curve, t) +*/ + __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1282, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_intersections = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1283 + * raise ValueError("Unknown curve degree") + * intersections = [] + * for t in _curve_line_intersections_t(curve, line): # <<<<<<<<<<<<<< + * pt = pointFinder(*curve, t) + * # Back-project the point onto the line, to avoid problems with +*/ + __pyx_t_4 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_curve_line_intersections_t); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1283, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_6); + assert(__pyx_t_4); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_6, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_4, __pyx_v_curve, __pyx_v_line}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_6, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1283, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) { + __pyx_t_6 = __pyx_t_3; __Pyx_INCREF(__pyx_t_6); + __pyx_t_1 = 0; + __pyx_t_7 = NULL; + } else { + __pyx_t_1 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1283, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1283, __pyx_L1_error) + } + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + for (;;) { + if (likely(!__pyx_t_7)) { + if (likely(PyList_CheckExact(__pyx_t_6))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_6); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1283, __pyx_L1_error) + #endif + if (__pyx_t_1 >= __pyx_temp) break; + } + __pyx_t_3 = __Pyx_PyList_GetItemRefFast(__pyx_t_6, __pyx_t_1, __Pyx_ReferenceSharing_OwnStrongReference); + ++__pyx_t_1; + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_6); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1283, __pyx_L1_error) + #endif + if (__pyx_t_1 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = __Pyx_NewRef(PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_1)); + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_1); + #endif + ++__pyx_t_1; + } + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1283, __pyx_L1_error) + } else { + __pyx_t_3 = __pyx_t_7(__pyx_t_6); + if (unlikely(!__pyx_t_3)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 1283, __pyx_L1_error) + PyErr_Clear(); + } + break; + } + } + __Pyx_GOTREF(__pyx_t_3); + __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1284 + * intersections = [] + * for t in _curve_line_intersections_t(curve, line): + * pt = pointFinder(*curve, t) # <<<<<<<<<<<<<< + * # Back-project the point onto the line, to avoid problems with + * # numerical accuracy in the case of vertical and horizontal lines +*/ + __pyx_t_3 = __Pyx_PySequence_Tuple(__pyx_v_curve); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1284, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1284, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_INCREF(__pyx_v_t); + __Pyx_GIVEREF(__pyx_v_t); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_t) != (0)) __PYX_ERR(0, 1284, __pyx_L1_error); + __pyx_t_8 = PyNumber_Add(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1284, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_v_pointFinder, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1284, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF_SET(__pyx_v_pt, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1287 + * # Back-project the point onto the line, to avoid problems with + * # numerical accuracy in the case of vertical and horizontal lines + * line_t = _line_t_of_pt(*line, pt) # <<<<<<<<<<<<<< + * pt = linePointAtT(*line, line_t) + * intersections.append(Intersection(pt=pt, t1=t, t2=line_t)) +*/ + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_line_t_of_pt); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1287, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_8 = __Pyx_PySequence_Tuple(__pyx_v_line); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1287, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1287, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_pt); + __Pyx_GIVEREF(__pyx_v_pt); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_pt) != (0)) __PYX_ERR(0, 1287, __pyx_L1_error); + __pyx_t_9 = PyNumber_Add(__pyx_t_8, __pyx_t_3); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1287, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1287, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_XDECREF_SET(__pyx_v_line_t, __pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1288 + * # numerical accuracy in the case of vertical and horizontal lines + * line_t = _line_t_of_pt(*line, pt) + * pt = linePointAtT(*line, line_t) # <<<<<<<<<<<<<< + * intersections.append(Intersection(pt=pt, t1=t, t2=line_t)) + * return intersections +*/ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_linePointAtT); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1288, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_9 = __Pyx_PySequence_Tuple(__pyx_v_line); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1288, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1288, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_INCREF(__pyx_v_line_t); + __Pyx_GIVEREF(__pyx_v_line_t); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_line_t) != (0)) __PYX_ERR(0, 1288, __pyx_L1_error); + __pyx_t_8 = PyNumber_Add(__pyx_t_9, __pyx_t_4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1288, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1288, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF_SET(__pyx_v_pt, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1289 + * line_t = _line_t_of_pt(*line, pt) + * pt = linePointAtT(*line, line_t) + * intersections.append(Intersection(pt=pt, t1=t, t2=line_t)) # <<<<<<<<<<<<<< + * return intersections + * +*/ + __pyx_t_8 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_Intersection); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1289, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_8); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[2 + ((CYTHON_VECTORCALL) ? 3 : 0)] = {__pyx_t_8, NULL}; + __pyx_t_9 = __Pyx_MakeVectorcallBuilderKwds(3); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1289, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_pt, __pyx_v_pt, __pyx_t_9, __pyx_callargs+1, 0) < (0)) __PYX_ERR(0, 1289, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_t1, __pyx_v_t, __pyx_t_9, __pyx_callargs+1, 1) < (0)) __PYX_ERR(0, 1289, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_t2, __pyx_v_line_t, __pyx_t_9, __pyx_callargs+1, 2) < (0)) __PYX_ERR(0, 1289, __pyx_L1_error) + __pyx_t_4 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_5, (1-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_9); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1289, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + } + __pyx_t_10 = __Pyx_PyList_Append(__pyx_v_intersections, __pyx_t_4); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 1289, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1283 + * raise ValueError("Unknown curve degree") + * intersections = [] + * for t in _curve_line_intersections_t(curve, line): # <<<<<<<<<<<<<< + * pt = pointFinder(*curve, t) + * # Back-project the point onto the line, to avoid problems with +*/ + } + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":1290 + * pt = linePointAtT(*line, line_t) + * intersections.append(Intersection(pt=pt, t1=t, t2=line_t)) + * return intersections # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_intersections); + __pyx_r = __pyx_v_intersections; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1255 + * + * + * def curveLineIntersections(curve, line): # <<<<<<<<<<<<<< + * """Finds intersections between a curve and a line. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("fontTools.misc.bezierTools.curveLineIntersections", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_pointFinder); + __Pyx_XDECREF(__pyx_v_intersections); + __Pyx_XDECREF(__pyx_v_t); + __Pyx_XDECREF(__pyx_v_pt); + __Pyx_XDECREF(__pyx_v_line_t); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1293 + * + * + * def _curve_bounds(c): # <<<<<<<<<<<<<< + * if len(c) == 3: + * return calcQuadraticBounds(*c) +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_81_curve_bounds(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_80_curve_bounds, "_curve_bounds(c)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_81_curve_bounds = {"_curve_bounds", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_81_curve_bounds, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_80_curve_bounds}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_81_curve_bounds(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_c = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_curve_bounds (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_c,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1293, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1293, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_curve_bounds", 0) < (0)) __PYX_ERR(0, 1293, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_curve_bounds", 1, 1, 1, i); __PYX_ERR(0, 1293, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1293, __pyx_L3_error) + } + __pyx_v_c = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_curve_bounds", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 1293, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_bounds", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_80_curve_bounds(__pyx_self, __pyx_v_c); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_80_curve_bounds(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_c) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + Py_ssize_t __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + size_t __pyx_t_6; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_curve_bounds", 0); + + /* "fontTools/misc/bezierTools.py":1294 + * + * def _curve_bounds(c): + * if len(c) == 3: # <<<<<<<<<<<<<< + * return calcQuadraticBounds(*c) + * elif len(c) == 4: +*/ + __pyx_t_1 = PyObject_Length(__pyx_v_c); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1294, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 3); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1295 + * def _curve_bounds(c): + * if len(c) == 3: + * return calcQuadraticBounds(*c) # <<<<<<<<<<<<<< + * elif len(c) == 4: + * return calcCubicBounds(*c) +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_calcQuadraticBounds); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1295, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_c); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1295, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1295, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1294 + * + * def _curve_bounds(c): + * if len(c) == 3: # <<<<<<<<<<<<<< + * return calcQuadraticBounds(*c) + * elif len(c) == 4: +*/ + } + + /* "fontTools/misc/bezierTools.py":1296 + * if len(c) == 3: + * return calcQuadraticBounds(*c) + * elif len(c) == 4: # <<<<<<<<<<<<<< + * return calcCubicBounds(*c) + * raise ValueError("Unknown curve degree") +*/ + __pyx_t_1 = PyObject_Length(__pyx_v_c); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1296, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 4); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1297 + * return calcQuadraticBounds(*c) + * elif len(c) == 4: + * return calcCubicBounds(*c) # <<<<<<<<<<<<<< + * raise ValueError("Unknown curve degree") + * +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_calcCubicBounds); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1297, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_c); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1297, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1297, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1296 + * if len(c) == 3: + * return calcQuadraticBounds(*c) + * elif len(c) == 4: # <<<<<<<<<<<<<< + * return calcCubicBounds(*c) + * raise ValueError("Unknown curve degree") +*/ + } + + /* "fontTools/misc/bezierTools.py":1298 + * elif len(c) == 4: + * return calcCubicBounds(*c) + * raise ValueError("Unknown curve degree") # <<<<<<<<<<<<<< + * + * +*/ + __pyx_t_4 = NULL; + __pyx_t_6 = 1; + { + PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_mstate_global->__pyx_kp_u_Unknown_curve_degree}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)(((PyTypeObject*)PyExc_ValueError)), __pyx_callargs+__pyx_t_6, (2-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1298, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 1298, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1293 + * + * + * def _curve_bounds(c): # <<<<<<<<<<<<<< + * if len(c) == 3: + * return calcQuadraticBounds(*c) +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_bounds", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1301 + * + * + * def _split_segment_at_t(c, t): # <<<<<<<<<<<<<< + * if len(c) == 2: + * s, e = c +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_83_split_segment_at_t(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_82_split_segment_at_t, "_split_segment_at_t(c, t)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_83_split_segment_at_t = {"_split_segment_at_t", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_83_split_segment_at_t, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_82_split_segment_at_t}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_83_split_segment_at_t(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_c = 0; + PyObject *__pyx_v_t = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_split_segment_at_t (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_c,&__pyx_mstate_global->__pyx_n_u_t,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1301, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1301, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1301, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_split_segment_at_t", 0) < (0)) __PYX_ERR(0, 1301, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_split_segment_at_t", 1, 2, 2, i); __PYX_ERR(0, 1301, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1301, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1301, __pyx_L3_error) + } + __pyx_v_c = values[0]; + __pyx_v_t = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_split_segment_at_t", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 1301, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._split_segment_at_t", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_82_split_segment_at_t(__pyx_self, __pyx_v_c, __pyx_v_t); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_82_split_segment_at_t(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_c, PyObject *__pyx_v_t) { + PyObject *__pyx_v_s = NULL; + PyObject *__pyx_v_e = NULL; + PyObject *__pyx_v_midpoint = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + Py_ssize_t __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *(*__pyx_t_6)(PyObject *); + size_t __pyx_t_7; + PyObject *__pyx_t_8 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_split_segment_at_t", 0); + + /* "fontTools/misc/bezierTools.py":1302 + * + * def _split_segment_at_t(c, t): + * if len(c) == 2: # <<<<<<<<<<<<<< + * s, e = c + * midpoint = linePointAtT(s, e, t) +*/ + __pyx_t_1 = PyObject_Length(__pyx_v_c); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1302, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 2); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1303 + * def _split_segment_at_t(c, t): + * if len(c) == 2: + * s, e = c # <<<<<<<<<<<<<< + * midpoint = linePointAtT(s, e, t) + * return [(s, midpoint), (midpoint, e)] +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_c))) || (PyList_CheckExact(__pyx_v_c))) { + PyObject* sequence = __pyx_v_c; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1303, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_3); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_4); + } else { + __pyx_t_3 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1303, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1303, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_4); + } + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1303, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1303, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_5 = PyObject_GetIter(__pyx_v_c); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1303, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_5); + index = 0; __pyx_t_3 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_3)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 1; __pyx_t_4 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_4)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_5), 2) < (0)) __PYX_ERR(0, 1303, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L5_unpacking_done; + __pyx_L4_unpacking_failed:; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1303, __pyx_L1_error) + __pyx_L5_unpacking_done:; + } + __pyx_v_s = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v_e = __pyx_t_4; + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1304 + * if len(c) == 2: + * s, e = c + * midpoint = linePointAtT(s, e, t) # <<<<<<<<<<<<<< + * return [(s, midpoint), (midpoint, e)] + * if len(c) == 3: +*/ + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_linePointAtT); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1304, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5); + assert(__pyx_t_3); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_5, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[4] = {__pyx_t_3, __pyx_v_s, __pyx_v_e, __pyx_v_t}; + __pyx_t_4 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_5, __pyx_callargs+__pyx_t_7, (4-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1304, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + } + __pyx_v_midpoint = __pyx_t_4; + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1305 + * s, e = c + * midpoint = linePointAtT(s, e, t) + * return [(s, midpoint), (midpoint, e)] # <<<<<<<<<<<<<< + * if len(c) == 3: + * return splitQuadraticAtT(*c, t) +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1305, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_INCREF(__pyx_v_s); + __Pyx_GIVEREF(__pyx_v_s); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_s) != (0)) __PYX_ERR(0, 1305, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_midpoint); + __Pyx_GIVEREF(__pyx_v_midpoint); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_midpoint) != (0)) __PYX_ERR(0, 1305, __pyx_L1_error); + __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1305, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_midpoint); + __Pyx_GIVEREF(__pyx_v_midpoint); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_midpoint) != (0)) __PYX_ERR(0, 1305, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_e); + __Pyx_GIVEREF(__pyx_v_e); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_e) != (0)) __PYX_ERR(0, 1305, __pyx_L1_error); + __pyx_t_3 = PyList_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1305, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 0, __pyx_t_4) != (0)) __PYX_ERR(0, 1305, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 1, __pyx_t_5) != (0)) __PYX_ERR(0, 1305, __pyx_L1_error); + __pyx_t_4 = 0; + __pyx_t_5 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1302 + * + * def _split_segment_at_t(c, t): + * if len(c) == 2: # <<<<<<<<<<<<<< + * s, e = c + * midpoint = linePointAtT(s, e, t) +*/ + } + + /* "fontTools/misc/bezierTools.py":1306 + * midpoint = linePointAtT(s, e, t) + * return [(s, midpoint), (midpoint, e)] + * if len(c) == 3: # <<<<<<<<<<<<<< + * return splitQuadraticAtT(*c, t) + * elif len(c) == 4: +*/ + __pyx_t_1 = PyObject_Length(__pyx_v_c); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1306, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 3); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1307 + * return [(s, midpoint), (midpoint, e)] + * if len(c) == 3: + * return splitQuadraticAtT(*c, t) # <<<<<<<<<<<<<< + * elif len(c) == 4: + * return splitCubicAtT(*c, t) +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_splitQuadraticAtT_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1307, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = __Pyx_PySequence_Tuple(__pyx_v_c); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1307, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1307, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_INCREF(__pyx_v_t); + __Pyx_GIVEREF(__pyx_v_t); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_t) != (0)) __PYX_ERR(0, 1307, __pyx_L1_error); + __pyx_t_8 = PyNumber_Add(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1307, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1307, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1306 + * midpoint = linePointAtT(s, e, t) + * return [(s, midpoint), (midpoint, e)] + * if len(c) == 3: # <<<<<<<<<<<<<< + * return splitQuadraticAtT(*c, t) + * elif len(c) == 4: +*/ + } + + /* "fontTools/misc/bezierTools.py":1308 + * if len(c) == 3: + * return splitQuadraticAtT(*c, t) + * elif len(c) == 4: # <<<<<<<<<<<<<< + * return splitCubicAtT(*c, t) + * raise ValueError("Unknown curve degree") +*/ + __pyx_t_1 = PyObject_Length(__pyx_v_c); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1308, __pyx_L1_error) + __pyx_t_2 = (__pyx_t_1 == 4); + if (__pyx_t_2) { + + /* "fontTools/misc/bezierTools.py":1309 + * return splitQuadraticAtT(*c, t) + * elif len(c) == 4: + * return splitCubicAtT(*c, t) # <<<<<<<<<<<<<< + * raise ValueError("Unknown curve degree") + * +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_splitCubicAtT_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_8 = __Pyx_PySequence_Tuple(__pyx_v_c); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_t); + __Pyx_GIVEREF(__pyx_v_t); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_t) != (0)) __PYX_ERR(0, 1309, __pyx_L1_error); + __pyx_t_5 = PyNumber_Add(__pyx_t_8, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1308 + * if len(c) == 3: + * return splitQuadraticAtT(*c, t) + * elif len(c) == 4: # <<<<<<<<<<<<<< + * return splitCubicAtT(*c, t) + * raise ValueError("Unknown curve degree") +*/ + } + + /* "fontTools/misc/bezierTools.py":1310 + * elif len(c) == 4: + * return splitCubicAtT(*c, t) + * raise ValueError("Unknown curve degree") # <<<<<<<<<<<<<< + * + * +*/ + __pyx_t_5 = NULL; + __pyx_t_7 = 1; + { + PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_mstate_global->__pyx_kp_u_Unknown_curve_degree}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)(((PyTypeObject*)PyExc_ValueError)), __pyx_callargs+__pyx_t_7, (2-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1310, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 1310, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1301 + * + * + * def _split_segment_at_t(c, t): # <<<<<<<<<<<<<< + * if len(c) == 2: + * s, e = c +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("fontTools.misc.bezierTools._split_segment_at_t", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_s); + __Pyx_XDECREF(__pyx_v_e); + __Pyx_XDECREF(__pyx_v_midpoint); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1313 + * + * + * def _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * curve1, curve2, precision=1e-3, range1=None, range2=None + * ): +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_85_curve_curve_intersections_t(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_84_curve_curve_intersections_t, "_curve_curve_intersections_t(curve1, curve2, precision=1e-3, range1=None, range2=None)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_85_curve_curve_intersections_t = {"_curve_curve_intersections_t", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_85_curve_curve_intersections_t, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_84_curve_curve_intersections_t}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_85_curve_curve_intersections_t(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_curve1 = 0; + PyObject *__pyx_v_curve2 = 0; + PyObject *__pyx_v_precision = 0; + PyObject *__pyx_v_range1 = 0; + PyObject *__pyx_v_range2 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_curve_curve_intersections_t (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_curve1,&__pyx_mstate_global->__pyx_n_u_curve2,&__pyx_mstate_global->__pyx_n_u_precision,&__pyx_mstate_global->__pyx_n_u_range1,&__pyx_mstate_global->__pyx_n_u_range2,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1313, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 5: + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 1313, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 1313, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1313, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1313, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1313, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_curve_curve_intersections_t", 0) < (0)) __PYX_ERR(0, 1313, __pyx_L3_error) + if (!values[2]) values[2] = __Pyx_NewRef(((PyObject *)((PyObject*)__pyx_mstate_global->__pyx_float_1eneg_3))); + + /* "fontTools/misc/bezierTools.py":1314 + * + * def _curve_curve_intersections_t( + * curve1, curve2, precision=1e-3, range1=None, range2=None # <<<<<<<<<<<<<< + * ): + * bounds1 = _curve_bounds(curve1) +*/ + if (!values[3]) values[3] = __Pyx_NewRef(((PyObject *)Py_None)); + if (!values[4]) values[4] = __Pyx_NewRef(((PyObject *)Py_None)); + for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_curve_curve_intersections_t", 0, 2, 5, i); __PYX_ERR(0, 1313, __pyx_L3_error) } + } + } else { + switch (__pyx_nargs) { + case 5: + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 1313, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 1313, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 1313, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1313, __pyx_L3_error) + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1313, __pyx_L3_error) + break; + default: goto __pyx_L5_argtuple_error; + } + if (!values[2]) values[2] = __Pyx_NewRef(((PyObject *)((PyObject*)__pyx_mstate_global->__pyx_float_1eneg_3))); + if (!values[3]) values[3] = __Pyx_NewRef(((PyObject *)Py_None)); + if (!values[4]) values[4] = __Pyx_NewRef(((PyObject *)Py_None)); + } + __pyx_v_curve1 = values[0]; + __pyx_v_curve2 = values[1]; + __pyx_v_precision = values[2]; + __pyx_v_range1 = values[3]; + __pyx_v_range2 = values[4]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_curve_curve_intersections_t", 0, 2, 5, __pyx_nargs); __PYX_ERR(0, 1313, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_curve_intersections_t", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_84_curve_curve_intersections_t(__pyx_self, __pyx_v_curve1, __pyx_v_curve2, __pyx_v_precision, __pyx_v_range1, __pyx_v_range2); + + /* "fontTools/misc/bezierTools.py":1313 + * + * + * def _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * curve1, curve2, precision=1e-3, range1=None, range2=None + * ): +*/ + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1329 + * return [] + * + * def midpoint(r): # <<<<<<<<<<<<<< + * return 0.5 * (r[0] + r[1]) + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_1midpoint(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_1midpoint = {"midpoint", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_1midpoint, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_1midpoint(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_r = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("midpoint (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_r,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1329, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1329, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "midpoint", 0) < (0)) __PYX_ERR(0, 1329, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("midpoint", 1, 1, 1, i); __PYX_ERR(0, 1329, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1329, __pyx_L3_error) + } + __pyx_v_r = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("midpoint", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 1329, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_curve_intersections_t.midpoint", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(__pyx_self, __pyx_v_r); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_r) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("midpoint", 0); + + /* "fontTools/misc/bezierTools.py":1330 + * + * def midpoint(r): + * return 0.5 * (r[0] + r[1]) # <<<<<<<<<<<<<< + * + * # If they do overlap but they're tiny, approximate +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_r, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1330, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_r, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1330, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyNumber_Add(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1330, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyNumber_Multiply(__pyx_mstate_global->__pyx_float_0_5, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1330, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1329 + * return [] + * + * def midpoint(r): # <<<<<<<<<<<<<< + * return 0.5 * (r[0] + r[1]) + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_curve_intersections_t.midpoint", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1366 + * ) + * + * unique_key = lambda ts: (int(ts[0] / precision), int(ts[1] / precision)) # <<<<<<<<<<<<<< + * seen = set() + * unique_values = [] +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_2lambda3(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_2lambda3 = {"lambda3", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_2lambda3, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_2lambda3(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_ts = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("lambda3 (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_ts,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1366, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1366, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "lambda3", 0) < (0)) __PYX_ERR(0, 1366, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("lambda3", 1, 1, 1, i); __PYX_ERR(0, 1366, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1366, __pyx_L3_error) + } + __pyx_v_ts = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("lambda3", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 1366, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_curve_intersections_t.lambda3", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_lambda_funcdef_lambda3(__pyx_self, __pyx_v_ts); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_lambda_funcdef_lambda3(PyObject *__pyx_self, PyObject *__pyx_v_ts) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *__pyx_cur_scope; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *__pyx_outer_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("lambda3", 0); + __pyx_outer_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *) __Pyx_CyFunction_GetClosure(__pyx_self); + __pyx_cur_scope = __pyx_outer_scope; + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_ts, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1366, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (unlikely(!__pyx_cur_scope->__pyx_v_precision)) { __Pyx_RaiseClosureNameError("precision"); __PYX_ERR(0, 1366, __pyx_L1_error) } + __pyx_t_2 = __Pyx_PyNumber_Divide(__pyx_t_1, __pyx_cur_scope->__pyx_v_precision); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1366, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyNumber_Int(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1366, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_ts, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1366, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (unlikely(!__pyx_cur_scope->__pyx_v_precision)) { __Pyx_RaiseClosureNameError("precision"); __PYX_ERR(0, 1366, __pyx_L1_error) } + __pyx_t_3 = __Pyx_PyNumber_Divide(__pyx_t_2, __pyx_cur_scope->__pyx_v_precision); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1366, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyNumber_Int(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1366, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1366, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 1366, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2) != (0)) __PYX_ERR(0, 1366, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_curve_intersections_t.lambda3", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1313 + * + * + * def _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * curve1, curve2, precision=1e-3, range1=None, range2=None + * ): +*/ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_84_curve_curve_intersections_t(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve1, PyObject *__pyx_v_curve2, PyObject *__pyx_v_precision, PyObject *__pyx_v_range1, PyObject *__pyx_v_range2) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *__pyx_cur_scope; + PyObject *__pyx_v_bounds1 = NULL; + PyObject *__pyx_v_bounds2 = NULL; + PyObject *__pyx_v_intersects = NULL; + CYTHON_UNUSED PyObject *__pyx_v__ = NULL; + PyObject *__pyx_v_midpoint = 0; + PyObject *__pyx_v_c11 = NULL; + PyObject *__pyx_v_c12 = NULL; + PyObject *__pyx_v_c11_range = NULL; + PyObject *__pyx_v_c12_range = NULL; + PyObject *__pyx_v_c21 = NULL; + PyObject *__pyx_v_c22 = NULL; + PyObject *__pyx_v_c21_range = NULL; + PyObject *__pyx_v_c22_range = NULL; + PyObject *__pyx_v_found = NULL; + PyObject *__pyx_v_unique_key = NULL; + PyObject *__pyx_v_seen = NULL; + PyObject *__pyx_v_unique_values = NULL; + PyObject *__pyx_v_ts = NULL; + PyObject *__pyx_v_key = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + size_t __pyx_t_4; + int __pyx_t_5; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + PyObject *(*__pyx_t_8)(PyObject *); + int __pyx_t_9; + Py_ssize_t __pyx_t_10; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_curve_curve_intersections_t", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t(__pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t, __pyx_mstate_global->__pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 1313, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_v_precision = __pyx_v_precision; + __Pyx_INCREF(__pyx_cur_scope->__pyx_v_precision); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_precision); + __Pyx_INCREF(__pyx_v_range1); + __Pyx_INCREF(__pyx_v_range2); + + /* "fontTools/misc/bezierTools.py":1316 + * curve1, curve2, precision=1e-3, range1=None, range2=None + * ): + * bounds1 = _curve_bounds(curve1) # <<<<<<<<<<<<<< + * bounds2 = _curve_bounds(curve2) + * +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_curve_bounds); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_v_curve1}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_4, (2-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_v_bounds1 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1317 + * ): + * bounds1 = _curve_bounds(curve1) + * bounds2 = _curve_bounds(curve2) # <<<<<<<<<<<<<< + * + * if not range1: +*/ + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_curve_bounds); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1317, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_3); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_curve2}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_4, (2-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1317, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_v_bounds2 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1319 + * bounds2 = _curve_bounds(curve2) + * + * if not range1: # <<<<<<<<<<<<<< + * range1 = (0.0, 1.0) + * if not range2: +*/ + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_range1); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1319, __pyx_L1_error) + __pyx_t_6 = (!__pyx_t_5); + if (__pyx_t_6) { + + /* "fontTools/misc/bezierTools.py":1320 + * + * if not range1: + * range1 = (0.0, 1.0) # <<<<<<<<<<<<<< + * if not range2: + * range2 = (0.0, 1.0) +*/ + __Pyx_INCREF(__pyx_mstate_global->__pyx_tuple[1]); + __Pyx_DECREF_SET(__pyx_v_range1, __pyx_mstate_global->__pyx_tuple[1]); + + /* "fontTools/misc/bezierTools.py":1319 + * bounds2 = _curve_bounds(curve2) + * + * if not range1: # <<<<<<<<<<<<<< + * range1 = (0.0, 1.0) + * if not range2: +*/ + } + + /* "fontTools/misc/bezierTools.py":1321 + * if not range1: + * range1 = (0.0, 1.0) + * if not range2: # <<<<<<<<<<<<<< + * range2 = (0.0, 1.0) + * +*/ + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_range2); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(0, 1321, __pyx_L1_error) + __pyx_t_5 = (!__pyx_t_6); + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1322 + * range1 = (0.0, 1.0) + * if not range2: + * range2 = (0.0, 1.0) # <<<<<<<<<<<<<< + * + * # If bounds don't intersect, go home +*/ + __Pyx_INCREF(__pyx_mstate_global->__pyx_tuple[1]); + __Pyx_DECREF_SET(__pyx_v_range2, __pyx_mstate_global->__pyx_tuple[1]); + + /* "fontTools/misc/bezierTools.py":1321 + * if not range1: + * range1 = (0.0, 1.0) + * if not range2: # <<<<<<<<<<<<<< + * range2 = (0.0, 1.0) + * +*/ + } + + /* "fontTools/misc/bezierTools.py":1325 + * + * # If bounds don't intersect, go home + * intersects, _ = sectRect(bounds1, bounds2) # <<<<<<<<<<<<<< + * if not intersects: + * return [] +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_sectRect); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1325, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_v_bounds1, __pyx_v_bounds2}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_4, (3-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1325, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1325, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_3); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_2); + } else { + __pyx_t_3 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1325, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1325, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + } + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1325, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1325, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_7 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1325, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_8 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_7); + index = 0; __pyx_t_3 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_3)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_3); + index = 1; __pyx_t_2 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < (0)) __PYX_ERR(0, 1325, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1325, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_v_intersects = __pyx_t_3; + __pyx_t_3 = 0; + __pyx_v__ = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1326 + * # If bounds don't intersect, go home + * intersects, _ = sectRect(bounds1, bounds2) + * if not intersects: # <<<<<<<<<<<<<< + * return [] + * +*/ + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_intersects); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1326, __pyx_L1_error) + __pyx_t_6 = (!__pyx_t_5); + if (__pyx_t_6) { + + /* "fontTools/misc/bezierTools.py":1327 + * intersects, _ = sectRect(bounds1, bounds2) + * if not intersects: + * return [] # <<<<<<<<<<<<<< + * + * def midpoint(r): +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1327, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1326 + * # If bounds don't intersect, go home + * intersects, _ = sectRect(bounds1, bounds2) + * if not intersects: # <<<<<<<<<<<<<< + * return [] + * +*/ + } + + /* "fontTools/misc/bezierTools.py":1329 + * return [] + * + * def midpoint(r): # <<<<<<<<<<<<<< + * return 0.5 * (r[0] + r[1]) + * +*/ + __pyx_t_1 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_1midpoint, 0, __pyx_mstate_global->__pyx_n_u_curve_curve_intersections_t_loc, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[5])); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1329, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_midpoint = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1333 + * + * # If they do overlap but they're tiny, approximate + * if rectArea(bounds1) < precision and rectArea(bounds2) < precision: # <<<<<<<<<<<<<< + * return [(midpoint(range1), midpoint(range2))] + * +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_rectArea); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1333, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_v_bounds1}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_4, (2-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1333, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_cur_scope->__pyx_v_precision, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1333, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1333, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_5) { + } else { + __pyx_t_6 = __pyx_t_5; + goto __pyx_L9_bool_binop_done; + } + __pyx_t_1 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_rectArea); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1333, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_1); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_v_bounds2}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_4, (2-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1333, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, __pyx_cur_scope->__pyx_v_precision, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1333, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1333, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_6 = __pyx_t_5; + __pyx_L9_bool_binop_done:; + if (__pyx_t_6) { + + /* "fontTools/misc/bezierTools.py":1334 + * # If they do overlap but they're tiny, approximate + * if rectArea(bounds1) < precision and rectArea(bounds2) < precision: + * return [(midpoint(range1), midpoint(range2))] # <<<<<<<<<<<<<< + * + * c11, c12 = _split_segment_at_t(curve1, 0.5) +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = __pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(__pyx_v_midpoint, __pyx_v_range1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1334, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(__pyx_v_midpoint, __pyx_v_range2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1334, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1334, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2) != (0)) __PYX_ERR(0, 1334, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3) != (0)) __PYX_ERR(0, 1334, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1334, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 1334, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1333 + * + * # If they do overlap but they're tiny, approximate + * if rectArea(bounds1) < precision and rectArea(bounds2) < precision: # <<<<<<<<<<<<<< + * return [(midpoint(range1), midpoint(range2))] + * +*/ + } + + /* "fontTools/misc/bezierTools.py":1336 + * return [(midpoint(range1), midpoint(range2))] + * + * c11, c12 = _split_segment_at_t(curve1, 0.5) # <<<<<<<<<<<<<< + * c11_range = (range1[0], midpoint(range1)) + * c12_range = (midpoint(range1), range1[1]) +*/ + __pyx_t_1 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_split_segment_at_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1336, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_1); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_1, __pyx_v_curve1, __pyx_mstate_global->__pyx_float_0_5}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_4, (3-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1336, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1336, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1336, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1336, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1336, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1336, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_7 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1336, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_8 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_7); + index = 0; __pyx_t_2 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_2)) goto __pyx_L11_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_1)) goto __pyx_L11_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < (0)) __PYX_ERR(0, 1336, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L12_unpacking_done; + __pyx_L11_unpacking_failed:; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1336, __pyx_L1_error) + __pyx_L12_unpacking_done:; + } + __pyx_v_c11 = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_c12 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1337 + * + * c11, c12 = _split_segment_at_t(curve1, 0.5) + * c11_range = (range1[0], midpoint(range1)) # <<<<<<<<<<<<<< + * c12_range = (midpoint(range1), range1[1]) + * +*/ + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_range1, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1337, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(__pyx_v_midpoint, __pyx_v_range1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1337, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1337, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3) != (0)) __PYX_ERR(0, 1337, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1) != (0)) __PYX_ERR(0, 1337, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_t_1 = 0; + __pyx_v_c11_range = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1338 + * c11, c12 = _split_segment_at_t(curve1, 0.5) + * c11_range = (range1[0], midpoint(range1)) + * c12_range = (midpoint(range1), range1[1]) # <<<<<<<<<<<<<< + * + * c21, c22 = _split_segment_at_t(curve2, 0.5) +*/ + __pyx_t_2 = __pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(__pyx_v_midpoint, __pyx_v_range1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1338, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_range1, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1338, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1338, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2) != (0)) __PYX_ERR(0, 1338, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1) != (0)) __PYX_ERR(0, 1338, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_1 = 0; + __pyx_v_c12_range = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1340 + * c12_range = (midpoint(range1), range1[1]) + * + * c21, c22 = _split_segment_at_t(curve2, 0.5) # <<<<<<<<<<<<<< + * c21_range = (range2[0], midpoint(range2)) + * c22_range = (midpoint(range2), range2[1]) +*/ + __pyx_t_1 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_split_segment_at_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1340, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_1); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_1, __pyx_v_curve2, __pyx_mstate_global->__pyx_float_0_5}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_4, (3-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1340, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1340, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1340, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1340, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1340, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1340, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_7 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1340, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_8 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_7); + index = 0; __pyx_t_2 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_2)) goto __pyx_L13_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_1 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_1)) goto __pyx_L13_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < (0)) __PYX_ERR(0, 1340, __pyx_L1_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L14_unpacking_done; + __pyx_L13_unpacking_failed:; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 1340, __pyx_L1_error) + __pyx_L14_unpacking_done:; + } + __pyx_v_c21 = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_v_c22 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1341 + * + * c21, c22 = _split_segment_at_t(curve2, 0.5) + * c21_range = (range2[0], midpoint(range2)) # <<<<<<<<<<<<<< + * c22_range = (midpoint(range2), range2[1]) + * +*/ + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_range2, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1341, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(__pyx_v_midpoint, __pyx_v_range2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1341, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1341, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3) != (0)) __PYX_ERR(0, 1341, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1) != (0)) __PYX_ERR(0, 1341, __pyx_L1_error); + __pyx_t_3 = 0; + __pyx_t_1 = 0; + __pyx_v_c21_range = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1342 + * c21, c22 = _split_segment_at_t(curve2, 0.5) + * c21_range = (range2[0], midpoint(range2)) + * c22_range = (midpoint(range2), range2[1]) # <<<<<<<<<<<<<< + * + * found = [] +*/ + __pyx_t_2 = __pyx_pf_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_midpoint(__pyx_v_midpoint, __pyx_v_range2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1342, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_range2, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1342, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1342, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2) != (0)) __PYX_ERR(0, 1342, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1) != (0)) __PYX_ERR(0, 1342, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_1 = 0; + __pyx_v_c22_range = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1344 + * c22_range = (midpoint(range2), range2[1]) + * + * found = [] # <<<<<<<<<<<<<< + * found.extend( + * _curve_curve_intersections_t( +*/ + __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1344, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_found = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1346 + * found = [] + * found.extend( + * _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * c11, c21, precision, range1=c11_range, range2=c21_range + * ) +*/ + __pyx_t_1 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_curve_curve_intersections_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1346, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/misc/bezierTools.py":1347 + * found.extend( + * _curve_curve_intersections_t( + * c11, c21, precision, range1=c11_range, range2=c21_range # <<<<<<<<<<<<<< + * ) + * ) +*/ + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_1); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[4 + ((CYTHON_VECTORCALL) ? 2 : 0)] = {__pyx_t_1, __pyx_v_c11, __pyx_v_c21, __pyx_cur_scope->__pyx_v_precision}; + __pyx_t_7 = __Pyx_MakeVectorcallBuilderKwds(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1346, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_range1, __pyx_v_c11_range, __pyx_t_7, __pyx_callargs+4, 0) < (0)) __PYX_ERR(0, 1346, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_range2, __pyx_v_c21_range, __pyx_t_7, __pyx_callargs+4, 1) < (0)) __PYX_ERR(0, 1346, __pyx_L1_error) + __pyx_t_3 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_4, (4-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_7); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1346, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + + /* "fontTools/misc/bezierTools.py":1345 + * + * found = [] + * found.extend( # <<<<<<<<<<<<<< + * _curve_curve_intersections_t( + * c11, c21, precision, range1=c11_range, range2=c21_range +*/ + __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_found, __pyx_t_3); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 1345, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1351 + * ) + * found.extend( + * _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * c12, c21, precision, range1=c12_range, range2=c21_range + * ) +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_curve_curve_intersections_t); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1351, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + + /* "fontTools/misc/bezierTools.py":1352 + * found.extend( + * _curve_curve_intersections_t( + * c12, c21, precision, range1=c12_range, range2=c21_range # <<<<<<<<<<<<<< + * ) + * ) +*/ + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_7); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_7, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[4 + ((CYTHON_VECTORCALL) ? 2 : 0)] = {__pyx_t_2, __pyx_v_c12, __pyx_v_c21, __pyx_cur_scope->__pyx_v_precision}; + __pyx_t_1 = __Pyx_MakeVectorcallBuilderKwds(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1351, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_range1, __pyx_v_c12_range, __pyx_t_1, __pyx_callargs+4, 0) < (0)) __PYX_ERR(0, 1351, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_range2, __pyx_v_c21_range, __pyx_t_1, __pyx_callargs+4, 1) < (0)) __PYX_ERR(0, 1351, __pyx_L1_error) + __pyx_t_3 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_7, __pyx_callargs+__pyx_t_4, (4-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1351, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + + /* "fontTools/misc/bezierTools.py":1350 + * ) + * ) + * found.extend( # <<<<<<<<<<<<<< + * _curve_curve_intersections_t( + * c12, c21, precision, range1=c12_range, range2=c21_range +*/ + __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_found, __pyx_t_3); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 1350, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1356 + * ) + * found.extend( + * _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * c11, c22, precision, range1=c11_range, range2=c22_range + * ) +*/ + __pyx_t_7 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_curve_curve_intersections_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1356, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/misc/bezierTools.py":1357 + * found.extend( + * _curve_curve_intersections_t( + * c11, c22, precision, range1=c11_range, range2=c22_range # <<<<<<<<<<<<<< + * ) + * ) +*/ + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_7); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_7); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[4 + ((CYTHON_VECTORCALL) ? 2 : 0)] = {__pyx_t_7, __pyx_v_c11, __pyx_v_c22, __pyx_cur_scope->__pyx_v_precision}; + __pyx_t_2 = __Pyx_MakeVectorcallBuilderKwds(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1356, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_range1, __pyx_v_c11_range, __pyx_t_2, __pyx_callargs+4, 0) < (0)) __PYX_ERR(0, 1356, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_range2, __pyx_v_c22_range, __pyx_t_2, __pyx_callargs+4, 1) < (0)) __PYX_ERR(0, 1356, __pyx_L1_error) + __pyx_t_3 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_4, (4-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_2); + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1356, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + + /* "fontTools/misc/bezierTools.py":1355 + * ) + * ) + * found.extend( # <<<<<<<<<<<<<< + * _curve_curve_intersections_t( + * c11, c22, precision, range1=c11_range, range2=c22_range +*/ + __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_found, __pyx_t_3); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 1355, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1361 + * ) + * found.extend( + * _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * c12, c22, precision, range1=c12_range, range2=c22_range + * ) +*/ + __pyx_t_1 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_curve_curve_intersections_t); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1361, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/misc/bezierTools.py":1362 + * found.extend( + * _curve_curve_intersections_t( + * c12, c22, precision, range1=c12_range, range2=c22_range # <<<<<<<<<<<<<< + * ) + * ) +*/ + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_1); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[4 + ((CYTHON_VECTORCALL) ? 2 : 0)] = {__pyx_t_1, __pyx_v_c12, __pyx_v_c22, __pyx_cur_scope->__pyx_v_precision}; + __pyx_t_7 = __Pyx_MakeVectorcallBuilderKwds(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1361, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_range1, __pyx_v_c12_range, __pyx_t_7, __pyx_callargs+4, 0) < (0)) __PYX_ERR(0, 1361, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_range2, __pyx_v_c22_range, __pyx_t_7, __pyx_callargs+4, 1) < (0)) __PYX_ERR(0, 1361, __pyx_L1_error) + __pyx_t_3 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_4, (4-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_7); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1361, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + + /* "fontTools/misc/bezierTools.py":1360 + * ) + * ) + * found.extend( # <<<<<<<<<<<<<< + * _curve_curve_intersections_t( + * c12, c22, precision, range1=c12_range, range2=c22_range +*/ + __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_found, __pyx_t_3); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 1360, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1366 + * ) + * + * unique_key = lambda ts: (int(ts[0] / precision), int(ts[1] / precision)) # <<<<<<<<<<<<<< + * seen = set() + * unique_values = [] +*/ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_28_curve_curve_intersections_t_2lambda3, 0, __pyx_mstate_global->__pyx_n_u_curve_curve_intersections_t_loc_2, ((PyObject*)__pyx_cur_scope), __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[6])); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1366, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_unique_key = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1367 + * + * unique_key = lambda ts: (int(ts[0] / precision), int(ts[1] / precision)) + * seen = set() # <<<<<<<<<<<<<< + * unique_values = [] + * +*/ + __pyx_t_3 = PySet_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1367, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_seen = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1368 + * unique_key = lambda ts: (int(ts[0] / precision), int(ts[1] / precision)) + * seen = set() + * unique_values = [] # <<<<<<<<<<<<<< + * + * for ts in found: +*/ + __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1368, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_unique_values = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1370 + * unique_values = [] + * + * for ts in found: # <<<<<<<<<<<<<< + * key = unique_key(ts) + * if key in seen: +*/ + __pyx_t_3 = __pyx_v_found; __Pyx_INCREF(__pyx_t_3); + __pyx_t_10 = 0; + for (;;) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_3); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1370, __pyx_L1_error) + #endif + if (__pyx_t_10 >= __pyx_temp) break; + } + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(__pyx_t_3, __pyx_t_10, __Pyx_ReferenceSharing_OwnStrongReference); + ++__pyx_t_10; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1370, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_v_ts, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1371 + * + * for ts in found: + * key = unique_key(ts) # <<<<<<<<<<<<<< + * if key in seen: + * continue +*/ + __pyx_t_2 = __pyx_lambda_funcdef_lambda3(__pyx_v_unique_key, __pyx_v_ts); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1371, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_v_key, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1372 + * for ts in found: + * key = unique_key(ts) + * if key in seen: # <<<<<<<<<<<<<< + * continue + * seen.add(key) +*/ + __pyx_t_6 = (__Pyx_PySet_ContainsTF(__pyx_v_key, __pyx_v_seen, Py_EQ)); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(0, 1372, __pyx_L1_error) + if (__pyx_t_6) { + + /* "fontTools/misc/bezierTools.py":1373 + * key = unique_key(ts) + * if key in seen: + * continue # <<<<<<<<<<<<<< + * seen.add(key) + * unique_values.append(ts) +*/ + goto __pyx_L15_continue; + + /* "fontTools/misc/bezierTools.py":1372 + * for ts in found: + * key = unique_key(ts) + * if key in seen: # <<<<<<<<<<<<<< + * continue + * seen.add(key) +*/ + } + + /* "fontTools/misc/bezierTools.py":1374 + * if key in seen: + * continue + * seen.add(key) # <<<<<<<<<<<<<< + * unique_values.append(ts) + * +*/ + __pyx_t_9 = PySet_Add(__pyx_v_seen, __pyx_v_key); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 1374, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1375 + * continue + * seen.add(key) + * unique_values.append(ts) # <<<<<<<<<<<<<< + * + * return unique_values +*/ + __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_unique_values, __pyx_v_ts); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 1375, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":1370 + * unique_values = [] + * + * for ts in found: # <<<<<<<<<<<<<< + * key = unique_key(ts) + * if key in seen: +*/ + __pyx_L15_continue:; + } + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1377 + * unique_values.append(ts) + * + * return unique_values # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_unique_values); + __pyx_r = __pyx_v_unique_values; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1313 + * + * + * def _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * curve1, curve2, precision=1e-3, range1=None, range2=None + * ): +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("fontTools.misc.bezierTools._curve_curve_intersections_t", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_bounds1); + __Pyx_XDECREF(__pyx_v_bounds2); + __Pyx_XDECREF(__pyx_v_intersects); + __Pyx_XDECREF(__pyx_v__); + __Pyx_XDECREF(__pyx_v_midpoint); + __Pyx_XDECREF(__pyx_v_c11); + __Pyx_XDECREF(__pyx_v_c12); + __Pyx_XDECREF(__pyx_v_c11_range); + __Pyx_XDECREF(__pyx_v_c12_range); + __Pyx_XDECREF(__pyx_v_c21); + __Pyx_XDECREF(__pyx_v_c22); + __Pyx_XDECREF(__pyx_v_c21_range); + __Pyx_XDECREF(__pyx_v_c22_range); + __Pyx_XDECREF(__pyx_v_found); + __Pyx_XDECREF(__pyx_v_unique_key); + __Pyx_XDECREF(__pyx_v_seen); + __Pyx_XDECREF(__pyx_v_unique_values); + __Pyx_XDECREF(__pyx_v_ts); + __Pyx_XDECREF(__pyx_v_key); + __Pyx_XDECREF(__pyx_v_range1); + __Pyx_XDECREF(__pyx_v_range2); + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1380 + * + * + * def _is_linelike(segment): # <<<<<<<<<<<<<< + * maybeline = _alignment_transformation(segment).transformPoints(segment) + * return all(math.isclose(p[1], 0.0) for p in maybeline) +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_87_is_linelike(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_86_is_linelike, "_is_linelike(segment)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_87_is_linelike = {"_is_linelike", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_87_is_linelike, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_86_is_linelike}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_87_is_linelike(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_segment = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_is_linelike (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_segment,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1380, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1380, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_is_linelike", 0) < (0)) __PYX_ERR(0, 1380, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_is_linelike", 1, 1, 1, i); __PYX_ERR(0, 1380, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1380, __pyx_L3_error) + } + __pyx_v_segment = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_is_linelike", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 1380, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._is_linelike", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_86_is_linelike(__pyx_self, __pyx_v_segment); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_12_is_linelike_2generator5(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/misc/bezierTools.py":1382 + * def _is_linelike(segment): + * maybeline = _alignment_transformation(segment).transformPoints(segment) + * return all(math.isclose(p[1], 0.0) for p in maybeline) # <<<<<<<<<<<<<< + * + * +*/ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_12_is_linelike_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("genexpr", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr(__pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr, __pyx_mstate_global->__pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 1382, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_genexpr_arg_0 = __pyx_genexpr_arg_0; + __Pyx_INCREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_4misc_11bezierTools_12_is_linelike_2generator5, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[7]), (PyObject *) __pyx_cur_scope, __pyx_mstate_global->__pyx_n_u_genexpr, __pyx_mstate_global->__pyx_n_u_is_linelike_locals_genexpr, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools); if (unlikely(!gen)) __PYX_ERR(0, 1382, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.misc.bezierTools._is_linelike.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_12_is_linelike_2generator5(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *(*__pyx_t_3)(PyObject *); + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + size_t __pyx_t_8; + int __pyx_t_9; + int __pyx_t_10; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("genexpr", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 1382, __pyx_L1_error) + if (unlikely(!__pyx_cur_scope->__pyx_genexpr_arg_0)) { __Pyx_RaiseUnboundLocalError(".0"); __PYX_ERR(0, 1382, __pyx_L1_error) } + if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) { + __pyx_t_1 = __pyx_cur_scope->__pyx_genexpr_arg_0; __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = 0; + __pyx_t_3 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_genexpr_arg_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1382, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1382, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_3)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1382, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(__pyx_t_1, __pyx_t_2, __Pyx_ReferenceSharing_OwnStrongReference); + ++__pyx_t_2; + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1382, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = __Pyx_NewRef(PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2)); + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); + #endif + ++__pyx_t_2; + } + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1382, __pyx_L1_error) + } else { + __pyx_t_4 = __pyx_t_3(__pyx_t_1); + if (unlikely(!__pyx_t_4)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 1382, __pyx_L1_error) + PyErr_Clear(); + } + break; + } + } + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_p); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_p, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + __pyx_t_4 = 0; + __pyx_t_5 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_math); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1382, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_isclose); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1382, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_GetItemInt(__pyx_cur_scope->__pyx_v_p, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_SharedReference); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1382, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_8 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_7); + assert(__pyx_t_5); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_7, __pyx__function); + __pyx_t_8 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_5, __pyx_t_6, __pyx_mstate_global->__pyx_float_0_0}; + __pyx_t_4 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_7, __pyx_callargs+__pyx_t_8, (3-__pyx_t_8) | (__pyx_t_8*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1382, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + } + __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_9 < 0))) __PYX_ERR(0, 1382, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_10 = (!__pyx_t_9); + if (__pyx_t_10) { + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(Py_False); + __pyx_r = Py_False; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + goto __pyx_L0; + } + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(Py_True); + __pyx_r = Py_True; + goto __pyx_L0; + } + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + if (__Pyx_PyErr_Occurred()) { + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1380 + * + * + * def _is_linelike(segment): # <<<<<<<<<<<<<< + * maybeline = _alignment_transformation(segment).transformPoints(segment) + * return all(math.isclose(p[1], 0.0) for p in maybeline) +*/ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_86_is_linelike(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_segment) { + PyObject *__pyx_v_maybeline = NULL; + PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_12_is_linelike_2generator5 = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + size_t __pyx_t_6; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_is_linelike", 0); + + /* "fontTools/misc/bezierTools.py":1381 + * + * def _is_linelike(segment): + * maybeline = _alignment_transformation(segment).transformPoints(segment) # <<<<<<<<<<<<<< + * return all(math.isclose(p[1], 0.0) for p in maybeline) + * +*/ + __pyx_t_4 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_alignment_transformation); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1381, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5); + assert(__pyx_t_4); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_5, __pyx__function); + __pyx_t_6 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_v_segment}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_5, __pyx_callargs+__pyx_t_6, (2-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1381, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __pyx_t_2 = __pyx_t_3; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_6 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_v_segment}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_transformPoints, __pyx_callargs+__pyx_t_6, (2-__pyx_t_6) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1381, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_v_maybeline = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1382 + * def _is_linelike(segment): + * maybeline = _alignment_transformation(segment).transformPoints(segment) + * return all(math.isclose(p[1], 0.0) for p in maybeline) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_pf_9fontTools_4misc_11bezierTools_12_is_linelike_genexpr(NULL, __pyx_v_maybeline); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1382, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_Generator_GetInlinedResult(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1382, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1380 + * + * + * def _is_linelike(segment): # <<<<<<<<<<<<<< + * maybeline = _alignment_transformation(segment).transformPoints(segment) + * return all(math.isclose(p[1], 0.0) for p in maybeline) +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.misc.bezierTools._is_linelike", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_maybeline); + __Pyx_XDECREF(__pyx_gb_9fontTools_4misc_11bezierTools_12_is_linelike_2generator5); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1385 + * + * + * def curveCurveIntersections(curve1, curve2): # <<<<<<<<<<<<<< + * """Finds intersections between a curve and a curve. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_89curveCurveIntersections(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_88curveCurveIntersections, "curveCurveIntersections(curve1, curve2)\n\nFinds intersections between a curve and a curve.\n\nArgs:\n curve1: List of coordinates of the first curve segment as 2D tuples.\n curve2: List of coordinates of the second curve segment as 2D tuples.\n\nReturns:\n A list of ``Intersection`` objects, each object having ``pt``, ``t1``\n and ``t2`` attributes containing the intersection point, time on first\n segment and time on second segment respectively.\n\nExamples::\n >>> curve1 = [ (10,100), (90,30), (40,140), (220,220) ]\n >>> curve2 = [ (5,150), (180,20), (80,250), (210,190) ]\n >>> intersections = curveCurveIntersections(curve1, curve2)\n >>> len(intersections)\n 3\n >>> intersections[0].pt\n (81.7831487395506, 109.88904552375288)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_89curveCurveIntersections = {"curveCurveIntersections", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_89curveCurveIntersections, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_88curveCurveIntersections}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_89curveCurveIntersections(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_curve1 = 0; + PyObject *__pyx_v_curve2 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("curveCurveIntersections (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_curve1,&__pyx_mstate_global->__pyx_n_u_curve2,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1385, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1385, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1385, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "curveCurveIntersections", 0) < (0)) __PYX_ERR(0, 1385, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("curveCurveIntersections", 1, 2, 2, i); __PYX_ERR(0, 1385, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1385, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1385, __pyx_L3_error) + } + __pyx_v_curve1 = values[0]; + __pyx_v_curve2 = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("curveCurveIntersections", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 1385, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.curveCurveIntersections", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_88curveCurveIntersections(__pyx_self, __pyx_v_curve1, __pyx_v_curve2); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_88curveCurveIntersections(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_curve1, PyObject *__pyx_v_curve2) { + PyObject *__pyx_v_line1 = NULL; + PyObject *__pyx_v_line2 = NULL; + PyObject *__pyx_v_hits = NULL; + PyObject *__pyx_v_intersection_ts = NULL; + PyObject *__pyx_8genexpr8__pyx_v_x = NULL; + PyObject *__pyx_8genexpr9__pyx_v_ts = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + size_t __pyx_t_4; + int __pyx_t_5; + Py_ssize_t __pyx_t_6; + PyObject *(*__pyx_t_7)(PyObject *); + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + PyObject *__pyx_t_13 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("curveCurveIntersections", 0); + + /* "fontTools/misc/bezierTools.py":1406 + * (81.7831487395506, 109.88904552375288) + * """ + * if _is_linelike(curve1): # <<<<<<<<<<<<<< + * line1 = curve1[0], curve1[-1] + * if _is_linelike(curve2): +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_is_linelike); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1406, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_v_curve1}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_4, (2-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1406, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1406, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1407 + * """ + * if _is_linelike(curve1): + * line1 = curve1[0], curve1[-1] # <<<<<<<<<<<<<< + * if _is_linelike(curve2): + * line2 = curve2[0], curve2[-1] +*/ + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curve1, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1407, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_curve1, -1L, long, 1, __Pyx_PyLong_From_long, 0, 1, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1407, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1407, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1) != (0)) __PYX_ERR(0, 1407, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_3); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3) != (0)) __PYX_ERR(0, 1407, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_3 = 0; + __pyx_v_line1 = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1408 + * if _is_linelike(curve1): + * line1 = curve1[0], curve1[-1] + * if _is_linelike(curve2): # <<<<<<<<<<<<<< + * line2 = curve2[0], curve2[-1] + * return lineLineIntersections(*line1, *line2) +*/ + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_is_linelike); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1408, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_3); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_curve2}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_4, (2-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1408, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1408, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1409 + * line1 = curve1[0], curve1[-1] + * if _is_linelike(curve2): + * line2 = curve2[0], curve2[-1] # <<<<<<<<<<<<<< + * return lineLineIntersections(*line1, *line2) + * else: +*/ + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_curve2, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1409, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curve2, -1L, long, 1, __Pyx_PyLong_From_long, 0, 1, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1409, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1409, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2) != (0)) __PYX_ERR(0, 1409, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1) != (0)) __PYX_ERR(0, 1409, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_1 = 0; + __pyx_v_line2 = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1410 + * if _is_linelike(curve2): + * line2 = curve2[0], curve2[-1] + * return lineLineIntersections(*line1, *line2) # <<<<<<<<<<<<<< + * else: + * hits = curveLineIntersections(curve2, line1) +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_lineLineIntersections); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1410, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyNumber_Add(__pyx_v_line1, __pyx_v_line2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1410, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1410, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1408 + * if _is_linelike(curve1): + * line1 = curve1[0], curve1[-1] + * if _is_linelike(curve2): # <<<<<<<<<<<<<< + * line2 = curve2[0], curve2[-1] + * return lineLineIntersections(*line1, *line2) +*/ + } + + /* "fontTools/misc/bezierTools.py":1412 + * return lineLineIntersections(*line1, *line2) + * else: + * hits = curveLineIntersections(curve2, line1) # <<<<<<<<<<<<<< + * # curve is passed first to this fn but is the second segment, so + * # we need to swap t1/t2 in the result +*/ + /*else*/ { + __pyx_t_1 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_curveLineIntersections); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1412, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_3); + assert(__pyx_t_1); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_1, __pyx_v_curve2, __pyx_v_line1}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_4, (3-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1412, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __pyx_v_hits = __pyx_t_2; + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1415 + * # curve is passed first to this fn but is the second segment, so + * # we need to swap t1/t2 in the result + * return [Intersection(pt=x.pt, t1=x.t2, t2=x.t1) for x in hits] # <<<<<<<<<<<<<< + * elif _is_linelike(curve2): + * line2 = curve2[0], curve2[-1] +*/ + __Pyx_XDECREF(__pyx_r); + { /* enter inner scope */ + __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1415, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_2); + if (likely(PyList_CheckExact(__pyx_v_hits)) || PyTuple_CheckExact(__pyx_v_hits)) { + __pyx_t_3 = __pyx_v_hits; __Pyx_INCREF(__pyx_t_3); + __pyx_t_6 = 0; + __pyx_t_7 = NULL; + } else { + __pyx_t_6 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_hits); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1415, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1415, __pyx_L7_error) + } + for (;;) { + if (likely(!__pyx_t_7)) { + if (likely(PyList_CheckExact(__pyx_t_3))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_3); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1415, __pyx_L7_error) + #endif + if (__pyx_t_6 >= __pyx_temp) break; + } + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(__pyx_t_3, __pyx_t_6, __Pyx_ReferenceSharing_OwnStrongReference); + ++__pyx_t_6; + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_3); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1415, __pyx_L7_error) + #endif + if (__pyx_t_6 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_1 = __Pyx_NewRef(PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_6)); + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(__pyx_t_3, __pyx_t_6); + #endif + ++__pyx_t_6; + } + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1415, __pyx_L7_error) + } else { + __pyx_t_1 = __pyx_t_7(__pyx_t_3); + if (unlikely(!__pyx_t_1)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 1415, __pyx_L7_error) + PyErr_Clear(); + } + break; + } + } + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XDECREF_SET(__pyx_8genexpr8__pyx_v_x, __pyx_t_1); + __pyx_t_1 = 0; + __pyx_t_8 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_mstate_global->__pyx_n_u_Intersection); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1415, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_8genexpr8__pyx_v_x, __pyx_mstate_global->__pyx_n_u_pt); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1415, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_8genexpr8__pyx_v_x, __pyx_mstate_global->__pyx_n_u_t2); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1415, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_8genexpr8__pyx_v_x, __pyx_mstate_global->__pyx_n_u_t1); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1415, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_12); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_9))) { + __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_9); + assert(__pyx_t_8); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_9); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_9, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[2 + ((CYTHON_VECTORCALL) ? 3 : 0)] = {__pyx_t_8, NULL}; + __pyx_t_13 = __Pyx_MakeVectorcallBuilderKwds(3); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 1415, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_13); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_pt, __pyx_t_10, __pyx_t_13, __pyx_callargs+1, 0) < (0)) __PYX_ERR(0, 1415, __pyx_L7_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_t1, __pyx_t_11, __pyx_t_13, __pyx_callargs+1, 1) < (0)) __PYX_ERR(0, 1415, __pyx_L7_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_t2, __pyx_t_12, __pyx_t_13, __pyx_callargs+1, 2) < (0)) __PYX_ERR(0, 1415, __pyx_L7_error) + __pyx_t_1 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_9, __pyx_callargs+__pyx_t_4, (1-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_13); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1415, __pyx_L7_error) + __Pyx_GOTREF(__pyx_t_1); + } + if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_1))) __PYX_ERR(0, 1415, __pyx_L7_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_8genexpr8__pyx_v_x); __pyx_8genexpr8__pyx_v_x = 0; + goto __pyx_L11_exit_scope; + __pyx_L7_error:; + __Pyx_XDECREF(__pyx_8genexpr8__pyx_v_x); __pyx_8genexpr8__pyx_v_x = 0; + goto __pyx_L1_error; + __pyx_L11_exit_scope:; + } /* exit inner scope */ + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + } + + /* "fontTools/misc/bezierTools.py":1406 + * (81.7831487395506, 109.88904552375288) + * """ + * if _is_linelike(curve1): # <<<<<<<<<<<<<< + * line1 = curve1[0], curve1[-1] + * if _is_linelike(curve2): +*/ + } + + /* "fontTools/misc/bezierTools.py":1416 + * # we need to swap t1/t2 in the result + * return [Intersection(pt=x.pt, t1=x.t2, t2=x.t1) for x in hits] + * elif _is_linelike(curve2): # <<<<<<<<<<<<<< + * line2 = curve2[0], curve2[-1] + * return curveLineIntersections(curve1, line2) +*/ + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_is_linelike); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1416, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_3); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_curve2}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_4, (2-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1416, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 1416, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__pyx_t_5) { + + /* "fontTools/misc/bezierTools.py":1417 + * return [Intersection(pt=x.pt, t1=x.t2, t2=x.t1) for x in hits] + * elif _is_linelike(curve2): + * line2 = curve2[0], curve2[-1] # <<<<<<<<<<<<<< + * return curveLineIntersections(curve1, line2) + * +*/ + __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_curve2, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1417, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_curve2, -1L, long, 1, __Pyx_PyLong_From_long, 0, 1, 1, 1, __Pyx_ReferenceSharing_FunctionArgument); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1417, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1417, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2) != (0)) __PYX_ERR(0, 1417, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1) != (0)) __PYX_ERR(0, 1417, __pyx_L1_error); + __pyx_t_2 = 0; + __pyx_t_1 = 0; + __pyx_v_line2 = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1418 + * elif _is_linelike(curve2): + * line2 = curve2[0], curve2[-1] + * return curveLineIntersections(curve1, line2) # <<<<<<<<<<<<<< + * + * intersection_ts = _curve_curve_intersections_t(curve1, curve2) +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_curveLineIntersections); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1418, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_1); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_1, __pyx_v_curve1, __pyx_v_line2}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_4, (3-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1418, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1416 + * # we need to swap t1/t2 in the result + * return [Intersection(pt=x.pt, t1=x.t2, t2=x.t1) for x in hits] + * elif _is_linelike(curve2): # <<<<<<<<<<<<<< + * line2 = curve2[0], curve2[-1] + * return curveLineIntersections(curve1, line2) +*/ + } + + /* "fontTools/misc/bezierTools.py":1420 + * return curveLineIntersections(curve1, line2) + * + * intersection_ts = _curve_curve_intersections_t(curve1, curve2) # <<<<<<<<<<<<<< + * return [ + * Intersection(pt=segmentPointAtT(curve1, ts[0]), t1=ts[0], t2=ts[1]) +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_curve_curve_intersections_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1420, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_1))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_1); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_1, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_v_curve1, __pyx_v_curve2}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_1, __pyx_callargs+__pyx_t_4, (3-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1420, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __pyx_v_intersection_ts = __pyx_t_3; + __pyx_t_3 = 0; + + /* "fontTools/misc/bezierTools.py":1421 + * + * intersection_ts = _curve_curve_intersections_t(curve1, curve2) + * return [ # <<<<<<<<<<<<<< + * Intersection(pt=segmentPointAtT(curve1, ts[0]), t1=ts[0], t2=ts[1]) + * for ts in intersection_ts +*/ + __Pyx_XDECREF(__pyx_r); + { /* enter inner scope */ + __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1421, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "fontTools/misc/bezierTools.py":1423 + * return [ + * Intersection(pt=segmentPointAtT(curve1, ts[0]), t1=ts[0], t2=ts[1]) + * for ts in intersection_ts # <<<<<<<<<<<<<< + * ] + * +*/ + if (likely(PyList_CheckExact(__pyx_v_intersection_ts)) || PyTuple_CheckExact(__pyx_v_intersection_ts)) { + __pyx_t_1 = __pyx_v_intersection_ts; __Pyx_INCREF(__pyx_t_1); + __pyx_t_6 = 0; + __pyx_t_7 = NULL; + } else { + __pyx_t_6 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_intersection_ts); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1423, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1423, __pyx_L14_error) + } + for (;;) { + if (likely(!__pyx_t_7)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1423, __pyx_L14_error) + #endif + if (__pyx_t_6 >= __pyx_temp) break; + } + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(__pyx_t_1, __pyx_t_6, __Pyx_ReferenceSharing_OwnStrongReference); + ++__pyx_t_6; + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1423, __pyx_L14_error) + #endif + if (__pyx_t_6 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_2 = __Pyx_NewRef(PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_6)); + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_6); + #endif + ++__pyx_t_6; + } + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1423, __pyx_L14_error) + } else { + __pyx_t_2 = __pyx_t_7(__pyx_t_1); + if (unlikely(!__pyx_t_2)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 1423, __pyx_L14_error) + PyErr_Clear(); + } + break; + } + } + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_8genexpr9__pyx_v_ts, __pyx_t_2); + __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1422 + * intersection_ts = _curve_curve_intersections_t(curve1, curve2) + * return [ + * Intersection(pt=segmentPointAtT(curve1, ts[0]), t1=ts[0], t2=ts[1]) # <<<<<<<<<<<<<< + * for ts in intersection_ts + * ] +*/ + __pyx_t_9 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_13, __pyx_mstate_global->__pyx_n_u_Intersection); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 1422, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_13); + __pyx_t_11 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_segmentPointAtT); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1422, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_8 = __Pyx_GetItemInt(__pyx_8genexpr9__pyx_v_ts, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_SharedReference); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1422, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_10))) { + __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_10); + assert(__pyx_t_11); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_10); + __Pyx_INCREF(__pyx_t_11); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_10, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_11, __pyx_v_curve1, __pyx_t_8}; + __pyx_t_12 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_10, __pyx_callargs+__pyx_t_4, (3-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1422, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_12); + } + __pyx_t_10 = __Pyx_GetItemInt(__pyx_8genexpr9__pyx_v_ts, 0, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_SharedReference); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1422, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_8 = __Pyx_GetItemInt(__pyx_8genexpr9__pyx_v_ts, 1, long, 1, __Pyx_PyLong_From_long, 0, 0, 1, 1, __Pyx_ReferenceSharing_SharedReference); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1422, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_4 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_13))) { + __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_13); + assert(__pyx_t_9); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_13); + __Pyx_INCREF(__pyx_t_9); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_13, __pyx__function); + __pyx_t_4 = 0; + } + #endif + { + PyObject *__pyx_callargs[2 + ((CYTHON_VECTORCALL) ? 3 : 0)] = {__pyx_t_9, NULL}; + __pyx_t_11 = __Pyx_MakeVectorcallBuilderKwds(3); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1422, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_11); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_pt, __pyx_t_12, __pyx_t_11, __pyx_callargs+1, 0) < (0)) __PYX_ERR(0, 1422, __pyx_L14_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_t1, __pyx_t_10, __pyx_t_11, __pyx_callargs+1, 1) < (0)) __PYX_ERR(0, 1422, __pyx_L14_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_t2, __pyx_t_8, __pyx_t_11, __pyx_callargs+1, 2) < (0)) __PYX_ERR(0, 1422, __pyx_L14_error) + __pyx_t_2 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_13, __pyx_callargs+__pyx_t_4, (1-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_11); + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1422, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_2); + } + if (unlikely(__Pyx_ListComp_Append(__pyx_t_3, (PyObject*)__pyx_t_2))) __PYX_ERR(0, 1421, __pyx_L14_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1423 + * return [ + * Intersection(pt=segmentPointAtT(curve1, ts[0]), t1=ts[0], t2=ts[1]) + * for ts in intersection_ts # <<<<<<<<<<<<<< + * ] + * +*/ + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_8genexpr9__pyx_v_ts); __pyx_8genexpr9__pyx_v_ts = 0; + goto __pyx_L18_exit_scope; + __pyx_L14_error:; + __Pyx_XDECREF(__pyx_8genexpr9__pyx_v_ts); __pyx_8genexpr9__pyx_v_ts = 0; + goto __pyx_L1_error; + __pyx_L18_exit_scope:; + } /* exit inner scope */ + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1385 + * + * + * def curveCurveIntersections(curve1, curve2): # <<<<<<<<<<<<<< + * """Finds intersections between a curve and a curve. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_XDECREF(__pyx_t_13); + __Pyx_AddTraceback("fontTools.misc.bezierTools.curveCurveIntersections", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_line1); + __Pyx_XDECREF(__pyx_v_line2); + __Pyx_XDECREF(__pyx_v_hits); + __Pyx_XDECREF(__pyx_v_intersection_ts); + __Pyx_XDECREF(__pyx_8genexpr8__pyx_v_x); + __Pyx_XDECREF(__pyx_8genexpr9__pyx_v_ts); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1427 + * + * + * def segmentSegmentIntersections(seg1, seg2): # <<<<<<<<<<<<<< + * """Finds intersections between two segments. + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_91segmentSegmentIntersections(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_90segmentSegmentIntersections, "segmentSegmentIntersections(seg1, seg2)\n\nFinds intersections between two segments.\n\nArgs:\n seg1: List of coordinates of the first segment as 2D tuples.\n seg2: List of coordinates of the second segment as 2D tuples.\n\nReturns:\n A list of ``Intersection`` objects, each object having ``pt``, ``t1``\n and ``t2`` attributes containing the intersection point, time on first\n segment and time on second segment respectively.\n\nExamples::\n >>> curve1 = [ (10,100), (90,30), (40,140), (220,220) ]\n >>> curve2 = [ (5,150), (180,20), (80,250), (210,190) ]\n >>> intersections = segmentSegmentIntersections(curve1, curve2)\n >>> len(intersections)\n 3\n >>> intersections[0].pt\n (81.7831487395506, 109.88904552375288)\n >>> curve3 = [ (100, 240), (30, 60), (210, 230), (160, 30) ]\n >>> line = [ (25, 260), (230, 20) ]\n >>> intersections = segmentSegmentIntersections(curve3, line)\n >>> len(intersections)\n 3\n >>> intersections[0].pt\n (84.9000930760723, 189.87306176459828)"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_91segmentSegmentIntersections = {"segmentSegmentIntersections", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_91segmentSegmentIntersections, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_90segmentSegmentIntersections}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_91segmentSegmentIntersections(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_seg1 = 0; + PyObject *__pyx_v_seg2 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("segmentSegmentIntersections (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_seg1,&__pyx_mstate_global->__pyx_n_u_seg2,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1427, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1427, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1427, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "segmentSegmentIntersections", 0) < (0)) __PYX_ERR(0, 1427, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("segmentSegmentIntersections", 1, 2, 2, i); __PYX_ERR(0, 1427, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1427, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 1427, __pyx_L3_error) + } + __pyx_v_seg1 = values[0]; + __pyx_v_seg2 = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("segmentSegmentIntersections", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 1427, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.segmentSegmentIntersections", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_90segmentSegmentIntersections(__pyx_self, __pyx_v_seg1, __pyx_v_seg2); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_90segmentSegmentIntersections(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_seg1, PyObject *__pyx_v_seg2) { + int __pyx_v_swapped; + PyObject *__pyx_v_intersections = NULL; + PyObject *__pyx_9genexpr10__pyx_v_i = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + Py_ssize_t __pyx_t_1; + Py_ssize_t __pyx_t_2; + int __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + size_t __pyx_t_9; + int __pyx_t_10; + PyObject *__pyx_t_11 = NULL; + PyObject *(*__pyx_t_12)(PyObject *); + PyObject *__pyx_t_13 = NULL; + PyObject *__pyx_t_14 = NULL; + PyObject *__pyx_t_15 = NULL; + PyObject *__pyx_t_16 = NULL; + PyObject *__pyx_t_17 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("segmentSegmentIntersections", 0); + __Pyx_INCREF(__pyx_v_seg1); + __Pyx_INCREF(__pyx_v_seg2); + + /* "fontTools/misc/bezierTools.py":1457 + * """ + * # Arrange by degree + * swapped = False # <<<<<<<<<<<<<< + * if len(seg2) > len(seg1): + * seg2, seg1 = seg1, seg2 +*/ + __pyx_v_swapped = 0; + + /* "fontTools/misc/bezierTools.py":1458 + * # Arrange by degree + * swapped = False + * if len(seg2) > len(seg1): # <<<<<<<<<<<<<< + * seg2, seg1 = seg1, seg2 + * swapped = True +*/ + __pyx_t_1 = PyObject_Length(__pyx_v_seg2); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1458, __pyx_L1_error) + __pyx_t_2 = PyObject_Length(__pyx_v_seg1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1458, __pyx_L1_error) + __pyx_t_3 = (__pyx_t_1 > __pyx_t_2); + if (__pyx_t_3) { + + /* "fontTools/misc/bezierTools.py":1459 + * swapped = False + * if len(seg2) > len(seg1): + * seg2, seg1 = seg1, seg2 # <<<<<<<<<<<<<< + * swapped = True + * if len(seg1) > 2: +*/ + __pyx_t_4 = __pyx_v_seg1; + __pyx_t_5 = __pyx_v_seg2; + __pyx_v_seg2 = __pyx_t_4; + __pyx_t_4 = 0; + __pyx_v_seg1 = __pyx_t_5; + __pyx_t_5 = 0; + + /* "fontTools/misc/bezierTools.py":1460 + * if len(seg2) > len(seg1): + * seg2, seg1 = seg1, seg2 + * swapped = True # <<<<<<<<<<<<<< + * if len(seg1) > 2: + * if len(seg2) > 2: +*/ + __pyx_v_swapped = 1; + + /* "fontTools/misc/bezierTools.py":1458 + * # Arrange by degree + * swapped = False + * if len(seg2) > len(seg1): # <<<<<<<<<<<<<< + * seg2, seg1 = seg1, seg2 + * swapped = True +*/ + } + + /* "fontTools/misc/bezierTools.py":1461 + * seg2, seg1 = seg1, seg2 + * swapped = True + * if len(seg1) > 2: # <<<<<<<<<<<<<< + * if len(seg2) > 2: + * intersections = curveCurveIntersections(seg1, seg2) +*/ + __pyx_t_2 = PyObject_Length(__pyx_v_seg1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1461, __pyx_L1_error) + __pyx_t_3 = (__pyx_t_2 > 2); + if (__pyx_t_3) { + + /* "fontTools/misc/bezierTools.py":1462 + * swapped = True + * if len(seg1) > 2: + * if len(seg2) > 2: # <<<<<<<<<<<<<< + * intersections = curveCurveIntersections(seg1, seg2) + * else: +*/ + __pyx_t_2 = PyObject_Length(__pyx_v_seg2); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1462, __pyx_L1_error) + __pyx_t_3 = (__pyx_t_2 > 2); + if (__pyx_t_3) { + + /* "fontTools/misc/bezierTools.py":1463 + * if len(seg1) > 2: + * if len(seg2) > 2: + * intersections = curveCurveIntersections(seg1, seg2) # <<<<<<<<<<<<<< + * else: + * intersections = curveLineIntersections(seg1, seg2) +*/ + __pyx_t_7 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_curveCurveIntersections); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1463, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_8))) { + __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_8); + assert(__pyx_t_7); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_8); + __Pyx_INCREF(__pyx_t_7); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_8, __pyx__function); + __pyx_t_9 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_7, __pyx_v_seg1, __pyx_v_seg2}; + __pyx_t_6 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_8, __pyx_callargs+__pyx_t_9, (3-__pyx_t_9) | (__pyx_t_9*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1463, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + __pyx_v_intersections = __pyx_t_6; + __pyx_t_6 = 0; + + /* "fontTools/misc/bezierTools.py":1462 + * swapped = True + * if len(seg1) > 2: + * if len(seg2) > 2: # <<<<<<<<<<<<<< + * intersections = curveCurveIntersections(seg1, seg2) + * else: +*/ + goto __pyx_L5; + } + + /* "fontTools/misc/bezierTools.py":1465 + * intersections = curveCurveIntersections(seg1, seg2) + * else: + * intersections = curveLineIntersections(seg1, seg2) # <<<<<<<<<<<<<< + * elif len(seg1) == 2 and len(seg2) == 2: + * intersections = lineLineIntersections(*seg1, *seg2) +*/ + /*else*/ { + __pyx_t_8 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_curveLineIntersections); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1465, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_9 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7); + assert(__pyx_t_8); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_7, __pyx__function); + __pyx_t_9 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_8, __pyx_v_seg1, __pyx_v_seg2}; + __pyx_t_6 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_7, __pyx_callargs+__pyx_t_9, (3-__pyx_t_9) | (__pyx_t_9*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1465, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + __pyx_v_intersections = __pyx_t_6; + __pyx_t_6 = 0; + } + __pyx_L5:; + + /* "fontTools/misc/bezierTools.py":1461 + * seg2, seg1 = seg1, seg2 + * swapped = True + * if len(seg1) > 2: # <<<<<<<<<<<<<< + * if len(seg2) > 2: + * intersections = curveCurveIntersections(seg1, seg2) +*/ + goto __pyx_L4; + } + + /* "fontTools/misc/bezierTools.py":1466 + * else: + * intersections = curveLineIntersections(seg1, seg2) + * elif len(seg1) == 2 and len(seg2) == 2: # <<<<<<<<<<<<<< + * intersections = lineLineIntersections(*seg1, *seg2) + * else: +*/ + __pyx_t_2 = PyObject_Length(__pyx_v_seg1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1466, __pyx_L1_error) + __pyx_t_10 = (__pyx_t_2 == 2); + if (__pyx_t_10) { + } else { + __pyx_t_3 = __pyx_t_10; + goto __pyx_L6_bool_binop_done; + } + __pyx_t_2 = PyObject_Length(__pyx_v_seg2); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1466, __pyx_L1_error) + __pyx_t_10 = (__pyx_t_2 == 2); + __pyx_t_3 = __pyx_t_10; + __pyx_L6_bool_binop_done:; + if (likely(__pyx_t_3)) { + + /* "fontTools/misc/bezierTools.py":1467 + * intersections = curveLineIntersections(seg1, seg2) + * elif len(seg1) == 2 and len(seg2) == 2: + * intersections = lineLineIntersections(*seg1, *seg2) # <<<<<<<<<<<<<< + * else: + * raise ValueError("Couldn't work out which intersection function to use") +*/ + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_lineLineIntersections); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1467, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __Pyx_PySequence_Tuple(__pyx_v_seg1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1467, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_PySequence_Tuple(__pyx_v_seg2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1467, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_11 = PyNumber_Add(__pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1467, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_11, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1467, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __pyx_v_intersections = __pyx_t_8; + __pyx_t_8 = 0; + + /* "fontTools/misc/bezierTools.py":1466 + * else: + * intersections = curveLineIntersections(seg1, seg2) + * elif len(seg1) == 2 and len(seg2) == 2: # <<<<<<<<<<<<<< + * intersections = lineLineIntersections(*seg1, *seg2) + * else: +*/ + goto __pyx_L4; + } + + /* "fontTools/misc/bezierTools.py":1469 + * intersections = lineLineIntersections(*seg1, *seg2) + * else: + * raise ValueError("Couldn't work out which intersection function to use") # <<<<<<<<<<<<<< + * if not swapped: + * return intersections +*/ + /*else*/ { + __pyx_t_11 = NULL; + __pyx_t_9 = 1; + { + PyObject *__pyx_callargs[2] = {__pyx_t_11, __pyx_mstate_global->__pyx_kp_u_Couldn_t_work_out_which_intersec}; + __pyx_t_8 = __Pyx_PyObject_FastCall((PyObject*)(((PyTypeObject*)PyExc_ValueError)), __pyx_callargs+__pyx_t_9, (2-__pyx_t_9) | (__pyx_t_9*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1469, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + } + __Pyx_Raise(__pyx_t_8, 0, 0, 0); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __PYX_ERR(0, 1469, __pyx_L1_error) + } + __pyx_L4:; + + /* "fontTools/misc/bezierTools.py":1470 + * else: + * raise ValueError("Couldn't work out which intersection function to use") + * if not swapped: # <<<<<<<<<<<<<< + * return intersections + * return [Intersection(pt=i.pt, t1=i.t2, t2=i.t1) for i in intersections] +*/ + __pyx_t_3 = (!__pyx_v_swapped); + if (__pyx_t_3) { + + /* "fontTools/misc/bezierTools.py":1471 + * raise ValueError("Couldn't work out which intersection function to use") + * if not swapped: + * return intersections # <<<<<<<<<<<<<< + * return [Intersection(pt=i.pt, t1=i.t2, t2=i.t1) for i in intersections] + * +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_intersections); + __pyx_r = __pyx_v_intersections; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1470 + * else: + * raise ValueError("Couldn't work out which intersection function to use") + * if not swapped: # <<<<<<<<<<<<<< + * return intersections + * return [Intersection(pt=i.pt, t1=i.t2, t2=i.t1) for i in intersections] +*/ + } + + /* "fontTools/misc/bezierTools.py":1472 + * if not swapped: + * return intersections + * return [Intersection(pt=i.pt, t1=i.t2, t2=i.t1) for i in intersections] # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + { /* enter inner scope */ + __pyx_t_8 = PyList_New(0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1472, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_8); + if (likely(PyList_CheckExact(__pyx_v_intersections)) || PyTuple_CheckExact(__pyx_v_intersections)) { + __pyx_t_11 = __pyx_v_intersections; __Pyx_INCREF(__pyx_t_11); + __pyx_t_2 = 0; + __pyx_t_12 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_11 = PyObject_GetIter(__pyx_v_intersections); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1472, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_12 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_11); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1472, __pyx_L11_error) + } + for (;;) { + if (likely(!__pyx_t_12)) { + if (likely(PyList_CheckExact(__pyx_t_11))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_11); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1472, __pyx_L11_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + __pyx_t_6 = __Pyx_PyList_GetItemRefFast(__pyx_t_11, __pyx_t_2, __Pyx_ReferenceSharing_OwnStrongReference); + ++__pyx_t_2; + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_11); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1472, __pyx_L11_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_6 = __Pyx_NewRef(PyTuple_GET_ITEM(__pyx_t_11, __pyx_t_2)); + #else + __pyx_t_6 = __Pyx_PySequence_ITEM(__pyx_t_11, __pyx_t_2); + #endif + ++__pyx_t_2; + } + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1472, __pyx_L11_error) + } else { + __pyx_t_6 = __pyx_t_12(__pyx_t_11); + if (unlikely(!__pyx_t_6)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 1472, __pyx_L11_error) + PyErr_Clear(); + } + break; + } + } + __Pyx_GOTREF(__pyx_t_6); + __Pyx_XDECREF_SET(__pyx_9genexpr10__pyx_v_i, __pyx_t_6); + __pyx_t_6 = 0; + __pyx_t_7 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_13, __pyx_mstate_global->__pyx_n_u_Intersection); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 1472, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_13); + __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_9genexpr10__pyx_v_i, __pyx_mstate_global->__pyx_n_u_pt); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 1472, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_14); + __pyx_t_15 = __Pyx_PyObject_GetAttrStr(__pyx_9genexpr10__pyx_v_i, __pyx_mstate_global->__pyx_n_u_t2); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 1472, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_15); + __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_9genexpr10__pyx_v_i, __pyx_mstate_global->__pyx_n_u_t1); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 1472, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_16); + __pyx_t_9 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_13))) { + __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_13); + assert(__pyx_t_7); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_13); + __Pyx_INCREF(__pyx_t_7); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_13, __pyx__function); + __pyx_t_9 = 0; + } + #endif + { + PyObject *__pyx_callargs[2 + ((CYTHON_VECTORCALL) ? 3 : 0)] = {__pyx_t_7, NULL}; + __pyx_t_17 = __Pyx_MakeVectorcallBuilderKwds(3); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 1472, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_17); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_pt, __pyx_t_14, __pyx_t_17, __pyx_callargs+1, 0) < (0)) __PYX_ERR(0, 1472, __pyx_L11_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_t1, __pyx_t_15, __pyx_t_17, __pyx_callargs+1, 1) < (0)) __PYX_ERR(0, 1472, __pyx_L11_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_t2, __pyx_t_16, __pyx_t_17, __pyx_callargs+1, 2) < (0)) __PYX_ERR(0, 1472, __pyx_L11_error) + __pyx_t_6 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_13, __pyx_callargs+__pyx_t_9, (1-__pyx_t_9) | (__pyx_t_9*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_17); + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; + __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0; + __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0; + __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0; + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1472, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_6); + } + if (unlikely(__Pyx_ListComp_Append(__pyx_t_8, (PyObject*)__pyx_t_6))) __PYX_ERR(0, 1472, __pyx_L11_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_XDECREF(__pyx_9genexpr10__pyx_v_i); __pyx_9genexpr10__pyx_v_i = 0; + goto __pyx_L15_exit_scope; + __pyx_L11_error:; + __Pyx_XDECREF(__pyx_9genexpr10__pyx_v_i); __pyx_9genexpr10__pyx_v_i = 0; + goto __pyx_L1_error; + __pyx_L15_exit_scope:; + } /* exit inner scope */ + __pyx_r = __pyx_t_8; + __pyx_t_8 = 0; + goto __pyx_L0; + + /* "fontTools/misc/bezierTools.py":1427 + * + * + * def segmentSegmentIntersections(seg1, seg2): # <<<<<<<<<<<<<< + * """Finds intersections between two segments. + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_13); + __Pyx_XDECREF(__pyx_t_14); + __Pyx_XDECREF(__pyx_t_15); + __Pyx_XDECREF(__pyx_t_16); + __Pyx_XDECREF(__pyx_t_17); + __Pyx_AddTraceback("fontTools.misc.bezierTools.segmentSegmentIntersections", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_intersections); + __Pyx_XDECREF(__pyx_9genexpr10__pyx_v_i); + __Pyx_XDECREF(__pyx_v_seg1); + __Pyx_XDECREF(__pyx_v_seg2); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1475 + * + * + * def _segmentrepr(obj): # <<<<<<<<<<<<<< + * """ + * >>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]]) +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_93_segmentrepr(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_92_segmentrepr, "_segmentrepr(obj)\n\n>>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]])\n'(1, (2, 3), (), ((2, (3, 4), (0.1, 2.2))))'"); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_93_segmentrepr = {"_segmentrepr", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_93_segmentrepr, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_92_segmentrepr}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_93_segmentrepr(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_obj = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_segmentrepr (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_obj,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1475, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1475, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_segmentrepr", 0) < (0)) __PYX_ERR(0, 1475, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_segmentrepr", 1, 1, 1, i); __PYX_ERR(0, 1475, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1475, __pyx_L3_error) + } + __pyx_v_obj = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_segmentrepr", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 1475, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools._segmentrepr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_92_segmentrepr(__pyx_self, __pyx_v_obj); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_12_segmentrepr_2generator6(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "fontTools/misc/bezierTools.py":1485 + * return "%g" % obj + * else: + * return "(%s)" % ", ".join(_segmentrepr(x) for x in it) # <<<<<<<<<<<<<< + * + * +*/ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_12_segmentrepr_genexpr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("genexpr", 0); + __pyx_cur_scope = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr(__pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr, __pyx_mstate_global->__pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 1485, __pyx_L1_error) + } else { + __Pyx_GOTREF((PyObject *)__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_genexpr_arg_0 = __pyx_genexpr_arg_0; + __Pyx_INCREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_genexpr_arg_0); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9fontTools_4misc_11bezierTools_12_segmentrepr_2generator6, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[8]), (PyObject *) __pyx_cur_scope, __pyx_mstate_global->__pyx_n_u_genexpr, __pyx_mstate_global->__pyx_n_u_segmentrepr_locals_genexpr, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools); if (unlikely(!gen)) __PYX_ERR(0, 1485, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.misc.bezierTools._segmentrepr.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF((PyObject *)__pyx_cur_scope); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_12_segmentrepr_2generator6(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *__pyx_cur_scope = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *(*__pyx_t_3)(PyObject *); + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + size_t __pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("genexpr", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 1485, __pyx_L1_error) + __pyx_r = PyList_New(0); if (unlikely(!__pyx_r)) __PYX_ERR(0, 1485, __pyx_L1_error) + __Pyx_GOTREF(__pyx_r); + if (unlikely(!__pyx_cur_scope->__pyx_genexpr_arg_0)) { __Pyx_RaiseUnboundLocalError(".0"); __PYX_ERR(0, 1485, __pyx_L1_error) } + if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_genexpr_arg_0)) { + __pyx_t_1 = __pyx_cur_scope->__pyx_genexpr_arg_0; __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = 0; + __pyx_t_3 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_genexpr_arg_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1485, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1485, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_3)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1485, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(__pyx_t_1, __pyx_t_2, __Pyx_ReferenceSharing_OwnStrongReference); + ++__pyx_t_2; + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1485, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = __Pyx_NewRef(PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2)); + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); + #endif + ++__pyx_t_2; + } + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1485, __pyx_L1_error) + } else { + __pyx_t_4 = __pyx_t_3(__pyx_t_1); + if (unlikely(!__pyx_t_4)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 1485, __pyx_L1_error) + PyErr_Clear(); + } + break; + } + } + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_x); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_x, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + __pyx_t_4 = 0; + __pyx_t_5 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_segmentrepr); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1485, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6); + assert(__pyx_t_5); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_6, __pyx__function); + __pyx_t_7 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_cur_scope->__pyx_v_x}; + __pyx_t_4 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_6, __pyx_callargs+__pyx_t_7, (2-__pyx_t_7) | (__pyx_t_7*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1485, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + } + if (unlikely(__Pyx_ListComp_Append(__pyx_r, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 1485, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_r); __pyx_r = 0; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + if (__Pyx_PyErr_Occurred()) { + __Pyx_Generator_Replace_StopIteration(0); + __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1475 + * + * + * def _segmentrepr(obj): # <<<<<<<<<<<<<< + * """ + * >>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]]) +*/ + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_92_segmentrepr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_obj) { + PyObject *__pyx_v_it = NULL; + PyObject *__pyx_gb_9fontTools_4misc_11bezierTools_12_segmentrepr_2generator6 = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_segmentrepr", 0); + + /* "fontTools/misc/bezierTools.py":1480 + * '(1, (2, 3), (), ((2, (3, 4), (0.1, 2.2))))' + * """ + * try: # <<<<<<<<<<<<<< + * it = iter(obj) + * except TypeError: +*/ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "fontTools/misc/bezierTools.py":1481 + * """ + * try: + * it = iter(obj) # <<<<<<<<<<<<<< + * except TypeError: + * return "%g" % obj +*/ + __pyx_t_4 = PyObject_GetIter(__pyx_v_obj); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1481, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_v_it = __pyx_t_4; + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1480 + * '(1, (2, 3), (), ((2, (3, 4), (0.1, 2.2))))' + * """ + * try: # <<<<<<<<<<<<<< + * it = iter(obj) + * except TypeError: +*/ + } + + /* "fontTools/misc/bezierTools.py":1485 + * return "%g" % obj + * else: + * return "(%s)" % ", ".join(_segmentrepr(x) for x in it) # <<<<<<<<<<<<<< + * + * +*/ + /*else:*/ { + __Pyx_XDECREF(__pyx_r); + __pyx_t_4 = __pyx_pf_9fontTools_4misc_11bezierTools_12_segmentrepr_genexpr(NULL, __pyx_v_it); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1485, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_Generator_GetInlinedResult(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1485, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyUnicode_Join(__pyx_mstate_global->__pyx_kp_u_, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1485, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = PyUnicode_Format(__pyx_mstate_global->__pyx_kp_u_s_2, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1485, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L6_except_return; + } + __pyx_L3_error:; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1482 + * try: + * it = iter(obj) + * except TypeError: # <<<<<<<<<<<<<< + * return "%g" % obj + * else: +*/ + __pyx_t_6 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(((PyTypeObject*)PyExc_TypeError)))); + if (__pyx_t_6) { + __Pyx_AddTraceback("fontTools.misc.bezierTools._segmentrepr", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_4, &__pyx_t_7) < 0) __PYX_ERR(0, 1482, __pyx_L5_except_error) + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_7); + + /* "fontTools/misc/bezierTools.py":1483 + * it = iter(obj) + * except TypeError: + * return "%g" % obj # <<<<<<<<<<<<<< + * else: + * return "(%s)" % ", ".join(_segmentrepr(x) for x in it) +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_8 = __Pyx_PyUnicode_FormatSafe(__pyx_mstate_global->__pyx_kp_u_g, __pyx_v_obj); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1483, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_r = __pyx_t_8; + __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L6_except_return; + } + goto __pyx_L5_except_error; + + /* "fontTools/misc/bezierTools.py":1480 + * '(1, (2, 3), (), ((2, (3, 4), (0.1, 2.2))))' + * """ + * try: # <<<<<<<<<<<<<< + * it = iter(obj) + * except TypeError: +*/ + __pyx_L5_except_error:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L6_except_return:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L0; + } + + /* "fontTools/misc/bezierTools.py":1475 + * + * + * def _segmentrepr(obj): # <<<<<<<<<<<<<< + * """ + * >>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]]) +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("fontTools.misc.bezierTools._segmentrepr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_it); + __Pyx_XDECREF(__pyx_gb_9fontTools_4misc_11bezierTools_12_segmentrepr_2generator6); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/misc/bezierTools.py":1488 + * + * + * def printSegments(segments): # <<<<<<<<<<<<<< + * """Helper for the doctests, displaying each segment in a list of + * segments on a single line as a tuple. +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_95printSegments(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4misc_11bezierTools_94printSegments, "printSegments(segments)\n\nHelper for the doctests, displaying each segment in a list of\nsegments on a single line as a tuple."); +static PyMethodDef __pyx_mdef_9fontTools_4misc_11bezierTools_95printSegments = {"printSegments", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4misc_11bezierTools_95printSegments, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4misc_11bezierTools_94printSegments}; +static PyObject *__pyx_pw_9fontTools_4misc_11bezierTools_95printSegments(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_segments = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("printSegments (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_segments,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 1488, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1488, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "printSegments", 0) < (0)) __PYX_ERR(0, 1488, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("printSegments", 1, 1, 1, i); __PYX_ERR(0, 1488, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 1488, __pyx_L3_error) + } + __pyx_v_segments = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("printSegments", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 1488, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.misc.bezierTools.printSegments", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4misc_11bezierTools_94printSegments(__pyx_self, __pyx_v_segments); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4misc_11bezierTools_94printSegments(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_segments) { + PyObject *__pyx_v_segment = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *(*__pyx_t_3)(PyObject *); + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + size_t __pyx_t_9; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("printSegments", 0); + + /* "fontTools/misc/bezierTools.py":1492 + * segments on a single line as a tuple. + * """ + * for segment in segments: # <<<<<<<<<<<<<< + * print(_segmentrepr(segment)) + * +*/ + if (likely(PyList_CheckExact(__pyx_v_segments)) || PyTuple_CheckExact(__pyx_v_segments)) { + __pyx_t_1 = __pyx_v_segments; __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = 0; + __pyx_t_3 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_segments); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1492, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1492, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_3)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1492, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(__pyx_t_1, __pyx_t_2, __Pyx_ReferenceSharing_OwnStrongReference); + ++__pyx_t_2; + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1492, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = __Pyx_NewRef(PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2)); + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); + #endif + ++__pyx_t_2; + } + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1492, __pyx_L1_error) + } else { + __pyx_t_4 = __pyx_t_3(__pyx_t_1); + if (unlikely(!__pyx_t_4)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 1492, __pyx_L1_error) + PyErr_Clear(); + } + break; + } + } + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_segment, __pyx_t_4); + __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1493 + * """ + * for segment in segments: + * print(_segmentrepr(segment)) # <<<<<<<<<<<<<< + * + * +*/ + __pyx_t_5 = NULL; + __pyx_t_7 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_segmentrepr); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1493, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_8))) { + __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_8); + assert(__pyx_t_7); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_8); + __Pyx_INCREF(__pyx_t_7); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_8, __pyx__function); + __pyx_t_9 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_7, __pyx_v_segment}; + __pyx_t_6 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_8, __pyx_callargs+__pyx_t_9, (2-__pyx_t_9) | (__pyx_t_9*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1493, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + } + __pyx_t_9 = 1; + { + PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_t_6}; + __pyx_t_4 = __Pyx_PyObject_FastCall((PyObject*)__pyx_builtin_print, __pyx_callargs+__pyx_t_9, (2-__pyx_t_9) | (__pyx_t_9*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1493, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + } + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/misc/bezierTools.py":1492 + * segments on a single line as a tuple. + * """ + * for segment in segments: # <<<<<<<<<<<<<< + * print(_segmentrepr(segment)) + * +*/ + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/misc/bezierTools.py":1488 + * + * + * def printSegments(segments): # <<<<<<<<<<<<<< + * """Helper for the doctests, displaying each segment in a list of + * segments on a single line as a tuple. +*/ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("fontTools.misc.bezierTools.printSegments", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_segment); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +/* #### Code section: module_exttypes ### */ + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_defaults(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + o = __Pyx_AllocateExtensionType(t, 1); + if (unlikely(!o)) return 0; + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_defaults(PyObject *o) { + struct __pyx_defaults *p = (struct __pyx_defaults *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely(__Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_defaults) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->arg0); + PyTypeObject *tp = Py_TYPE(o); + #if CYTHON_USE_TYPE_SLOTS + (*tp->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(tp, Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(tp); + #endif +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_defaults(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_defaults *p = (struct __pyx_defaults *)o; + { + e = __Pyx_call_type_traverse(o, 1, v, a); + if (e) return e; + } + if (p->arg0) { + e = (*v)(p->arg0, a); if (e) return e; + } + return 0; +} + +static int __pyx_tp_clear_9fontTools_4misc_11bezierTools___pyx_defaults(PyObject *o) { + PyObject* tmp; + struct __pyx_defaults *p = (struct __pyx_defaults *)o; + tmp = ((PyObject*)p->arg0); + p->arg0 = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_defaults_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_defaults}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_defaults}, + {Py_tp_clear, (void *)__pyx_tp_clear_9fontTools_4misc_11bezierTools___pyx_defaults}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_defaults}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_defaults_spec = { + "fontTools.misc.bezierTools.__pyx_defaults", + sizeof(struct __pyx_defaults), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_defaults_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_defaults = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_defaults", /*tp_name*/ + sizeof(struct __pyx_defaults), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_defaults, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_defaults, /*tp_traverse*/ + __pyx_tp_clear_9fontTools_4misc_11bezierTools___pyx_defaults, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_defaults, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #if !CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800 + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if PY_VERSION_HEX >= 0x030d00A4 + 0, /*tp_versions_used*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_USE_FREELISTS + if (likely((int)(__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr > 0) & __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(t, __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr)))) + { + o = (PyObject*)__pyx_mstate_global->__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr[--__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr]; + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(Py_TYPE(o)); + #endif + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr)); + #if CYTHON_COMPILING_IN_LIMITED_API + (void) PyObject_Init(o, t); + #else + (void) PyObject_INIT(o, t); + #endif + PyObject_GC_Track(o); + } else + #endif + { + o = __Pyx_AllocateExtensionType(t, 1); + if (unlikely(!o)) return 0; + } + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr(PyObject *o) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely(__Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_genexpr_arg_0); + Py_CLEAR(p->__pyx_v_t); + #if CYTHON_USE_FREELISTS + if (likely((int)(__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr < 8) & __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(Py_TYPE(o), __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr)))) + { + __pyx_mstate_global->__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr[__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr++] = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *)o); + } else + #endif + { + PyTypeObject *tp = Py_TYPE(o); + #if CYTHON_USE_TYPE_SLOTS + (*tp->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(tp, Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(tp); + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr *)o; + { + e = __Pyx_call_type_traverse(o, 1, v, a); + if (e) return e; + } + if (p->__pyx_genexpr_arg_0) { + e = (*v)(p->__pyx_genexpr_arg_0, a); if (e) return e; + } + if (p->__pyx_v_t) { + e = (*v)(p->__pyx_v_t, a); if (e) return e; + } + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr_spec = { + "fontTools.misc.bezierTools.__pyx_scope_struct__genexpr", + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_scope_struct__genexpr", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #if !CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800 + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if PY_VERSION_HEX >= 0x030d00A4 + 0, /*tp_versions_used*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_USE_FREELISTS + if (likely((int)(__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr > 0) & __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(t, __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr)))) + { + o = (PyObject*)__pyx_mstate_global->__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr[--__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr]; + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(Py_TYPE(o)); + #endif + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr)); + #if CYTHON_COMPILING_IN_LIMITED_API + (void) PyObject_Init(o, t); + #else + (void) PyObject_INIT(o, t); + #endif + PyObject_GC_Track(o); + } else + #endif + { + o = __Pyx_AllocateExtensionType(t, 1); + if (unlikely(!o)) return 0; + } + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr(PyObject *o) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely(__Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_genexpr_arg_0); + Py_CLEAR(p->__pyx_v_t); + #if CYTHON_USE_FREELISTS + if (likely((int)(__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr < 8) & __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(Py_TYPE(o), __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr)))) + { + __pyx_mstate_global->__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr[__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr++] = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *)o); + } else + #endif + { + PyTypeObject *tp = Py_TYPE(o); + #if CYTHON_USE_TYPE_SLOTS + (*tp->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(tp, Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(tp); + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr *)o; + { + e = __Pyx_call_type_traverse(o, 1, v, a); + if (e) return e; + } + if (p->__pyx_genexpr_arg_0) { + e = (*v)(p->__pyx_genexpr_arg_0, a); if (e) return e; + } + if (p->__pyx_v_t) { + e = (*v)(p->__pyx_v_t, a); if (e) return e; + } + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr_spec = { + "fontTools.misc.bezierTools.__pyx_scope_struct_1_genexpr", + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_scope_struct_1_genexpr", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #if !CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800 + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if PY_VERSION_HEX >= 0x030d00A4 + 0, /*tp_versions_used*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_USE_FREELISTS + if (likely((int)(__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC > 0) & __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(t, __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC)))) + { + o = (PyObject*)__pyx_mstate_global->__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC[--__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC]; + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(Py_TYPE(o)); + #endif + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC)); + #if CYTHON_COMPILING_IN_LIMITED_API + (void) PyObject_Init(o, t); + #else + (void) PyObject_INIT(o, t); + #endif + PyObject_GC_Track(o); + } else + #endif + { + o = __Pyx_AllocateExtensionType(t, 1); + if (unlikely(!o)) return 0; + } + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC(PyObject *o) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely(__Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_v_ts); + #if CYTHON_USE_FREELISTS + if (likely((int)(__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC < 8) & __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(Py_TYPE(o), __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC)))) + { + __pyx_mstate_global->__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC[__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC++] = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *)o); + } else + #endif + { + PyTypeObject *tp = Py_TYPE(o); + #if CYTHON_USE_TYPE_SLOTS + (*tp->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(tp, Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(tp); + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC *)o; + { + e = __Pyx_call_type_traverse(o, 1, v, a); + if (e) return e; + } + if (p->__pyx_v_ts) { + e = (*v)(p->__pyx_v_ts, a); if (e) return e; + } + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC_spec = { + "fontTools.misc.bezierTools.__pyx_scope_struct_2_splitCubicAtTC", + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_scope_struct_2_splitCubicAtTC", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #if !CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800 + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if PY_VERSION_HEX >= 0x030d00A4 + 0, /*tp_versions_used*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_USE_FREELISTS + if (likely((int)(__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC > 0) & __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(t, __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC)))) + { + o = (PyObject*)__pyx_mstate_global->__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC[--__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC]; + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(Py_TYPE(o)); + #endif + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC)); + #if CYTHON_COMPILING_IN_LIMITED_API + (void) PyObject_Init(o, t); + #else + (void) PyObject_INIT(o, t); + #endif + PyObject_GC_Track(o); + } else + #endif + { + o = __Pyx_AllocateExtensionType(t, 1); + if (unlikely(!o)) return 0; + } + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC(PyObject *o) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely(__Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_v_i); + Py_CLEAR(p->__pyx_v_pt1); + Py_CLEAR(p->__pyx_v_pt2); + Py_CLEAR(p->__pyx_v_pt3); + Py_CLEAR(p->__pyx_v_pt4); + Py_CLEAR(p->__pyx_v_ts); + Py_CLEAR(p->__pyx_t_0); + #if CYTHON_USE_FREELISTS + if (likely((int)(__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC < 8) & __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(Py_TYPE(o), __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC)))) + { + __pyx_mstate_global->__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC[__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC++] = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *)o); + } else + #endif + { + PyTypeObject *tp = Py_TYPE(o); + #if CYTHON_USE_TYPE_SLOTS + (*tp->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(tp, Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(tp); + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC *)o; + { + e = __Pyx_call_type_traverse(o, 1, v, a); + if (e) return e; + } + if (p->__pyx_v_i) { + e = (*v)(p->__pyx_v_i, a); if (e) return e; + } + if (p->__pyx_v_pt1) { + e = (*v)(p->__pyx_v_pt1, a); if (e) return e; + } + if (p->__pyx_v_pt2) { + e = (*v)(p->__pyx_v_pt2, a); if (e) return e; + } + if (p->__pyx_v_pt3) { + e = (*v)(p->__pyx_v_pt3, a); if (e) return e; + } + if (p->__pyx_v_pt4) { + e = (*v)(p->__pyx_v_pt4, a); if (e) return e; + } + if (p->__pyx_v_ts) { + e = (*v)(p->__pyx_v_ts, a); if (e) return e; + } + if (p->__pyx_t_0) { + e = (*v)(p->__pyx_t_0, a); if (e) return e; + } + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC_spec = { + "fontTools.misc.bezierTools.__pyx_scope_struct_3__splitCubicAtTC", + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_scope_struct_3__splitCubicAtTC", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #if !CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800 + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if PY_VERSION_HEX >= 0x030d00A4 + 0, /*tp_versions_used*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_USE_FREELISTS + if (likely((int)(__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr > 0) & __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(t, __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr)))) + { + o = (PyObject*)__pyx_mstate_global->__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr[--__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr]; + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(Py_TYPE(o)); + #endif + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr)); + #if CYTHON_COMPILING_IN_LIMITED_API + (void) PyObject_Init(o, t); + #else + (void) PyObject_INIT(o, t); + #endif + PyObject_GC_Track(o); + } else + #endif + { + o = __Pyx_AllocateExtensionType(t, 1); + if (unlikely(!o)) return 0; + } + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr(PyObject *o) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely(__Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_genexpr_arg_0); + Py_CLEAR(p->__pyx_v_i); + #if CYTHON_USE_FREELISTS + if (likely((int)(__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr < 8) & __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(Py_TYPE(o), __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr)))) + { + __pyx_mstate_global->__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr[__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr++] = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *)o); + } else + #endif + { + PyTypeObject *tp = Py_TYPE(o); + #if CYTHON_USE_TYPE_SLOTS + (*tp->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(tp, Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(tp); + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr *)o; + { + e = __Pyx_call_type_traverse(o, 1, v, a); + if (e) return e; + } + if (p->__pyx_genexpr_arg_0) { + e = (*v)(p->__pyx_genexpr_arg_0, a); if (e) return e; + } + if (p->__pyx_v_i) { + e = (*v)(p->__pyx_v_i, a); if (e) return e; + } + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr_spec = { + "fontTools.misc.bezierTools.__pyx_scope_struct_4_genexpr", + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_scope_struct_4_genexpr", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #if !CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800 + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if PY_VERSION_HEX >= 0x030d00A4 + 0, /*tp_versions_used*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_USE_FREELISTS + if (likely((int)(__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t > 0) & __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(t, __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t)))) + { + o = (PyObject*)__pyx_mstate_global->__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t[--__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t]; + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(Py_TYPE(o)); + #endif + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t)); + #if CYTHON_COMPILING_IN_LIMITED_API + (void) PyObject_Init(o, t); + #else + (void) PyObject_INIT(o, t); + #endif + PyObject_GC_Track(o); + } else + #endif + { + o = __Pyx_AllocateExtensionType(t, 1); + if (unlikely(!o)) return 0; + } + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t(PyObject *o) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely(__Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_v_precision); + #if CYTHON_USE_FREELISTS + if (likely((int)(__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t < 8) & __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(Py_TYPE(o), __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t)))) + { + __pyx_mstate_global->__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t[__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t++] = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *)o); + } else + #endif + { + PyTypeObject *tp = Py_TYPE(o); + #if CYTHON_USE_TYPE_SLOTS + (*tp->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(tp, Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(tp); + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *)o; + { + e = __Pyx_call_type_traverse(o, 1, v, a); + if (e) return e; + } + if (p->__pyx_v_precision) { + e = (*v)(p->__pyx_v_precision, a); if (e) return e; + } + return 0; +} + +static int __pyx_tp_clear_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t(PyObject *o) { + PyObject* tmp; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t *)o; + tmp = ((PyObject*)p->__pyx_v_precision); + p->__pyx_v_precision = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t}, + {Py_tp_clear, (void *)__pyx_tp_clear_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t_spec = { + "fontTools.misc.bezierTools.__pyx_scope_struct_5__curve_curve_intersections_t", + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_scope_struct_5__curve_curve_intersections_t", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t, /*tp_traverse*/ + __pyx_tp_clear_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #if !CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800 + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if PY_VERSION_HEX >= 0x030d00A4 + 0, /*tp_versions_used*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_USE_FREELISTS + if (likely((int)(__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr > 0) & __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(t, __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr)))) + { + o = (PyObject*)__pyx_mstate_global->__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr[--__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr]; + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(Py_TYPE(o)); + #endif + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr)); + #if CYTHON_COMPILING_IN_LIMITED_API + (void) PyObject_Init(o, t); + #else + (void) PyObject_INIT(o, t); + #endif + PyObject_GC_Track(o); + } else + #endif + { + o = __Pyx_AllocateExtensionType(t, 1); + if (unlikely(!o)) return 0; + } + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr(PyObject *o) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely(__Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_genexpr_arg_0); + Py_CLEAR(p->__pyx_v_p); + #if CYTHON_USE_FREELISTS + if (likely((int)(__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr < 8) & __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(Py_TYPE(o), __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr)))) + { + __pyx_mstate_global->__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr[__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr++] = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *)o); + } else + #endif + { + PyTypeObject *tp = Py_TYPE(o); + #if CYTHON_USE_TYPE_SLOTS + (*tp->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(tp, Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(tp); + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr *)o; + { + e = __Pyx_call_type_traverse(o, 1, v, a); + if (e) return e; + } + if (p->__pyx_genexpr_arg_0) { + e = (*v)(p->__pyx_genexpr_arg_0, a); if (e) return e; + } + if (p->__pyx_v_p) { + e = (*v)(p->__pyx_v_p, a); if (e) return e; + } + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr_spec = { + "fontTools.misc.bezierTools.__pyx_scope_struct_6_genexpr", + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_scope_struct_6_genexpr", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #if !CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800 + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if PY_VERSION_HEX >= 0x030d00A4 + 0, /*tp_versions_used*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static PyObject *__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + #if CYTHON_USE_FREELISTS + if (likely((int)(__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr > 0) & __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(t, __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr)))) + { + o = (PyObject*)__pyx_mstate_global->__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr[--__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr]; + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(Py_TYPE(o)); + #endif + memset(o, 0, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr)); + #if CYTHON_COMPILING_IN_LIMITED_API + (void) PyObject_Init(o, t); + #else + (void) PyObject_INIT(o, t); + #endif + PyObject_GC_Track(o); + } else + #endif + { + o = __Pyx_AllocateExtensionType(t, 1); + if (unlikely(!o)) return 0; + } + return o; +} + +static void __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr(PyObject *o) { + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely(__Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_genexpr_arg_0); + Py_CLEAR(p->__pyx_v_x); + #if CYTHON_USE_FREELISTS + if (likely((int)(__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr < 8) & __PYX_CHECK_FINAL_TYPE_FOR_FREELISTS(Py_TYPE(o), __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr, sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr)))) + { + __pyx_mstate_global->__pyx_freelist_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr[__pyx_mstate_global->__pyx_freecount_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr++] = ((struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *)o); + } else + #endif + { + PyTypeObject *tp = Py_TYPE(o); + #if CYTHON_USE_TYPE_SLOTS + (*tp->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(tp, Py_tp_free); + if (tp_free) tp_free(o); + } + #endif + #if CYTHON_USE_TYPE_SPECS + Py_DECREF(tp); + #endif + } +} + +static int __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *p = (struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr *)o; + { + e = __Pyx_call_type_traverse(o, 1, v, a); + if (e) return e; + } + if (p->__pyx_genexpr_arg_0) { + e = (*v)(p->__pyx_genexpr_arg_0, a); if (e) return e; + } + if (p->__pyx_v_x) { + e = (*v)(p->__pyx_v_x, a); if (e) return e; + } + return 0; +} +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr}, + {Py_tp_traverse, (void *)__pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr}, + {Py_tp_new, (void *)__pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr}, + {0, 0}, +}; +static PyType_Spec __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr_spec = { + "fontTools.misc.bezierTools.__pyx_scope_struct_7_genexpr", + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, + __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr_slots, +}; +#else + +static PyTypeObject __pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr = { + PyVarObject_HEAD_INIT(0, 0) + "fontTools.misc.bezierTools.""__pyx_scope_struct_7_genexpr", /*tp_name*/ + sizeof(struct __pyx_obj_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #if !CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800 + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if PY_VERSION_HEX >= 0x030d00A4 + 0, /*tp_versions_used*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; +/* #### Code section: initfunc_declarations ### */ +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_CreateCodeObjects(__pyx_mstatetype *__pyx_mstate); /*proto*/ +/* #### Code section: init_module ### */ + +static int __Pyx_modinit_global_init_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + #if CYTHON_USE_TYPE_SPECS + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_defaults = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_defaults_spec, NULL); if (unlikely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_defaults)) __PYX_ERR(0, 815, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_defaults_spec, __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_defaults) < (0)) __PYX_ERR(0, 815, __pyx_L1_error) + #else + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_defaults = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_defaults; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_defaults) < (0)) __PYX_ERR(0, 815, __pyx_L1_error) + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount((PyObject*)__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_defaults); + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_defaults->tp_dictoffset && __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_defaults->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_defaults->tp_getattro = PyObject_GenericGetAttr; + } + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr_spec, NULL); if (unlikely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr)) __PYX_ERR(0, 546, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr_spec, __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr) < (0)) __PYX_ERR(0, 546, __pyx_L1_error) + #else + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr) < (0)) __PYX_ERR(0, 546, __pyx_L1_error) + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount((PyObject*)__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr); + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr->tp_dictoffset && __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct__genexpr->tp_getattro = PyObject_GenericGetAttr; + } + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr_spec, NULL); if (unlikely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr)) __PYX_ERR(0, 583, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr_spec, __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr) < (0)) __PYX_ERR(0, 583, __pyx_L1_error) + #else + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr) < (0)) __PYX_ERR(0, 583, __pyx_L1_error) + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount((PyObject*)__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr); + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr->tp_dictoffset && __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_1_genexpr->tp_getattro = PyObject_GenericGetAttr; + } + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC_spec, NULL); if (unlikely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC)) __PYX_ERR(0, 644, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC_spec, __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC) < (0)) __PYX_ERR(0, 644, __pyx_L1_error) + #else + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC) < (0)) __PYX_ERR(0, 644, __pyx_L1_error) + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount((PyObject*)__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC); + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC->tp_dictoffset && __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_2_splitCubicAtTC->tp_getattro = PyObject_GenericGetAttr; + } + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC_spec, NULL); if (unlikely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC)) __PYX_ERR(0, 770, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC_spec, __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC) < (0)) __PYX_ERR(0, 770, __pyx_L1_error) + #else + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC) < (0)) __PYX_ERR(0, 770, __pyx_L1_error) + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount((PyObject*)__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC); + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC->tp_dictoffset && __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_3__splitCubicAtTC->tp_getattro = PyObject_GenericGetAttr; + } + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr_spec, NULL); if (unlikely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr)) __PYX_ERR(0, 1252, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr_spec, __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr) < (0)) __PYX_ERR(0, 1252, __pyx_L1_error) + #else + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr) < (0)) __PYX_ERR(0, 1252, __pyx_L1_error) + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount((PyObject*)__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr); + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr->tp_dictoffset && __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_4_genexpr->tp_getattro = PyObject_GenericGetAttr; + } + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t_spec, NULL); if (unlikely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t)) __PYX_ERR(0, 1313, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t_spec, __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t) < (0)) __PYX_ERR(0, 1313, __pyx_L1_error) + #else + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t) < (0)) __PYX_ERR(0, 1313, __pyx_L1_error) + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount((PyObject*)__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t); + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t->tp_dictoffset && __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_5__curve_curve_intersections_t->tp_getattro = PyObject_GenericGetAttr; + } + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr_spec, NULL); if (unlikely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr)) __PYX_ERR(0, 1382, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr_spec, __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr) < (0)) __PYX_ERR(0, 1382, __pyx_L1_error) + #else + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr) < (0)) __PYX_ERR(0, 1382, __pyx_L1_error) + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount((PyObject*)__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr); + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr->tp_dictoffset && __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_6_genexpr->tp_getattro = PyObject_GenericGetAttr; + } + #endif + #if CYTHON_USE_TYPE_SPECS + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr_spec, NULL); if (unlikely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr)) __PYX_ERR(0, 1485, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr_spec, __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr) < (0)) __PYX_ERR(0, 1485, __pyx_L1_error) + #else + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr = &__pyx_type_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr) < (0)) __PYX_ERR(0, 1485, __pyx_L1_error) + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount((PyObject*)__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr); + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr->tp_dictoffset && __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_mstate->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_scope_struct_7_genexpr->tp_getattro = PyObject_GenericGetAttr; + } + #endif + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_type_import_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_import_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec_bezierTools(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec_bezierTools}, + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + {Py_mod_gil, Py_MOD_GIL_USED}, + #endif + #if PY_VERSION_HEX >= 0x030C0000 && CYTHON_USE_MODULE_STATE + {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED}, + #endif + {0, NULL} +}; +#endif + +#ifdef __cplusplus +namespace { + struct PyModuleDef __pyx_moduledef = + #else + static struct PyModuleDef __pyx_moduledef = + #endif + { + PyModuleDef_HEAD_INIT, + "bezierTools", + __pyx_k_fontTools_misc_bezierTools_py_to, /* m_doc */ + #if CYTHON_USE_MODULE_STATE + sizeof(__pyx_mstatetype), /* m_size */ + #else + (CYTHON_PEP489_MULTI_PHASE_INIT) ? 0 : -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + #if CYTHON_USE_MODULE_STATE + __pyx_m_traverse, /* m_traverse */ + __pyx_m_clear, /* m_clear */ + NULL /* m_free */ + #else + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ + #endif + }; + #ifdef __cplusplus +} /* anonymous namespace */ +#endif + +/* PyModInitFuncType */ +#ifndef CYTHON_NO_PYINIT_EXPORT + #define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#else + #ifdef __cplusplus + #define __Pyx_PyMODINIT_FUNC extern "C" PyObject * + #else + #define __Pyx_PyMODINIT_FUNC PyObject * + #endif +#endif + +__Pyx_PyMODINIT_FUNC PyInit_bezierTools(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit_bezierTools(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +/* ModuleCreationPEP489 */ +#if CYTHON_COMPILING_IN_LIMITED_API && (__PYX_LIMITED_VERSION_HEX < 0x03090000\ + || ((defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS)) && __PYX_LIMITED_VERSION_HEX < 0x030A0000)) +static PY_INT64_T __Pyx_GetCurrentInterpreterId(void) { + { + PyObject *module = PyImport_ImportModule("_interpreters"); // 3.13+ I think + if (!module) { + PyErr_Clear(); // just try the 3.8-3.12 version + module = PyImport_ImportModule("_xxsubinterpreters"); + if (!module) goto bad; + } + PyObject *current = PyObject_CallMethod(module, "get_current", NULL); + Py_DECREF(module); + if (!current) goto bad; + if (PyTuple_Check(current)) { + PyObject *new_current = PySequence_GetItem(current, 0); + Py_DECREF(current); + current = new_current; + if (!new_current) goto bad; + } + long long as_c_int = PyLong_AsLongLong(current); + Py_DECREF(current); + return as_c_int; + } + bad: + PySys_WriteStderr("__Pyx_GetCurrentInterpreterId failed. Try setting the C define CYTHON_PEP489_MULTI_PHASE_INIT=0\n"); + return -1; +} +#endif +#if !CYTHON_USE_MODULE_STATE +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + static PY_INT64_T main_interpreter_id = -1; +#if CYTHON_COMPILING_IN_GRAAL && defined(GRAALPY_VERSION_NUM) && GRAALPY_VERSION_NUM > 0x19000000 + PY_INT64_T current_id = GraalPyInterpreterState_GetIDFromThreadState(PyThreadState_Get()); +#elif CYTHON_COMPILING_IN_GRAAL + PY_INT64_T current_id = PyInterpreterState_GetIDFromThreadState(PyThreadState_Get()); +#elif CYTHON_COMPILING_IN_LIMITED_API && (__PYX_LIMITED_VERSION_HEX < 0x03090000\ + || ((defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS)) && __PYX_LIMITED_VERSION_HEX < 0x030A0000)) + PY_INT64_T current_id = __Pyx_GetCurrentInterpreterId(); +#elif CYTHON_COMPILING_IN_LIMITED_API + PY_INT64_T current_id = PyInterpreterState_GetID(PyInterpreterState_Get()); +#else + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); +#endif + if (unlikely(current_id == -1)) { + return -1; + } + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return 0; + } else if (unlikely(main_interpreter_id != current_id)) { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +#endif +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) +{ + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + CYTHON_UNUSED_VAR(def); + #if !CYTHON_USE_MODULE_STATE + if (__Pyx_check_single_interpreter()) + return NULL; + #endif + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec_bezierTools(PyObject *__pyx_pyinit_module) +#endif +{ + int stringtab_initialized = 0; + #if CYTHON_USE_MODULE_STATE + int pystate_addmodule_run = 0; + #endif + __pyx_mstatetype *__pyx_mstate = NULL; + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + Py_ssize_t __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + size_t __pyx_t_9; + int __pyx_t_10; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + PyObject *__pyx_t_13 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module 'bezierTools' has already been imported. Re-initialisation is not supported."); + return -1; + } + #else + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_t_1 = __pyx_pyinit_module; + Py_INCREF(__pyx_t_1); + #else + __pyx_t_1 = PyModule_Create(&__pyx_moduledef); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #if CYTHON_USE_MODULE_STATE + { + int add_module_result = __Pyx_State_AddModule(__pyx_t_1, &__pyx_moduledef); + __pyx_t_1 = 0; /* transfer ownership from __pyx_t_1 to "bezierTools" pseudovariable */ + if (unlikely((add_module_result < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + pystate_addmodule_run = 1; + } + #else + __pyx_m = __pyx_t_1; + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + PyUnstable_Module_SetGIL(__pyx_m, Py_MOD_GIL_USED); + #endif + __pyx_mstate = __pyx_mstate_global; + CYTHON_UNUSED_VAR(__pyx_t_1); + __pyx_mstate->__pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_mstate->__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_mstate->__pyx_d); + __pyx_mstate->__pyx_b = __Pyx_PyImport_AddModuleRef(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_mstate->__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_cython_runtime = __Pyx_PyImport_AddModuleRef("cython_runtime"); if (unlikely(!__pyx_mstate->__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_mstate->__pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /* ImportRefnannyAPI */ + #if CYTHON_REFNANNY + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); + if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); + } + #endif + +__Pyx_RefNannySetupContext("PyInit_bezierTools", 0); + __Pyx_init_runtime_version(); + if (__Pyx_check_binary_version(__PYX_LIMITED_VERSION_HEX, __Pyx_get_runtime_version(), CYTHON_COMPILING_IN_LIMITED_API) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_mstate->__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_mstate->__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_mstate->__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Library function declarations ---*/ + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitConstants(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + stringtab_initialized = 1; + if (__Pyx_InitGlobals() < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (__pyx_module_is_main_fontTools__misc__bezierTools) { + if (PyObject_SetAttr(__pyx_m, __pyx_mstate_global->__pyx_n_u_name, __pyx_mstate_global->__pyx_n_u_main) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + } + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "fontTools.misc.bezierTools")) { + if (unlikely((PyDict_SetItemString(modules, "fontTools.misc.bezierTools", __pyx_m) < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (__Pyx_CreateCodeObjects(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(__pyx_mstate); + (void)__Pyx_modinit_variable_export_code(__pyx_mstate); + (void)__Pyx_modinit_function_export_code(__pyx_mstate); + if (unlikely((__Pyx_modinit_type_init_code(__pyx_mstate) < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + (void)__Pyx_modinit_type_import_code(__pyx_mstate); + (void)__Pyx_modinit_variable_import_code(__pyx_mstate); + (void)__Pyx_modinit_function_import_code(__pyx_mstate); + /*--- Execution code ---*/ + + /* "fontTools/misc/bezierTools.py":5 + * """ + * + * from fontTools.misc.arrayTools import calcBounds, sectRect, rectArea # <<<<<<<<<<<<<< + * from fontTools.misc.transform import Identity + * import math +*/ + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_calcBounds,__pyx_mstate_global->__pyx_n_u_sectRect,__pyx_mstate_global->__pyx_n_u_rectArea}; + __pyx_t_1 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_fontTools_misc_arrayTools, __pyx_imported_names, 3, NULL, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 5, __pyx_L1_error) + } + __pyx_t_2 = __pyx_t_1; + __Pyx_GOTREF(__pyx_t_2); + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_calcBounds,__pyx_mstate_global->__pyx_n_u_sectRect,__pyx_mstate_global->__pyx_n_u_rectArea}; + for (__pyx_t_3=0; __pyx_t_3 < 3; __pyx_t_3++) { + __pyx_t_4 = __Pyx_ImportFrom(__pyx_t_2, __pyx_imported_names[__pyx_t_3]); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_imported_names[__pyx_t_3], __pyx_t_4) < (0)) __PYX_ERR(0, 5, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":6 + * + * from fontTools.misc.arrayTools import calcBounds, sectRect, rectArea + * from fontTools.misc.transform import Identity # <<<<<<<<<<<<<< + * import math + * from collections import namedtuple +*/ + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_Identity}; + __pyx_t_1 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_fontTools_misc_transform, __pyx_imported_names, 1, NULL, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 6, __pyx_L1_error) + } + __pyx_t_2 = __pyx_t_1; + __Pyx_GOTREF(__pyx_t_2); + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_Identity}; + __pyx_t_3 = 0; { + __pyx_t_4 = __Pyx_ImportFrom(__pyx_t_2, __pyx_imported_names[__pyx_t_3]); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_imported_names[__pyx_t_3], __pyx_t_4) < (0)) __PYX_ERR(0, 6, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":7 + * from fontTools.misc.arrayTools import calcBounds, sectRect, rectArea + * from fontTools.misc.transform import Identity + * import math # <<<<<<<<<<<<<< + * from collections import namedtuple + * +*/ + __pyx_t_1 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_math, 0, 0, NULL, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error) + __pyx_t_2 = __pyx_t_1; + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_math, __pyx_t_2) < (0)) __PYX_ERR(0, 7, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":8 + * from fontTools.misc.transform import Identity + * import math + * from collections import namedtuple # <<<<<<<<<<<<<< + * + * try: +*/ + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_namedtuple}; + __pyx_t_1 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_collections, __pyx_imported_names, 1, NULL, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 8, __pyx_L1_error) + } + __pyx_t_2 = __pyx_t_1; + __Pyx_GOTREF(__pyx_t_2); + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_namedtuple}; + __pyx_t_3 = 0; { + __pyx_t_4 = __Pyx_ImportFrom(__pyx_t_2, __pyx_imported_names[__pyx_t_3]); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_imported_names[__pyx_t_3], __pyx_t_4) < (0)) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":10 + * from collections import namedtuple + * + * try: # <<<<<<<<<<<<<< + * import cython + * except (AttributeError, ImportError): +*/ + { + (void)__pyx_t_1; (void)__pyx_t_5; (void)__pyx_t_6; /* mark used */ + /*try:*/ { + + /* "fontTools/misc/bezierTools.py":11 + * + * try: + * import cython # <<<<<<<<<<<<<< + * except (AttributeError, ImportError): + * # if cython not installed, use mock module with no-op decorators and types +*/ + } + } + + /* "fontTools/misc/bezierTools.py":15 + * # if cython not installed, use mock module with no-op decorators and types + * from fontTools.misc import cython + * COMPILED = cython.compiled # <<<<<<<<<<<<<< + * + * +*/ + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_COMPILED, Py_True) < (0)) __PYX_ERR(0, 15, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":18 + * + * + * EPSILON = 1e-9 # <<<<<<<<<<<<<< + * + * +*/ + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_EPSILON, __pyx_mstate_global->__pyx_float_1eneg_9) < (0)) __PYX_ERR(0, 18, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":21 + * + * + * Intersection = namedtuple("Intersection", ["pt", "t1", "t2"]) # <<<<<<<<<<<<<< + * + * +*/ + __pyx_t_4 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_namedtuple); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_PyList_Pack(3, __pyx_mstate_global->__pyx_n_u_pt, __pyx_mstate_global->__pyx_n_u_t1, __pyx_mstate_global->__pyx_n_u_t2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_4, __pyx_mstate_global->__pyx_n_u_Intersection, __pyx_t_8}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_7, __pyx_callargs+__pyx_t_9, (3-__pyx_t_9) | (__pyx_t_9*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_Intersection, __pyx_t_2) < (0)) __PYX_ERR(0, 21, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":24 + * + * + * __all__ = [ # <<<<<<<<<<<<<< + * "approximateCubicArcLength", + * "approximateCubicArcLengthC", +*/ + __pyx_t_2 = __Pyx_PyList_Pack(28, __pyx_mstate_global->__pyx_n_u_approximateCubicArcLength, __pyx_mstate_global->__pyx_n_u_approximateCubicArcLengthC, __pyx_mstate_global->__pyx_n_u_approximateQuadraticArcLength, __pyx_mstate_global->__pyx_n_u_approximateQuadraticArcLengthC, __pyx_mstate_global->__pyx_n_u_calcCubicArcLength, __pyx_mstate_global->__pyx_n_u_calcCubicArcLengthC, __pyx_mstate_global->__pyx_n_u_calcQuadraticArcLength, __pyx_mstate_global->__pyx_n_u_calcQuadraticArcLengthC, __pyx_mstate_global->__pyx_n_u_calcCubicBounds, __pyx_mstate_global->__pyx_n_u_calcQuadraticBounds, __pyx_mstate_global->__pyx_n_u_splitLine, __pyx_mstate_global->__pyx_n_u_splitQuadratic, __pyx_mstate_global->__pyx_n_u_splitCubic, __pyx_mstate_global->__pyx_n_u_splitQuadraticAtT_2, __pyx_mstate_global->__pyx_n_u_splitCubicAtT_2, __pyx_mstate_global->__pyx_n_u_splitCubicAtTC, __pyx_mstate_global->__pyx_n_u_splitCubicIntoTwoAtTC, __pyx_mstate_global->__pyx_n_u_solveQuadratic, __pyx_mstate_global->__pyx_n_u_solveCubic, __pyx_mstate_global->__pyx_n_u_quadraticPointAtT, __pyx_mstate_global->__pyx_n_u_cubicPointAtT, __pyx_mstate_global->__pyx_n_u_cubicPointAtTC, __pyx_mstate_global->__pyx_n_u_linePointAtT, __pyx_mstate_global->__pyx_n_u_segmentPointAtT, __pyx_mstate_global->__pyx_n_u_lineLineIntersections, __pyx_mstate_global->__pyx_n_u_curveLineIntersections, __pyx_mstate_global->__pyx_n_u_curveCurveIntersections, __pyx_mstate_global->__pyx_n_u_segmentSegmentIntersections); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_all, __pyx_t_2) < (0)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":56 + * + * + * def calcCubicArcLength(pt1, pt2, pt3, pt4, tolerance=0.005): # <<<<<<<<<<<<<< + * """Calculates the arc length for a cubic Bezier segment. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_1calcCubicArcLength, 0, __pyx_mstate_global->__pyx_n_u_calcCubicArcLength, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[9])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_mstate_global->__pyx_tuple[2]); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_calcCubicArcLength, __pyx_t_2) < (0)) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":75 + * + * + * def _split_cubic_into_two(p0, p1, p2, p3): # <<<<<<<<<<<<<< + * mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + * deriv3 = (p3 + p2 - p1 - p0) * 0.125 +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_3_split_cubic_into_two, 0, __pyx_mstate_global->__pyx_n_u_split_cubic_into_two, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[10])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 75, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_split_cubic_into_two, __pyx_t_2) < (0)) __PYX_ERR(0, 75, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":84 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * p0=cython.complex, +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_5_calcCubicArcLengthCRecurse, 0, __pyx_mstate_global->__pyx_n_u_calcCubicArcLengthCRecurse, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[11])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 84, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_calcCubicArcLengthCRecurse, __pyx_t_2) < (0)) __PYX_ERR(0, 84, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":115 + * mult=cython.double, + * ) + * def calcCubicArcLengthC(pt1, pt2, pt3, pt4, tolerance=0.005): # <<<<<<<<<<<<<< + * """Calculates the arc length for a cubic Bezier segment. + * +*/ + __pyx_t_2 = PyFloat_FromDouble(((double)0.005)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/misc/bezierTools.py":104 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, +*/ + __pyx_t_7 = PyTuple_Pack(1, __pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_7calcCubicArcLengthC, 0, __pyx_mstate_global->__pyx_n_u_calcCubicArcLengthC, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[12])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_t_7); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_calcCubicArcLengthC, __pyx_t_2) < (0)) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":129 + * + * + * epsilonDigits = 6 # <<<<<<<<<<<<<< + * epsilon = 1e-10 + * +*/ + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_epsilonDigits, __pyx_mstate_global->__pyx_int_6) < (0)) __PYX_ERR(0, 129, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":130 + * + * epsilonDigits = 6 + * epsilon = 1e-10 # <<<<<<<<<<<<<< + * + * +*/ + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_epsilon, __pyx_mstate_global->__pyx_float_1eneg_10) < (0)) __PYX_ERR(0, 130, __pyx_L1_error) + + /* "fontTools/misc/bezierTools.py":151 + * + * + * def calcQuadraticArcLength(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the arc length for a quadratic Bezier segment. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_9calcQuadraticArcLength, 0, __pyx_mstate_global->__pyx_n_u_calcQuadraticArcLength, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[13])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 151, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_calcQuadraticArcLength, __pyx_t_2) < (0)) __PYX_ERR(0, 151, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":186 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_11calcQuadraticArcLengthC, 0, __pyx_mstate_global->__pyx_n_u_calcQuadraticArcLengthC, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[14])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 186, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_calcQuadraticArcLengthC, __pyx_t_2) < (0)) __PYX_ERR(0, 186, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":237 + * + * + * def approximateQuadraticArcLength(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the arc length for a quadratic Bezier segment. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_13approximateQuadraticArcLength, 0, __pyx_mstate_global->__pyx_n_u_approximateQuadraticArcLength, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[15])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 237, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_approximateQuadraticArcLength, __pyx_t_2) < (0)) __PYX_ERR(0, 237, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":254 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_15approximateQuadraticArcLengthC, 0, __pyx_mstate_global->__pyx_n_u_approximateQuadraticArcLengthC, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[16])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 254, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_approximateQuadraticArcLengthC, __pyx_t_2) < (0)) __PYX_ERR(0, 254, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":298 + * + * + * def calcQuadraticBounds(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * """Calculates the bounding rectangle for a quadratic Bezier segment. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_17calcQuadraticBounds, 0, __pyx_mstate_global->__pyx_n_u_calcQuadraticBounds, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[17])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 298, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_calcQuadraticBounds, __pyx_t_2) < (0)) __PYX_ERR(0, 298, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":332 + * + * + * def approximateCubicArcLength(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * """Approximates the arc length for a cubic Bezier segment. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_19approximateCubicArcLength, 0, __pyx_mstate_global->__pyx_n_u_approximateCubicArcLength, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[18])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 332, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_approximateCubicArcLength, __pyx_t_2) < (0)) __PYX_ERR(0, 332, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":362 + * + * + * @cython.returns(cython.double) # <<<<<<<<<<<<<< + * @cython.locals( + * pt1=cython.complex, +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_21approximateCubicArcLengthC, 0, __pyx_mstate_global->__pyx_n_u_approximateCubicArcLengthC, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[19])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 362, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_approximateCubicArcLengthC, __pyx_t_2) < (0)) __PYX_ERR(0, 362, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":412 + * + * + * def calcCubicBounds(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * """Calculates the bounding rectangle for a quadratic Bezier segment. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_23calcCubicBounds, 0, __pyx_mstate_global->__pyx_n_u_calcCubicBounds, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[20])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 412, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_calcCubicBounds, __pyx_t_2) < (0)) __PYX_ERR(0, 412, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":450 + * + * + * def splitLine(pt1, pt2, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a line at a given coordinate. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_25splitLine, 0, __pyx_mstate_global->__pyx_n_u_splitLine, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[21])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_splitLine, __pyx_t_2) < (0)) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":507 + * + * + * def splitQuadratic(pt1, pt2, pt3, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a quadratic Bezier curve at a given coordinate. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_27splitQuadratic, 0, __pyx_mstate_global->__pyx_n_u_splitQuadratic, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[22])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 507, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_splitQuadratic, __pyx_t_2) < (0)) __PYX_ERR(0, 507, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":552 + * + * + * def splitCubic(pt1, pt2, pt3, pt4, where, isHorizontal): # <<<<<<<<<<<<<< + * """Split a cubic Bezier curve at a given coordinate. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_29splitCubic, 0, __pyx_mstate_global->__pyx_n_u_splitCubic, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[23])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 552, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_splitCubic, __pyx_t_2) < (0)) __PYX_ERR(0, 552, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":589 + * + * + * def splitQuadraticAtT(pt1, pt2, pt3, *ts): # <<<<<<<<<<<<<< + * """Split a quadratic Bezier curve at one or more values of t. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_31splitQuadraticAtT, 0, __pyx_mstate_global->__pyx_n_u_splitQuadraticAtT_2, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[24])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 589, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_splitQuadraticAtT_2, __pyx_t_2) < (0)) __PYX_ERR(0, 589, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":613 + * + * + * def splitCubicAtT(pt1, pt2, pt3, pt4, *ts): # <<<<<<<<<<<<<< + * """Split a cubic Bezier curve at one or more values of t. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_33splitCubicAtT, 0, __pyx_mstate_global->__pyx_n_u_splitCubicAtT_2, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[25])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 613, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_splitCubicAtT_2, __pyx_t_2) < (0)) __PYX_ERR(0, 613, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":644 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * pt1=cython.complex, + * pt2=cython.complex, +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_35splitCubicAtTC, 0, __pyx_mstate_global->__pyx_n_u_splitCubicAtTC, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[2])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 644, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_splitCubicAtTC, __pyx_t_2) < (0)) __PYX_ERR(0, 644, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":668 + * + * + * @cython.returns(cython.complex) # <<<<<<<<<<<<<< + * @cython.locals( + * t=cython.double, +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_38splitCubicIntoTwoAtTC, 0, __pyx_mstate_global->__pyx_n_u_splitCubicIntoTwoAtTC, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[26])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 668, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_splitCubicIntoTwoAtTC, __pyx_t_2) < (0)) __PYX_ERR(0, 668, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":708 + * + * + * def _splitQuadraticAtT(a, b, c, *ts): # <<<<<<<<<<<<<< + * ts = list(ts) + * segments = [] +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_40_splitQuadraticAtT, 0, __pyx_mstate_global->__pyx_n_u_splitQuadraticAtT, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[27])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 708, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_splitQuadraticAtT, __pyx_t_2) < (0)) __PYX_ERR(0, 708, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":735 + * + * + * def _splitCubicAtT(a, b, c, d, *ts): # <<<<<<<<<<<<<< + * ts = list(ts) + * ts.insert(0, 0.0) +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_42_splitCubicAtT, 0, __pyx_mstate_global->__pyx_n_u_splitCubicAtT, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[28])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 735, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_splitCubicAtT, __pyx_t_2) < (0)) __PYX_ERR(0, 735, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":770 + * + * + * @cython.locals( # <<<<<<<<<<<<<< + * a=cython.complex, + * b=cython.complex, +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_44_splitCubicAtTC, 0, __pyx_mstate_global->__pyx_n_u_splitCubicAtTC_2, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[3])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 770, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_splitCubicAtTC_2, __pyx_t_2) < (0)) __PYX_ERR(0, 770, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":812 + * # + * + * from math import sqrt, acos, cos, pi # <<<<<<<<<<<<<< + * + * +*/ + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_sqrt,__pyx_mstate_global->__pyx_n_u_acos,__pyx_mstate_global->__pyx_n_u_cos,__pyx_mstate_global->__pyx_n_u_pi}; + __pyx_t_6 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_math, __pyx_imported_names, 4, NULL, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 812, __pyx_L1_error) + } + __pyx_t_2 = __pyx_t_6; + __Pyx_GOTREF(__pyx_t_2); + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_sqrt,__pyx_mstate_global->__pyx_n_u_acos,__pyx_mstate_global->__pyx_n_u_cos,__pyx_mstate_global->__pyx_n_u_pi}; + for (__pyx_t_3=0; __pyx_t_3 < 4; __pyx_t_3++) { + __pyx_t_7 = __Pyx_ImportFrom(__pyx_t_2, __pyx_imported_names[__pyx_t_3]); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 812, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_imported_names[__pyx_t_3], __pyx_t_7) < (0)) __PYX_ERR(0, 812, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + } + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":815 + * + * + * def solveQuadratic(a, b, c, sqrt=sqrt): # <<<<<<<<<<<<<< + * """Solve a quadratic equation. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_47solveQuadratic, 0, __pyx_mstate_global->__pyx_n_u_solveQuadratic, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[29])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 815, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (!__Pyx_CyFunction_InitDefaults(__pyx_t_2, __pyx_mstate_global->__pyx_ptype_9fontTools_4misc_11bezierTools___pyx_defaults)) __PYX_ERR(0, 815, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_sqrt); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 815, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_CyFunction_Defaults(struct __pyx_defaults, __pyx_t_2)->arg0 = __pyx_t_7; + __Pyx_GIVEREF(__pyx_t_7); + __pyx_t_7 = 0; + __Pyx_CyFunction_SetDefaultsGetter(__pyx_t_2, __pyx_pf_9fontTools_4misc_11bezierTools_96__defaults__); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_solveQuadratic, __pyx_t_2) < (0)) __PYX_ERR(0, 815, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":848 + * + * + * def solveCubic(a, b, c, d): # <<<<<<<<<<<<<< + * """Solve a cubic equation. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_49solveCubic, 0, __pyx_mstate_global->__pyx_n_u_solveCubic, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[30])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 848, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_solveCubic, __pyx_t_2) < (0)) __PYX_ERR(0, 848, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":945 + * + * + * def calcQuadraticParameters(pt1, pt2, pt3): # <<<<<<<<<<<<<< + * x2, y2 = pt2 + * x3, y3 = pt3 +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_51calcQuadraticParameters, 0, __pyx_mstate_global->__pyx_n_u_calcQuadraticParameters, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[31])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 945, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_calcQuadraticParameters, __pyx_t_2) < (0)) __PYX_ERR(0, 945, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":956 + * + * + * def calcCubicParameters(pt1, pt2, pt3, pt4): # <<<<<<<<<<<<<< + * x2, y2 = pt2 + * x3, y3 = pt3 +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_53calcCubicParameters, 0, __pyx_mstate_global->__pyx_n_u_calcCubicParameters, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[32])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 956, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_calcCubicParameters, __pyx_t_2) < (0)) __PYX_ERR(0, 956, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":988 + * + * + * def calcQuadraticPoints(a, b, c): # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_55calcQuadraticPoints, 0, __pyx_mstate_global->__pyx_n_u_calcQuadraticPoints, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[33])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 988, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_calcQuadraticPoints, __pyx_t_2) < (0)) __PYX_ERR(0, 988, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1001 + * + * + * def calcCubicPoints(a, b, c, d): # <<<<<<<<<<<<<< + * ax, ay = a + * bx, by = b +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_57calcCubicPoints, 0, __pyx_mstate_global->__pyx_n_u_calcCubicPoints, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[34])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1001, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_calcCubicPoints, __pyx_t_2) < (0)) __PYX_ERR(0, 1001, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1040 + * + * + * def linePointAtT(pt1, pt2, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a line. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_59linePointAtT, 0, __pyx_mstate_global->__pyx_n_u_linePointAtT, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[35])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1040, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_linePointAtT, __pyx_t_2) < (0)) __PYX_ERR(0, 1040, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1053 + * + * + * def quadraticPointAtT(pt1, pt2, pt3, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a quadratic curve. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_61quadraticPointAtT, 0, __pyx_mstate_global->__pyx_n_u_quadraticPointAtT, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[36])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1053, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_quadraticPointAtT, __pyx_t_2) < (0)) __PYX_ERR(0, 1053, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1068 + * + * + * def cubicPointAtT(pt1, pt2, pt3, pt4, t): # <<<<<<<<<<<<<< + * """Finds the point at time `t` on a cubic curve. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_63cubicPointAtT, 0, __pyx_mstate_global->__pyx_n_u_cubicPointAtT, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[37])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1068, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_cubicPointAtT, __pyx_t_2) < (0)) __PYX_ERR(0, 1068, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1094 + * + * + * @cython.returns(cython.complex) # <<<<<<<<<<<<<< + * @cython.locals( + * t=cython.double, +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_65cubicPointAtTC, 0, __pyx_mstate_global->__pyx_n_u_cubicPointAtTC, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[38])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1094, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_cubicPointAtTC, __pyx_t_2) < (0)) __PYX_ERR(0, 1094, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1119 + * + * + * def segmentPointAtT(seg, t): # <<<<<<<<<<<<<< + * if len(seg) == 2: + * return linePointAtT(*seg, t) +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_67segmentPointAtT, 0, __pyx_mstate_global->__pyx_n_u_segmentPointAtT, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[39])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1119, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_segmentPointAtT, __pyx_t_2) < (0)) __PYX_ERR(0, 1119, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1134 + * + * + * def _line_t_of_pt(s, e, pt): # <<<<<<<<<<<<<< + * sx, sy = s + * ex, ey = e +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_69_line_t_of_pt, 0, __pyx_mstate_global->__pyx_n_u_line_t_of_pt, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[40])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1134, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_line_t_of_pt, __pyx_t_2) < (0)) __PYX_ERR(0, 1134, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1148 + * + * + * def _both_points_are_on_same_side_of_origin(a, b, origin): # <<<<<<<<<<<<<< + * xDiff = (a[0] - origin[0]) * (b[0] - origin[0]) + * yDiff = (a[1] - origin[1]) * (b[1] - origin[1]) +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_71_both_points_are_on_same_side_of_origin, 0, __pyx_mstate_global->__pyx_n_u_both_points_are_on_same_side_of, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[41])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_both_points_are_on_same_side_of, __pyx_t_2) < (0)) __PYX_ERR(0, 1148, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1154 + * + * + * def lineLineIntersections(s1, e1, s2, e2): # <<<<<<<<<<<<<< + * """Finds intersections between two line segments. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_73lineLineIntersections, 0, __pyx_mstate_global->__pyx_n_u_lineLineIntersections, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[42])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1154, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_lineLineIntersections, __pyx_t_2) < (0)) __PYX_ERR(0, 1154, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1232 + * + * + * def _alignment_transformation(segment): # <<<<<<<<<<<<<< + * # Returns a transformation which aligns a segment horizontally at the + * # origin. Apply this transformation to curves and root-find to find +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_75_alignment_transformation, 0, __pyx_mstate_global->__pyx_n_u_alignment_transformation, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[43])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_alignment_transformation, __pyx_t_2) < (0)) __PYX_ERR(0, 1232, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1242 + * + * + * def _curve_line_intersections_t(curve, line): # <<<<<<<<<<<<<< + * aligned_curve = _alignment_transformation(line).transformPoints(curve) + * if len(curve) == 3: +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_77_curve_line_intersections_t, 0, __pyx_mstate_global->__pyx_n_u_curve_line_intersections_t, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[44])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_curve_line_intersections_t, __pyx_t_2) < (0)) __PYX_ERR(0, 1242, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1255 + * + * + * def curveLineIntersections(curve, line): # <<<<<<<<<<<<<< + * """Finds intersections between a curve and a line. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_79curveLineIntersections, 0, __pyx_mstate_global->__pyx_n_u_curveLineIntersections, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[45])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1255, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_curveLineIntersections, __pyx_t_2) < (0)) __PYX_ERR(0, 1255, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1293 + * + * + * def _curve_bounds(c): # <<<<<<<<<<<<<< + * if len(c) == 3: + * return calcQuadraticBounds(*c) +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_81_curve_bounds, 0, __pyx_mstate_global->__pyx_n_u_curve_bounds, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[46])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1293, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_curve_bounds, __pyx_t_2) < (0)) __PYX_ERR(0, 1293, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1301 + * + * + * def _split_segment_at_t(c, t): # <<<<<<<<<<<<<< + * if len(c) == 2: + * s, e = c +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_83_split_segment_at_t, 0, __pyx_mstate_global->__pyx_n_u_split_segment_at_t, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[47])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1301, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_split_segment_at_t, __pyx_t_2) < (0)) __PYX_ERR(0, 1301, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1313 + * + * + * def _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * curve1, curve2, precision=1e-3, range1=None, range2=None + * ): +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_85_curve_curve_intersections_t, 0, __pyx_mstate_global->__pyx_n_u_curve_curve_intersections_t, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[48])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1313, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_mstate_global->__pyx_tuple[3]); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_curve_curve_intersections_t, __pyx_t_2) < (0)) __PYX_ERR(0, 1313, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1380 + * + * + * def _is_linelike(segment): # <<<<<<<<<<<<<< + * maybeline = _alignment_transformation(segment).transformPoints(segment) + * return all(math.isclose(p[1], 0.0) for p in maybeline) +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_87_is_linelike, 0, __pyx_mstate_global->__pyx_n_u_is_linelike, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[49])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1380, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_is_linelike, __pyx_t_2) < (0)) __PYX_ERR(0, 1380, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1385 + * + * + * def curveCurveIntersections(curve1, curve2): # <<<<<<<<<<<<<< + * """Finds intersections between a curve and a curve. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_89curveCurveIntersections, 0, __pyx_mstate_global->__pyx_n_u_curveCurveIntersections, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[50])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1385, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_curveCurveIntersections, __pyx_t_2) < (0)) __PYX_ERR(0, 1385, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1427 + * + * + * def segmentSegmentIntersections(seg1, seg2): # <<<<<<<<<<<<<< + * """Finds intersections between two segments. + * +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_91segmentSegmentIntersections, 0, __pyx_mstate_global->__pyx_n_u_segmentSegmentIntersections, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[51])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1427, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_segmentSegmentIntersections, __pyx_t_2) < (0)) __PYX_ERR(0, 1427, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1475 + * + * + * def _segmentrepr(obj): # <<<<<<<<<<<<<< + * """ + * >>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]]) +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_93_segmentrepr, 0, __pyx_mstate_global->__pyx_n_u_segmentrepr, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[52])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1475, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_segmentrepr, __pyx_t_2) < (0)) __PYX_ERR(0, 1475, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1488 + * + * + * def printSegments(segments): # <<<<<<<<<<<<<< + * """Helper for the doctests, displaying each segment in a list of + * segments on a single line as a tuple. +*/ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4misc_11bezierTools_95printSegments, 0, __pyx_mstate_global->__pyx_n_u_printSegments, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_misc_bezierTools, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[53])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1488, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_printSegments, __pyx_t_2) < (0)) __PYX_ERR(0, 1488, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1496 + * + * + * if __name__ == "__main__": # <<<<<<<<<<<<<< + * import sys + * import doctest +*/ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1496, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_10 = (__Pyx_PyUnicode_Equals(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_main, Py_EQ)); if (unlikely((__pyx_t_10 < 0))) __PYX_ERR(0, 1496, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__pyx_t_10) { + + /* "fontTools/misc/bezierTools.py":1497 + * + * if __name__ == "__main__": + * import sys # <<<<<<<<<<<<<< + * import doctest + * +*/ + __pyx_t_6 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_sys, 0, 0, NULL, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1497, __pyx_L1_error) + __pyx_t_2 = __pyx_t_6; + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_sys, __pyx_t_2) < (0)) __PYX_ERR(0, 1497, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1498 + * if __name__ == "__main__": + * import sys + * import doctest # <<<<<<<<<<<<<< + * + * sys.exit(doctest.testmod().failed) +*/ + __pyx_t_6 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_doctest, 0, 0, NULL, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1498, __pyx_L1_error) + __pyx_t_2 = __pyx_t_6; + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_doctest, __pyx_t_2) < (0)) __PYX_ERR(0, 1498, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1500 + * import doctest + * + * sys.exit(doctest.testmod().failed) # <<<<<<<<<<<<<< +*/ + __pyx_t_7 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_sys); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1500, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_exit); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1500, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_11 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_12, __pyx_mstate_global->__pyx_n_u_doctest); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1500, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_t_12, __pyx_mstate_global->__pyx_n_u_testmod); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 1500, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_13); + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __pyx_t_9 = 1; + { + PyObject *__pyx_callargs[2] = {__pyx_t_11, NULL}; + __pyx_t_8 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_13, __pyx_callargs+__pyx_t_9, (1-__pyx_t_9) | (__pyx_t_9*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1500, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + } + __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_failed); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 1500, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_13); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_9 = 1; + { + PyObject *__pyx_callargs[2] = {__pyx_t_7, __pyx_t_13}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_4, __pyx_callargs+__pyx_t_9, (2-__pyx_t_9) | (__pyx_t_9*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1500, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/misc/bezierTools.py":1496 + * + * + * if __name__ == "__main__": # <<<<<<<<<<<<<< + * import sys + * import doctest +*/ + } + + /* "fontTools/misc/bezierTools.py":1 + * # -*- coding: utf-8 -*- # <<<<<<<<<<<<<< + * """fontTools.misc.bezierTools.py -- tools for working with Bezier path segments. + * """ +*/ + __pyx_t_2 = __Pyx_PyDict_NewPresized(15); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_calcQuadraticArcLength_line_151, __pyx_mstate_global->__pyx_kp_u_Calculates_the_arc_length_for_a) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_calcQuadraticBounds_line_298, __pyx_mstate_global->__pyx_kp_u_Calculates_the_bounding_rectangl) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_approximateCubicArcLength_line_3, __pyx_mstate_global->__pyx_kp_u_Approximates_the_arc_length_for) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_calcCubicBounds_line_412, __pyx_mstate_global->__pyx_kp_u_Calculates_the_bounding_rectangl_2) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_splitLine_line_450, __pyx_mstate_global->__pyx_kp_u_Split_a_line_at_a_given_coordina) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_splitQuadratic_line_507, __pyx_mstate_global->__pyx_kp_u_Split_a_quadratic_Bezier_curve_a) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_splitCubic_line_552, __pyx_mstate_global->__pyx_kp_u_Split_a_cubic_Bezier_curve_at_a) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_splitQuadraticAtT_line_589, __pyx_mstate_global->__pyx_kp_u_Split_a_quadratic_Bezier_curve_a_2) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_splitCubicAtT_line_613, __pyx_mstate_global->__pyx_kp_u_Split_a_cubic_Bezier_curve_at_on) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_solveCubic_line_848, __pyx_mstate_global->__pyx_kp_u_Solve_a_cubic_equation_Solves_a) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_lineLineIntersections_line_1154, __pyx_mstate_global->__pyx_kp_u_Finds_intersections_between_two) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_curveLineIntersections_line_1255, __pyx_mstate_global->__pyx_kp_u_Finds_intersections_between_a_cu) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_curveCurveIntersections_line_138, __pyx_mstate_global->__pyx_kp_u_Finds_intersections_between_a_cu_2) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_segmentSegmentIntersections_line, __pyx_mstate_global->__pyx_kp_u_Finds_intersections_between_two_2) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_segmentrepr_line_1475, __pyx_mstate_global->__pyx_kp_u_segmentrepr_1_2_3_2_3_4_0_1_2) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_test, __pyx_t_2) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_XDECREF(__pyx_t_13); + if (__pyx_m) { + if (__pyx_mstate->__pyx_d && stringtab_initialized) { + __Pyx_AddTraceback("init fontTools.misc.bezierTools", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + #if !CYTHON_USE_MODULE_STATE + Py_CLEAR(__pyx_m); + #else + Py_DECREF(__pyx_m); + if (pystate_addmodule_run) { + PyObject *tp, *value, *tb; + PyErr_Fetch(&tp, &value, &tb); + PyState_RemoveModule(&__pyx_moduledef); + PyErr_Restore(tp, value, tb); + } + #endif + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init fontTools.misc.bezierTools"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #else + return __pyx_m; + #endif +} +/* #### Code section: pystring_table ### */ +/* #### Code section: cached_builtins ### */ + +static int __Pyx_InitCachedBuiltins(__pyx_mstatetype *__pyx_mstate) { + CYTHON_UNUSED_VAR(__pyx_mstate); + __pyx_builtin_round = __Pyx_GetBuiltinName(__pyx_mstate->__pyx_n_u_round); if (!__pyx_builtin_round) __PYX_ERR(0, 906, __pyx_L1_error) + __pyx_builtin_print = __Pyx_GetBuiltinName(__pyx_mstate->__pyx_n_u_print); if (!__pyx_builtin_print) __PYX_ERR(0, 1493, __pyx_L1_error) + + /* Cached unbound methods */ + __pyx_mstate->__pyx_umethod_PyDict_Type_items.type = (PyObject*)&PyDict_Type; + __pyx_mstate->__pyx_umethod_PyDict_Type_items.method_name = &__pyx_mstate->__pyx_n_u_items; + __pyx_mstate->__pyx_umethod_PyDict_Type_pop.type = (PyObject*)&PyDict_Type; + __pyx_mstate->__pyx_umethod_PyDict_Type_pop.method_name = &__pyx_mstate->__pyx_n_u_pop; + __pyx_mstate->__pyx_umethod_PyDict_Type_values.type = (PyObject*)&PyDict_Type; + __pyx_mstate->__pyx_umethod_PyDict_Type_values.method_name = &__pyx_mstate->__pyx_n_u_values; + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: cached_constants ### */ + +static int __Pyx_InitCachedConstants(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "fontTools/misc/bezierTools.py":639 + * # segment should always start at pt1 and the last segment should end at pt4, + * # so we set those values directly before returning. + * split[0] = (pt1, *split[0][1:]) # <<<<<<<<<<<<<< + * split[-1] = (*split[-1][:-1], pt4) + * return split +*/ + __pyx_mstate_global->__pyx_slice[0] = PySlice_New(__pyx_mstate_global->__pyx_int_1, Py_None, Py_None); if (unlikely(!__pyx_mstate_global->__pyx_slice[0])) __PYX_ERR(0, 639, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_slice[0]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_slice[0]); + + /* "fontTools/misc/bezierTools.py":640 + * # so we set those values directly before returning. + * split[0] = (pt1, *split[0][1:]) + * split[-1] = (*split[-1][:-1], pt4) # <<<<<<<<<<<<<< + * return split + * +*/ + __pyx_mstate_global->__pyx_slice[1] = PySlice_New(Py_None, __pyx_mstate_global->__pyx_int_neg_1, Py_None); if (unlikely(!__pyx_mstate_global->__pyx_slice[1])) __PYX_ERR(0, 640, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_slice[1]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_slice[1]); + + /* "fontTools/misc/bezierTools.py":711 + * ts = list(ts) + * segments = [] + * ts.insert(0, 0.0) # <<<<<<<<<<<<<< + * ts.append(1.0) + * ax, ay = a +*/ + __pyx_mstate_global->__pyx_tuple[0] = PyTuple_Pack(2, __pyx_mstate_global->__pyx_int_0, __pyx_mstate_global->__pyx_float_0_0); if (unlikely(!__pyx_mstate_global->__pyx_tuple[0])) __PYX_ERR(0, 711, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[0]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[0]); + + /* "fontTools/misc/bezierTools.py":1320 + * + * if not range1: + * range1 = (0.0, 1.0) # <<<<<<<<<<<<<< + * if not range2: + * range2 = (0.0, 1.0) +*/ + __pyx_mstate_global->__pyx_tuple[1] = PyTuple_Pack(2, __pyx_mstate_global->__pyx_float_0_0, __pyx_mstate_global->__pyx_float_1_0); if (unlikely(!__pyx_mstate_global->__pyx_tuple[1])) __PYX_ERR(0, 1320, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[1]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[1]); + + /* "fontTools/misc/bezierTools.py":56 + * + * + * def calcCubicArcLength(pt1, pt2, pt3, pt4, tolerance=0.005): # <<<<<<<<<<<<<< + * """Calculates the arc length for a cubic Bezier segment. + * +*/ + __pyx_mstate_global->__pyx_tuple[2] = PyTuple_Pack(1, ((PyObject*)__pyx_mstate_global->__pyx_float_0_005)); if (unlikely(!__pyx_mstate_global->__pyx_tuple[2])) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[2]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[2]); + + /* "fontTools/misc/bezierTools.py":1313 + * + * + * def _curve_curve_intersections_t( # <<<<<<<<<<<<<< + * curve1, curve2, precision=1e-3, range1=None, range2=None + * ): +*/ + __pyx_mstate_global->__pyx_tuple[3] = PyTuple_Pack(3, ((PyObject*)__pyx_mstate_global->__pyx_float_1eneg_3), Py_None, Py_None); if (unlikely(!__pyx_mstate_global->__pyx_tuple[3])) __PYX_ERR(0, 1313, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[3]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[3]); + #if CYTHON_IMMORTAL_CONSTANTS + { + PyObject **table = __pyx_mstate->__pyx_tuple; + for (Py_ssize_t i=0; i<4; ++i) { + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL); + #else + Py_SET_REFCNT(table[i], _Py_IMMORTAL_INITIAL_REFCNT); + #endif + } + } + #endif + #if CYTHON_IMMORTAL_CONSTANTS + { + PyObject **table = __pyx_mstate->__pyx_slice; + for (Py_ssize_t i=0; i<2; ++i) { + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL); + #else + Py_SET_REFCNT(table[i], _Py_IMMORTAL_INITIAL_REFCNT); + #endif + } + } + #endif + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} +/* #### Code section: init_constants ### */ + +static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) { + CYTHON_UNUSED_VAR(__pyx_mstate); + { + const struct { const unsigned int length: 11; } index[] = {{2},{942},{1182},{542},{600},{52},{742},{779},{749},{1065},{33},{884},{1246},{768},{1293},{1557},{661},{20},{1},{1},{36},{26},{33},{30},{35},{34},{7},{6},{2},{2},{9},{33},{4},{39},{119},{24},{21},{24},{21},{20},{28},{25},{4},{6},{8},{8},{2},{7},{8},{12},{3},{20},{1},{2},{1},{2},{5},{1},{1},{2},{4},{3},{3},{2},{2},{4},{13},{25},{7},{5},{6},{25},{26},{29},{30},{4},{5},{18},{5},{2},{3},{3},{2},{3},{3},{1},{2},{3},{3},{39},{7},{7},{3},{2},{3},{2},{3},{1},{2},{3},{9},{3},{9},{3},{3},{3},{9},{3},{9},{10},{18},{19},{27},{15},{19},{15},{22},{23},{19},{23},{19},{17},{18},{5},{11},{3},{13},{14},{5},{6},{6},{23},{22},{13},{28},{46},{46},{27},{44},{2},{2},{1},{2},{2},{3},{3},{5},{7},{7},{6},{7},{2},{2},{1},{2},{3},{3},{2},{3},{3},{3},{7},{13},{2},{4},{2},{6},{25},{26},{24},{5},{8},{7},{4},{1},{6},{15},{13},{10},{12},{13},{12},{29},{7},{2},{5},{3},{8},{4},{5},{5},{21},{12},{6},{13},{8},{4},{9},{3},{5},{8},{10},{4},{1},{8},{10},{4},{3},{4},{4},{3},{8},{6},{1},{2},{2},{2},{2},{2},{8},{11},{6},{3},{9},{5},{13},{2},{3},{4},{4},{3},{4},{4},{3},{3},{2},{2},{17},{12},{1},{3},{3},{6},{6},{8},{5},{6},{5},{1},{2},{3},{3},{2},{3},{3},{5},{8},{4},{3},{4},{4},{7},{15},{27},{12},{29},{8},{4},{12},{10},{7},{7},{9},{10},{14},{5},{10},{14},{14},{15},{13},{21},{27},{9},{14},{18},{17},{31},{21},{19},{4},{5},{7},{2},{2},{3},{1},{2},{4},{4},{2},{8},{7},{5},{5},{9},{15},{9},{2},{3},{10},{13},{2},{2},{2},{2},{2},{5},{6},{5},{1},{2},{2},{2},{2},{2},{5},{6},{1},{2},{2},{2},{2},{5},{6},{205},{2},{204},{22},{42},{24},{87},{182},{141},{37},{127},{95},{40},{31},{106},{31},{61},{172},{23},{105},{94},{92},{151},{651},{404},{145},{155},{92},{102},{120},{386},{269},{87},{145},{244},{30},{252},{187},{43},{2},{2},{2},{179},{2},{568},{143},{104},{54},{80},{129},{38},{90}}; + #if (CYTHON_COMPRESS_STRINGS) == 2 /* compression: bz2 (6697 bytes) */ +const char* const cstring = "BZh91AY&SYl\266\355\314\000\014\337\377\377\377\377\377\337\177\377\377\377\377\347\377\357\377\377\377\367\300@@@@@X@P@@@@\000@\000`\036\357wy}\267\276\357+\324<\356\327\336\032\273\271\336=\356\357{z\361f\301<\037z\311\\\362\341D\372\373\275\034\373\026o\226\357\273\236\236\236\200\367\261\362:)\356\364s\327N\215\034@M\203{\300( E\013\342\200 \037\tB \204\023\324\236M1\265\006\247\264\001\032jz\236\023\010S\324z\233ML#L\230A\210h\006\215\000\323M\000\006\202I\023\002i\2414\ni4\315I\345\033)\211\3523SF\236\246\200\315!\220\006\200h\000\320\000\014\232\000\r\002S@IE=#\322\206\020\306\232!\223LG\240\023?M)\244`@a\001\210\014\002i\202\006\231\006\023L\t4\222EOD\324\336\223D\364\323SOMM\030\232\033Q\210h\321\223cM\"6I\241\240\000i\241\240\311\221\351\032\000\000\010\244H\323F\232MS\304\365O\324\361'\222\203z\221\243\030\240\3204\315#@z@\000h\320\000d\003@\332\231\r\000$D!4\t\202b\t\204dL\3214\247\236\245\017\0014!\240\323@\003@\000\000\001\223@\000Q'P}Z\227U\331\231\320,Zu6\333\034f\334\304e\240\260f\276\343:v%\205U\023\374\333\257\333t\256E|\256w7w\311\213]^\261\276H7\377d\353\026\236\271\374\275\213m0\224\220J\222\232\n0\224:E\037\"!\245\304\230\240\247&\036\032\323\003u\207\004\201L\301$\224E\"\265\n\223\230\004\320\246\004\3479\314\377\241\354\263033@PP \261`\240\306AH\214\210\301`\n\002\222*\300TE\001`\260\006<\240\010J\210\252*\225B\265=\262\004Y!JR\222$\211X\227q/\374%e\343\022\024\305\006&!]\366HU4\306\010\301\001\245\2446\206\300\030\311\030\202\213\010\260\005\200\240\252\013\025d\016\021LGT\210\001m\"\006\254\314\303z]\311\370d\304\201\231\005\366\271\332\001\345C\236\000\374!y\352k\215\007r.\364\262\361\350\026l+Lt\346\222\347I\020C\314\204\005\316\263\236y\226\001|\252\211\370M\203\310\362qs\327\353\317|\013\330\345\301\237\014\217\"\213Fx\306r,8\003!GdPQf\326\340W\t\034\205\366\003\342\373\257AM\216l\245Q\321\003Cm\355\006\2771}\325\315\332\013\264\355@\306\220v\372\375t\027\247\317zW\336\001Pc\001\244\337\247\017HJ\273\301\203h\210\301w\207L4\304\355""\245\262\250\244Pp:\233O\026rtl\026c\001\246\226\177\005\365ld\265\220\330C\024\031\256\252W\332\301f\233\023HrH{\307%\026ET\245\031@\363\206H\232\211\257\223\252\244&\t\203(\262\240\273\221/}P\244a\202\243\035\264E\223M8\264\"\227RU\235J\257sh$[;\335\221\235A#$\202\251\031\010\262FH}\225\222\n\225=\004\325*\211\n\265Y\235\352\032\006\354\262\003<\267\022W\025\322\270]\\\214+T\252k\211\000E@\245\026\241\246x\342\225\212\225\014\252@\203\003\301\364\244\310]P\242\223\232\216UR1\221\300}\235s\274\222I\002\230\225\311\002\210\367G3B\036\207Q\316\211\365\020\212A\n\260B;\220\262 \0206\222\230\016\257\347(\213\277\211\322\"\312/=v\350\252\364`\016D\004\003\202\"#\030\000\376\335\361W\267\317\213n\022l\025\001U!\014ci\374\220\001\360\271`\376\347\211\0317\237\021\355\310fg\014\227\202\326\006\330\263[R>\375vC\020\005\013S\320\272\353!B^\003\035f \375\002\241\2543\2535\342r\337\230\265\001\321@\302\230\271\262\203\222C~\010\242\276\370BJ\231\331\016\235\210\032\032\021\206\315\336\207\356\3518\264-1\201\240\332\363\200\373L\221\262\331\rz\005T\356\270/\336\266\027\000\305\213\204u\246\235p\312\214\317&\302\240Xn\006\206\354c\244\205\016\037|\305f\022\013\2637\036'\341!\242\333`\252\235\305\273\027\203\263`\300\030%aM\350\272\030\271\246\026\256;\016\261\203\215vz\236\242#K\225\316>\007\206\201\021\004\006L&L\215\311\223\226@1\202\204}i0\034\304G\315pb@\276\254-i\006\204j\2707\0030\0237\262\250\177w\026b\014\207\005Cx\361R\005q\026\030\"b\321^\304\342\340T3\014\205@\222\001\203\"\002\0245\245H\3032+\233R4\\\265O\235F\251\2646[+j\207v\370\312/\217\266Z\333\332\345\021\311F\023i\016gx5\204\356m\315\272g\013\252\"\244yF\312f\307\205\226\020\357\364;\236\026\301\221\021{\313\252\244TE\013\026\303\334\010\367\306\"\026)b\202\001D^\224\357\224\241EOP\367\341\351\330\013\026W22X\227\357\262\347\266h\314\365\r\267\347\231\232\276\314\371\026@\276\263\270\376^\233\225.\310d2\036\276<\377\007\320u\005!m\006\210\230\371K\224\006\023H\335\032\206\260\331\024\346\246\344\222\3541I""\315\024\201\023\nX\262\213\330\321\201\r\"\310\002\301a\005\204\322\022\211 \254\030\304\202\300PP\240\326E\017\013\271\244&2\010VB\034s\262\367|n\214\265\234<\374|\275\351\264*\236.\344\222\370A\335YqgNL\003*^\003\343K\007\035\001\352E@`\222N\222d\223\010pBL\006\202c\031B%\341\267$\210/v\272\033@\332\002\262\002\222\025\r\314.P\352}*Bj\013\246U\010\240\310a\316\007\010,?\317$J\362\"\325|)N\224v\267\372>\247g\262{>\316\265\345\322L\331\234\267\362L\322\361x\263x_\036w:\250f\205Lp\200\230\003,D\0242\276\232\001&\204\023\021\rs\367liXEEUE$\010\004\005Y\326\365\220s\262\344[\t\235\005\324m\263D\314\351\225\032\336n03v\261*B\2501\202\210\263q\036\201\224X\203m1\225\273&\031+f\223c\177\2357A\336\0336\366YZ\0023\351\237\005\t\207\240\3403(f\032E\342\300X\006\337\263\312\261}\304\022H\331-\214O\357\363\372\217:\361\347\362\375\030\233\023le\344r\266\327\324\351\032\244\260hou\275\2647\016\321`\203\330\031i\340\232\016s\337\275\343\321\347\332\232L-9\3557^r\232\035\271\366M\317<\260\222\332\215\263F\250B\004\030>!\004\250\201\332qL\224\032\202\344\333e\202{N\326\330l\311\032q^\323\367\272o\260\364\363L\314\037=E\251l\363\004A_\335\3768\356\257\270u\3719N \330\337\227i\255\267\300\302wjD\334ZT\030\250s^r\006\225\223H\245Z(\250\266P\215\021j\033\2317\032/xSyL\tL\224\320\233\230\006H\320(^v\363A\200\260\027O\"T\301\217\277D\312\005C\221\301\232\024\272\3032\230\342\"\333%\020\250\002\220-\220\2536\222\220\246(\r\206\033\204\3406\300\251\220u.\250\260\205BRw\020\224M\362\2070\2570\031q\220f$\324\2559\334\3530\263\3102]\361>l\221RZX\227\t\002fb\363\007'Z\221|a\014^\363\030\302e\3078~es\211\213\261\221#\003+\003\007\237\364\377\307s\323\337\33018plNv\211\324\351J2\r\202.\\\306\330\347\304\220\304\237\004\220y\303\004\022\001\206@2\316\354\342\231\267Q\374\272\307S\032\205!ye3wC\345\tTg\0243$\362D\233\022\004`\214g$\323\320\211\n\266d\315\t\035\017\220\306&7<\033\303\310l\363\376\211\341\207c\234xJ\236\033\036\016\275_;?\257\327\313+cIS\267\031JR\212-t\310\274\345U\021\220\030""\013\210b\016\316\004\3428x\211\221\307\0334\301\201\206\"\207Q&Lj\241\320\237\007\222E\002vS\ru\014\350\310\217\263\316\346\034\304l\352S\241\316\243V\223V\234\272Y\202G)\n\260BFF\265L\302\024\2461\026vl\320\232\352\004d@\236p)\3330 K,N\334\013O\267\006\300\311\222f!@\007\247\254\206\224\206p\354\350^\246n\201J\302\017\305\361-]\265M\332\362\360H^\265{\216\226\273`\360\245Sj\256\243\243\215\371\323\024\261bw\221\363g\315\216\316d1\3059\316t\240\025\001\022\232\010TD\227\341\360\325\n\311^\303kl\355\2059\372\273\034\332.)\245;\021sB\241\034\332\263\211\245aI\245r\001\310\264{\204/\333\204\267aI\342H\236z\274\276\351\315\314\031ey]\244e\014\037\221\2269\352\320(\371\341^\\\345\245Z\225'K2\244\327\276\030eD\t@IBT\225\tiQ\r\372\272\271T\364\362\365\320:jy\013\350t\026\260uZ\353\257'\243\003\n\343\325\324S\014\320\303-ns8^s\3415$W\\d\306rD\225yy\202\317'\036\237\032\331\r\215\025\333\305u\371}W\007W\227g{J\372`\203\276\007r1Qs\222(\030\026\005\003\2659p\240\026\365K\325\341*6i\006\266k\020\2741\022\204\243\342\210C\016\363\337\364\346B\324#0\252/p\367\025\256\263\313\216""\322\034\035\357R\351\304\325\004\307\360\247h\032\266@\246_i\231n>\230\030\260\211\202\301\"\010\010\211M\025\242\354dd\373\371\247\245\2719;0\036\343\016\370c\005'\010\253d`\243C\206N\0318@\341\207\014\3419G\201\236\251\013\366}\017\204\335>St\360]\370j\203P\321h\032\032z\262\242\344%@\242[P\350\212\\e\305\211\315O\"\231tVF.=\240<)B\220\365\275\177Y\353\207\2004Z\262a\231\216\266*\377<\347\200\205\276IHMQvu\251\353\344uF\030\334\377\2019s\376\035W}\317J:\365#\223\222\017\267\212=\271\217g\263\315\364\323\360\263\030\245\210\214\255\270C\023\216SK5\2001wv\007*UG\232\236erB\272\034\014j\305K\2124M\244z\271\240\206&\245\0341Vf \207\243^\307(3\344Z\"&\306\316\224\340\0031\000\317A.+\201\2707nE\355\222H\263\205\341+ \260X\025Q\277\035\371\357\013\010\3110\272\215w;\273t\234\216\357t\321\006\200h\221\2747\233\240y\227\336J\354mBB\302\n\235V\256\005\202FC\014\355\006F\222\025\341\343v\033\026{Y\010\367\236\341\201\004L\204o\212N\331\331\021\223 \215\262l\341\330\220\035\211v\001\330\227`v\021\350\210\274\2614\007#\n\010\266\260h\346\350i\304ETj/,\346I\247\007\034U\326\031\272H\004\2073'\035WA\212\004TA_#y\264\360\340\034\022\340\267\371\321\347V\363sf\003x\314\343\001\373\335\340\266\021\270d\234\226\t\033%\t\260\251X\003\263\002\207i\023K\227\0016\314\220#Sg\005\025\030\340O=!6\306\233U\205\361\375\256\024\266\n\342e\336\312(\202`PG\243<\207\344tA5\364\366\363T,\316\273[\262\3250\306-\251JQ\231Q&\003\rRC\033lm\214\222)\265B(\333\036\207\246M\330Z\245d^ti\010\302\250\217F\220\315,\017\367\010\206\014i\241\"\315h\n\007\327\227\237H\262=\261y~\214\207\322\366\337\360\005\331r\353\362\251\004\260\006\222b\006\233\227\316,\320\324J\320\031\0255\307B\344*\231\225\037b2\032\264\354\025\2540bM\210\266\260\016\364\322\013\314\360\000g\330':,\013c\r\014X\302Et\215\244%\247\026\3409\214\t\242!U\261$\300\376J)\352$\250\317\026F\222\226\034D\267\205Z\205\\\032\307z.d\273\035@K\246\311\244t\272C\273x\232e\323vU\312\300\204\r6\330\274\023S\370\007T\235\234\252dj\342\252\200t\357>\031D.\230\010_7\2777\036\316d\205\210c\327\"\361/i\351\250\260UE\302\000\221\364\t9I*}\200\343\303\202\315\322v\203\030\332\006!;\342\360\302\022B\357Hi97\2303\276\344Oxx{\203n\204T\0220`\252\202\304\021\210\212\214D\030\250\242\212\253\023\301'6f}\036\367\222+J\377\221#J\361\033\261\210\237\270^\317\202\017@,@\237\214\037G\221v \037\320\214\r\215\002bb\030\232W\264\207\036\260\366q\3460\013\00786\245h\314\226^\276\344\032\332CH\031\265\013\336y\030\020\0145#\001\332\310\016r\001A\222A\246\227Xq]T\261\003\232\302\313w@_#\210\034D\302\305\210\027\3324\234w\357\314\207\313\321x]\225\205\024\007WJ\016\320\321G\314c\257\226\360\347\016d\263@7\376\006\036\325\205\020\004,\341\274\3474\260\033J\224\303=NdY\243,\010X-\205\016\224\223B\347d\370\314\346~:4\354>G\245\014\360c1+\211\n\346il\235\275-\210""\344d5\246\211 \030\232\252a\340H**\006\375\377\303$=\031A9\346\300\240\r\033\304\007\026\000A]\267\363x\007\2621\326\257\022\2619\310Zh\240\204\327L \317\214\"\002B\264\344\251\331\3351\003\266\334hq\203\232k\355\273\215\211y\014\230p\2155\320\301(!\031!\241!\016\036_o\201\2417\310\310M\362\025V@R\357SI\337Z\270\003P\260\215\311\324\316!\232\204\320\200\235\205\006F\003 `5hL\311'\220\240 0@F\n\272\226\2245%,\020\022\002#\025\036\343\226\210*Kj\370\\\200/.N\347\3039\363bHwG\225\340t!8\201Y#m\275Icx\275<\211u|m\003\324\031\201\200\301\243K3\264^\225\0175h\002)\2000=\320\177P]\351ZR%\246\363\237!C?&\031S\014\\v`\200\340\272\230-6\360\007EVg\006.qFZ\371\276>\201\342\2341\300<\324\232j\354\324\016I\036S\031\271\202\317\267\351\347\346\246\201\205H\371\373\204pI\202\032\354%\264\006\304rf\316L\034\270-\341\355\013\360\247K\204\033f\031\027\006wT:\260\233\002e\217\004{P[u~\330\250\2747\322\202\241H\r\372\276\270k\337\366sd\247\"2;\364o^\357\213\371>o\231\312E\002\005D\276\224|\365*\3304V\"\030V\013\013M\206\345\304[\036\253Z\363\275\361\320\003\267 3\241\n\021J\017\247\345\251&\216\233\312tt\353\n\205ru\240F\325\226\207X\330\204\362\347@ew\322\010\225,WZ\331d3/I\343\230(Xi1;\357\022\232\006\"\201\"\220\206\326)*%lx\332\306K\301JZ-\006\r T+Z\032h;\023\355\200\255\270 \033\246%\036\002\2060\3069\000\340\231^x\374C\024\273\303\234\344\322\220HD \201@kJ\200\340\250\230\025L u\252\030H\201\204\243\353H\267\262D\237\251\036\213\253\325\333Jv\365\323\021.\261,\206)b\226p\250P\210\303,\222'\317\323|\205\216\313\3423R\373\335DxQ\303\245*\275 U\322\355\254\\\014\220a\361\234u\364C\222\332\227\266{\256a\337\241mL\024V&\020o\020\344\350\326\257\305\036,\007\336\276.\256\026]\347q1\007\001\017\206\274\2478\341\270\301\326\204\005\301\316F\016p\350\315\212\321L+\321\263\344\264\260l\231\266\000\346i\005#\213\301Q7\016\373\353\315S\270A\334%\334.\344w\007j\347F\215\341\244\314\232r#\235\242\201\260\031\262T\002cbj\244lL*S\240\233\321k\232>zQ4Wq\013\225z\263 \354\362x\004\362\262\255""\007\256\201\010\r8\013\014\242P\206\003hS\302RG\202\023\006*\252Z\232\235\316\253\241\314\352\260r)\0057\205\376\352{\262\021RZA\"\335v@\331Y\025F\220-\301 \263b\342\356\360lH\310\326\014`\205>J\310\300F.\000\300\310mU\306\364\320\\\301\264(\030%l\263u\003\313\276\230\254XQ6\357E\373n\263r\204\002\200\311Q0\200\2602\333\321\034\236\331\350\325\3037\300\302N\334\3319\345\242\267\"\3026d\201\322H\034*GIt\241\320.\2014\007\033G\245\310H\025\210`\313\034C\200\020\010A\021\005\367e\030\215\304\014U[V\337\205\\\275\\\262\252\220n~~q%\001\205\362\001\002\005\2311+2\377\206\346\014\312\367nF\340\334\033\205\270\366\232>\037G\037G\243R:|\236\316\215m\t\014\006\201\264\213\322\264\355F\275z\326\277V\301\352\301p\r\321\355^\241VEF\352/[\2278\254Lq\357Y\306\014\3678G?\030\343\307~\203\330u\365\337\316}\002Y'\035q\326\374\257=\365\004\322\231\363\304p\242\350\335\320v\362\234\336E\2450\325\034\231;.Yx\374\353\3149mJ\214b\356,q\312\3340|\334\347\230d\347\t\035!\307\303E\265\331\035\264C\277\363\206\217\361\346\245G\301\332N\257W\255*Y\304\271ob\013P\275\321\274\363\312\030\n \300X!\003\357\376&A\210\261N\222T\205aS\224 W\342\014\261\345Bv\262\004\261\023\207\327\310R\204\366\372$\277\307\327\222\305GI\243\230\\K\006\025+\252X\232\205\225=\255\217d\020?e\242\010\300\362\3540Ly\300\223f\025\247\257\345\373\226\372\332)p\315g\300\260\203\021\230\260\321\242`v\251\210G\277\373;Q\233\202\206\323y\223\",D\351\035\021}\224\355\t\311\321\321\325_HCdLK\260\315\006\354\224\035]\260\034=\203v\227f\032N#{\341\005\257\221\346{9\r\226\313Aa\252\027k,d\304\"x\226%\016T\020\002\376\252\010\007\233\034)vo\345~\022;\270ND\177\240z\246\242\324}]\027%:Y\203\262\352\224O\017Gl\233\350\177,78\355\325\351>W\343O\037\322\361v5\344 \256\333`;\250`T\337\201E\nQ\355[\030n\325\024\306\360A\202*\221\021\3619\036\256\2751\370\347\006\331\232S\344X\210\231\177\\O6\354;M\333\267R\354X\271\361\275o\365\344\366\241\343\357'\222\207\313\r\203}20\351\3503\ne\2718<\242\351\220\3632\212\032\025\2233\321\301u^+t>#""\213\367\236^\370_N\334\2244K\210\345a\345\np\340\321T\205C\241\3071\341C\327\335m\337\310\341\206\200\344\004\0335A\276F\223{\314\\\014#\227C\301\337\021\273\275\027\"97\323\020\316(\204\327r\241\302<\302(\226d\2416J\241\314\032\330t\304z\233\26699 \375\220\320\241\334t\210\345\202a\023.\232Sxd\301\014\343\016\n\213=\000\364w\206\356\361\267o7\262\240\345p^\315\022L\306H\302\023bS\352\234\234\236\2653\356\336\233\242E\202\272\014\266\177\237B\356w\010m\324,\336'V\235?O\347z\335i\3258\216\313P\373[\212\030\203\306T\353\205\2315\037\357\340u\375N\244z\374g\024+\256>\273*\360\026h0\330a\257?[\304f\326)\270p\353t\372\217[2\034O\031\356\021:\365\362j\237\002\244w\304t\177\377\376\035\217\027\331\360\374o\032\236P\361\343\300\374\317\356\364\031\216Z\2146\326\331h\233\316.?\350\237U\017\366\207\375\354^\307`\316\347\262lr&\273#\225\366\251Y\360~\207d=\0272S\263Q.^\310\206\276\355\343\354\177/?\3204\214=KV\\\364!\227\321\030\211\211\277\213\214\343\274~7\235\347M\220v\271\272\263-\037l<\376\267L\361\347W\252qkI\220\320j\234L0x\373\216\242y\223\315\0310\366\204\350\245\017\367\340\252&\335\033\217\004\337\313\320\0274p^\n\267v\227\034\201PJ8t\0317\326\271\215q\212\356\363\323&Q\360\261\332Q\223\264\333\326?\234\001\227\023d\236\347\014\203\3312(*\017p\361\3300\371\023\200\357\3424\227'\201C\272\344\216bv\314^\261\274\354\216TU\036\212\212\236\000\301\214\366l\246.\3434\n*\246L\252\252\212\350]\213\312b\367r\343\034/n\023x\267\220\242J\336@\352\034\375\275\377~r\300\217\210\336\341)\331\017\314\357\267\373\233\371\003y\231 EF7\262\344\306\273\217\030\306\370\030\201\356\200\313\223\251|\237\177\250n\375\354\301\214\352\251\000\252]\276a0\273\n0\270wE\031U/w\327\006&V\302\247\207\033\n\220\0306;\367\261\376M\3108b\021W\246\306<\212\347;\241D\337/_\025\373\256\302\257\344\277J\370\233\2528R\261\376\267x\035|\323\351\206\0073\225y\367\305]\004\347w/^G\251x\267\350q\363\312+y.\333\267n\343\230\270\254\367y\316_^\332\266\340\345rV\257\236\326m\026\236\370\034\356\023\252\276""\225\255\240\360[\266\177\026x\226\337Kr\345\262\001Wkk\207\275qU\316}\233In\255ql\214\245\253#\337Z\266U\377\252\225r\265\213\025S\303^\266uB\220\250\246l\233>;\362H7e$/I\321\327\3175\222Mb\355\335s\203[_\\\354kj\026\213r&\251\347\263@\325\241\245\251\352\034\304\323\371vj\223Gu\2217\317\022*\321\230v\016AS\305\224\346wt\017L\212NN#\004Z|\\t(\311\253\320\227\307Ma,\003\364p\2256+\226\327\244-'\333\275\320QN^C\264c\262\233\302i\310\204\\:I\231\246\234M.\321Y)N\006\004S9\216\321\216'{L\202\305\rBT\256\262b!\016g\014i\245\2574E,(\215<\2172\232\356\320\236^\310\203\007\251\232\230\234\353\350\300\220{\274\321j]B5\334jI3cD\350\223\365pN\245\tp4\022K\355\253\235U\216\367\211\331\256\266h\"\322\314\225g\327\202\226\235;\313^\311\365\253e\005F\031\0253A\201owS\212\235\344\314FJr\3038\242K@\352\240\034\247P<\353\211j\313\3321=\333\352L\307\245\232\231-l#\t|\rB\204\313l\211\333\"/\206\207\227c\362\"\370\\\023\377\027rE8P\220l\266\355\314"; + PyObject *data = __Pyx_DecompressString(cstring, 6697, 2); + if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error) + const char* const bytes = __Pyx_PyBytes_AsString(data); + #if !CYTHON_ASSUME_SAFE_MACROS + if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) } + #endif + #elif (CYTHON_COMPRESS_STRINGS) != 0 /* compression: zlib (6885 bytes) */ +const char* const cstring = "x\332\355[KW\033I\22666\270\260\r\266\301\330\3453]\335'1\270\014nP)\362\241\007]\345i\036v\227\317qU\233WU\365q\327\210\224\224\200\272\204Rd\246@\352\3233\343\245\226Zj\251\245\226:3\033-uf\305RK\226\374\204\372\t\363\335\210L\275%\300\217\251\3563\215!32\0367n\334\270\367\273\367F\246\027\244\345t\3322\263\211\003\3351l\311\3317$\335\212II#\265\347\354K\273\246%\351R,\023M\304\244\025\343\257\t\303\222lc\357\300H9\276\2337%\374l\333\030\364\007=c\333\213\257\314\250\3568\246t\230\321\343\226\356d,C:N\200F\352+MJ\233\211\224\003\352\246\2447gk\231\310\307\211m\032\206\264\264\233I\305\226vbz2\266J\323.[\261W\274\313\216\313\214\2354\217\301F4\343H\007&\346\320c\261\214E\324,\303\316$=\276\226\255={\211\227\350'\355\260\205\264#\343O\301\237\272$\255\232)\3072\223\036_\346._\270\273B\335\226\3445\311\311\244\223\206\355\222\3330\260\236T\013\305\345\246\214\216\364d\306p\373=\317\352\007\030\266\264t\263\321\363\331\263g\255\213n_\324\334\234\177A\362\317/Hs\262\266 1?/\006\233E\334\250}\276A\215\205\375>\277\252(r8\020\n+r\210\005/;\221\346\0258m\255Y\244)[&\322T_(\244\311\376\240\032V\265\260_y\277yDI\324\315K3R2\2212~'\031Y=\346\270\033'\331\373f&\031\227\242\006\346\366\373\232\214\250a_\270\365\207}\000N\026\233\234\3042v\372\202\234(\001_X\016\004\003\001\231i\001% \277\037#\213Z/V\3327\300\037RC*\013hJ\320\257\211\235^\205ad\222\375m\325\265\276~\366\332e\027K\322\246\243[\216\260\204\376\206\340k\031#/I_\353\251x\322\270\314 eIz\236\212\237?\342C\230\033\201\307\272'\207\036\373\320v'\301\033\007i'\347I\252A\n\226v)\262\215\355\r5w\324L\222\246\353\226\2134\rz\241\313\022o\330*\n\241\336\304\245#\303\302`=\371\356\263\320\022\344\246\212\252\347\254\202\371\203\276\240\237\300\210\251r \354\367\207.\273\246\2768\007\355\367\313\341`\200iZ@\325\344\200\362n\322\352&,\373}0\337\020\223U%\034R\375\301\300\245\005\264\310\032\273\254\265\221\366\313>M\221\203J\210\005TU\013\311\332\245H\253\rpR\373\352\317\002jZ<\227df\034;\0217\032\363\004\002\276@\353O\360""\3358\0300\177\3224\323\211\324\236\024\325c?5\210\253\236\236u\240S\324\314\244\342\324\3332b\216\236\332\003d|\024\224\322\337\r\247\364w@*\375|\254\302\0323\326b\3021\016DG\254>\r\317\202\345\221(\372\310egg.\373M\"\265 \345\3705\373\215\236\245\262\236\235\337\331\271\004\332\255\020e\273]_\373\331\030\357\304\233I\221}\376\371\213\223m\361\351\335\241\303\034h-H\374\322h\375\250\332\361\241c\273_`\003y\310\320)\345\013\306\204\255\373\030\324z\355cO\352\027\014\004\373\356\2467A\332\202\234\347\036=\336\225\274\337G\322\343\356i\265>\250\357\226\335(\250IZ\321|\032\"-U\241\271\371\217\024P}\010}\203Z\220/\223\377\010\275\242p-\365\304\221\216M\353'\302D\351x?\021\333\227\300\227a\331\330\241\204\231\222(\257\340\005$!\031\333x\221\000Wm=l\004|\316\261a\244x\306c\035!\270\002\014\350\014?\254)L\326\214E\277\3266b^\372\n`\"6\247ym\316\266ee\304I\356f:\231p:\337\273\272\311\032\325\357\301\203\244Z|\352\007?\027\363hp\303]\222^\233v\202;@\335;Y\201\376\332\234\311\306)GsP\302\376\332\264\022\177%\365N.Ik\t\313\365\236\356\204\226\236\023c\033\207ib\274\364\022\355\220\300B\203\020\375\354\354p\036\340\243\023n<\223\206\341\301\212\370Q\354\237Z\204\360;)\261+\355\352I\033\2117\250\246.N&%\375\320-\314\001p@\001T[vjKs<\354hOY\243\006-\220\216\022\233\242m\252\\\242\365\204\350\030l\330\231X\314\260\355\335L2\351\nhA\342\247\241|\332\216\260\004\002\336\003\267\311\366\274z\3601#?\247s""\375\221=\307g\020j}\261\363\306\005\211\277\276}A\022n=\036\274\354i\345\007ae0'\260{\315;\321T\230\217h\001>\334CF\224Z\307\270Uh\014\2048\330\210\207P\260I\342\343,\201\232\311\342{\313\322\007\034\t\002\177\303>\026\324X\220\007}\276`8\344WA\t\274\371C\234\315\240O\r\252L%jmtZ\353]!\204B\360\025aF\357\207\202\336r\031ui\251\013Cp\262\026\356\"\327ZO\3354\237\354\227\333\030\t\323\213\300\200\334\306\2608\336\365\005\203\001%`,2\217\344`t3S\244\335\342\323\016\341\023\271\311}4\210{\352\330M\200\263\007#\334y\300\360\256\240pN\026\334O\325\226\235\255\013k\033\334\332\337\235\251\\\222\177\272\004?\344*\2640\205\025\035k\3427\316E\320\247\250J\010d\003\276N\353jo\"\031h\2760\247\245*\356\360\260\302\311\211\3466\261x\372/\016|.\343\317\273\336\202v\236\031u\274\375l{\215\331\277\357\305\274\274x\r\362\316N\236\017\377\307\362\361m'\202\2565\267\275\214\021\306L]\373;x>\340\375\375{\313K\250\213\273w:6\353xg+\354\212l\240\257\357\321:\277k\230\363\252z\277 \274\354\344\274\330w\366\0170\301 \362\235\257N?\360\274\375c\222\0176q\363\325\373\300X\250\331M\353\232Z\353\303\324y\013vA\271e\336^rn\366\322\272V\254uN\353\201a\327+\377\367Hw\376\231\352\3742\251\216\263o\031\306\337m\256\323\370\226e\320\3071\347&9\203\276\247y\277\211\317O\256\264\363\3419x\351H\354\202\334\321\374\347%\\\"\326\241\236J\260#\334lTR\240\305;\007\265\217\304e_\350G\320&\313\n\035\206\252\276\200\252\212\024E\024\273\022\236\326\372f\030)\002=E\343\257\233\332\007\264\326\213D*\020\014\006\333\347\362\213#\"\346\327T\245%\037\362\226=#\375\360\303\017\322\313'\007R\312t8\362%\223\260\024\344A\256\375\354\232\311\244y\314?\2763\350\325\006,\006&\0367\354\204\245Ga\003\037P\021\373'\246\027\323\303\256\322\245\324\365|\247\360\216Y\342?N\206\330\211\245\227O\021\233\037z\266\246Y\2756\274_n\370\3611\347\"\254\rH\373.\310`\240%;\014\366B\247`\013:\211l\266G\332\266\235\372)e\036\247\334\335\212\033{\330 \337\277\366\375\352_\232\343\221\277\242\310\363\035\237\302\271-*\023-\335\037\344\272""\035\230\306\346{|\204\351\266\312\341\320|\237\317.\274\361JH\233\357\375\201\222\327C\326\264\371x\302&\3640Rt}\274\267\027K\330\242\034\357\371\346\335\033\3124u~\356\261=?\340=\227\327U\225\203B\204\244\016\021w\000}R9\367\206-Hod\010\377G\334\351\217\036\336\000EUz\360\373\030\275\305\220\177\304\217 \360\204^{\314\321\000\332\036\372\243\2079\032\300\343Jw\300<~\236\360\001\255\2635\330\20165\017\365\335\332\220\032\232o;\231p\353\003Li\251w+5M\236oD\306\336vB\277\272\224\333\353\037\nw\264y\r\376\340|\204E\034\376'\343\037/\255\376\361\233\327/_=_[[{\376z\363\345\253?~\3732N\237\236:\271V\351BU\"\221\327\271,\376\326\0221'\362\255\221u6\214\335\365uecC\336\220#\353JD\327\231\316\"\212\316\262:\313\351\262\256\3501\323\326\223\211\275\224\021\217p\305\210\360'\022P\304\261\364\224\275kZ\007\374\375^\004-I\\\350\313V\250\270\221\212\367U\364\276\r\253--\335J>\260qU\267b\373\272\235H\341\222K\305\022\246/fZf\006a\264a\353\216\236\222\365\254\236\305E\321szN\326sJ4\312\242,\033e\271H\324t\366#\002\335#\272eD\260\026[?0\"\364\231|\304\334\215\210h\222\177\277k3q\223\243f6\212\177r4\027\315\311\261\030\2131\372\215@\"{F\214\311\370\365\312\331\030\313\305d\206_\267F\226\361\353\226a\253\302D\273\377\363Zw\315j\244G\335\206\201m\261\215\016\300h<\276\326-,\205t\240Y\305W\332\033Gz\327\256\366\300\224\266\252\366Y\232\325B\246\221XR\267\355\310\236\341\320\367\321\364\210M\211$R\244@1\203\376W@,i\322w\017\311\244\013\003P\272X\203U\030E\333\303*\327C\361\t\201\370\200\240\017\250\365\0062W\215\305>\272\017\342\332\366\202\034v5\240\315\367e\322\304R\355g\276\203D\234\253\316\305z\177\231\324\017\242q\375\231\333\317\025D\257i{55\351\354\031)#\233\266b\331X.\036\367\307Y\234e\343,\0277\222\216\316/\021Y\334\224\270a%\216\224\270\031s\014\333\211g\3439\303`\006\313\032,g\310\206\2345\344\034\014\325H\333\211$\342#q[\203\266;\266\2215\262\330\256\334\256\236\000\2567\336\367\373\350}\277O\267\220\247\362\347\216\206\226\017\001:Z\032`\261K\202\217D\350\333\352H\304]""\307>&L$R6\375g\244\226%GP\333*\201\306\203\335\232EG\022\330F\317\326\351\201D\227L\374\324V\356\022\035x\"\245Kp\235\264\1772r\336\326\210\021)\203\321E\356\351\320\250\322\323F\276ON\304\275\001-\322N$r\200\\\224\256\316\376\201\236\213rr\320\023\374\276v\032\372\02290\343\231\244\201{&\351\240w\212 \207_\343<\200\003\227\216\031\375\213\271\273\313\360'c{\010\207\326\020\025\nf\30496\335JWx\021\035\216\337>\264\034\233\336+\330\307\344\352\343v\326\316\341\237\3430\207Ed\374)\216\034\211\020\344\210+T\035\031\017\324a\3372\217\0353i@]bF\003\022\204\237\340\217\364_}P<6\3057.\021\030\246[\0229\333\221\377\210\035\311G\312\221\312\237E%?\275\312f\375Y\226\225\263JV\315\256%vw\263\033\244\204\271\034\313\3119%\247\346\250.\307\353\336\016\375\354\2772r3?\231\227\363\353\247\303\267p\333\310\037\236\016\217\347\267\013\217\n\313\247\303w\362Va\262 \0276\n\250\0359\035\245\347\373\205hq\270\270R\214\226\256\225\202\345G\345\225r\2642\\Y\251\030U\271\272Y\273Z{\\\263N\356\235\254\234D\353\2577\352\033\233g \033\004\265\265\342\325\342|I.m\225'\313\n\206\014\235\366k8\033\276\231\237\315\307\nS\2306\203\211\364\323\316\212\263\341\261\3742x|\\8*\376\271\374/\225@\365~U/2,\347\351\225\221\321\267\177+00?z\267p\275\240\027\234b\2404Yb\247\243\267\362_\026\016\213C\247cS\205\027\305\351\242Z<*m\224\016O\307\356\325\357\315\225\257\226\347*""\323gT\236/OP\371\347\353W\306\247@\347Ui\250t\257\264\\\332.\317\224\327\313FE\251\350\225Lu\2556R[?\275q\277\260^\320\273&\272S\277\363\270\264^\332/\203\317\007\365\007re\272\022\2522Z.\032\247\n\313\205\315\342\235\322ay\264r\025-Z\365\032\344\266^\215\327fj\033\265\303\223\241\323\321\261\374\213\3024\3262ze\344F\376V\001\203\306\363\353\371$xf\365+\277-\263\237?\27322V\277\365\033\010\206o\310\203\30216\343zi\257\274Q>\252|_]\251\356\326\226\337B\276w\353w\371j\352\362Jm\272\006\016~\305e\364\371\300-\027\233\362\2748\t\tYX\220\302\351Z\225\311\212Z\261 \347h\355ZM\256m\237<:Y=\261\352\353\233\365\315\355\372\366w ;5\220l\213\362\\+\262\"\266\347f\376Q~5\177\214\212\253\305G\305\325\342!\364I\206\234\037\225W1\335\275\312re\235:\315\200\020)\241\002\021\037\236}0:c\030s\330\312\365f\341\032Wt\273\205\310F\311\346\n\036\303\352\345\312F\305\256NW\025H\340j\355Qm\245\026=\271v\302N\260\266\033\357K\300cF\346\033\013\345\351\267\261::M\242S^\311\353y[H\226\226\266\016\353\230,\250\005\253x\257\270\\\334,]-\315\226\242\345ke\306e0q:\374\311\333L~%o\200\301\037\320Z\270Z\230\201\036_-\316\202\303\341\322J\tFz\2333\241\360\235\221\213[\334\030h\277n\344\3577\330\273_\214\227\036\225\276./\237\336\270\235\217c\001/\033\334\216\224\327\261\272\007W\026}\264)cy\025\022\230\022\310s\253~\353\363\222^:*o\203\237L\025\312\355\332\000\251\367\023\3106P\375\0242\375\374\344\023R\311\r4\007\010\007lHf\253>1\313\315\367q9S\201\264\356\026n\026\247\211\247\211\374\027\305\t\330\324\277b\231\254\374\307*\253.W\377\355D>Y\207\321\222\212\220\314\034\262X\241nFQ+\361\305?\303\250\0310}\255\244\226h\317~?\3049yT\232\346h\370\242\362\244:Y\r\324>=\271z2-\364k\034X\265Y\030*\334+\254B\002\223E\205C'+\255\226\254\362}\250\306De\246\262Y\275Z}T]\255Z\265{\265\345\332\246;\370\031)\347=\014\337\202\3704H{\232\224\r\025\247\243\277\202\210I\257\3537?\343\020\331\243t&\372""\362\301$\373\251\342F1#\266\352\335\210p\016\316\\\005 e'\005\230\001\325\303\267\313$'G\030\027\337\376\365\242^$\361\254\014\271k\020\263A+\3523\032,\301\251\312\365\257^{.\342F\237U\022\013P\230\372l\240\022\255\016WW\352\317\334!\200gn\005\202\017R\234\027Cb\313g\353\267\t}\215\262F.\346n\3416\255\246s\273\277\205\260\227\373m4\343\n\367k,!\006\350_+\017\t,\036\317\377\201\373\025\030\334\0230\312\310l\3278\362\333\240K\233:\202y\343\334O\220\275k\325\241\352\004iL\250\020$\354.\276(=-/s'\302*kh\204\317\252\222\210\276\006\347\267@sB\220\236 q\334\307\312\206N\275\002\325L\320\023o\233\342\332\204\342'o-!&\3019\337\327\007\200\205\331B\014k\375\002\376\224\235\272\235\326\n\334\346\005B\221*\220\325=\342\312\340\216N\024\217K\200\002\227\024\330z\345\nt\232\213y\010\022\277q7\377\037\256T \206\321\374\010pG\367\340o\275\273 \366u\245a\374\244\200\207\247|\005\033\034\275V9`\361-\346\326p\017Pi\000(\267`B\354\254\223\036\341\367\204\220\tQ\374\2524\344=L`\311\321\342xi]\340\272%\204\303\315\037\020\262I\236\202\334\352st\234\346\0005R\344\020{\010\201@eOo\334\001;s\300\355\3453\010i\030\240\264\001\3377\305\325(\000\370\034\275\315\241s\2134\210\306\t\344\005ln\271\016\345\250aZ\215\312h\361\272\013\215q\300\302s(\004;\247\221\324\351\026\3714X\t\346>\033m\032\332\017\250\272\207\3361\276\247c\023. ]-\315\270.f\r\301\304\343\312\341\351\370]\216\314\204\232n/\271\025`E%\305*\254\253\253\250\3555\352\254\263\275\253\310e9\214Pn\350l\224;3<,\027\276\307\326\306J\023\234\314\325\3624\255p\205\273\016.\275[\334g\"\036\273K\332\354\355\317\243\302\n\264w\222\243-\247\n\353;\235\232-}S\301\236\336\316\037p\237\357\025\316<\323\235D(\3304d\376D\0101\0016\276\206<\377D\230\327\260r\212\"\310\240G\337fA\377\006&[B\360\371\0208D\0265\001\307|\210\020\370k\370\225uz\024}\003\360E\323\227\353\213(\226T\370S2Nx)!\321\237J\237\226oU\202U\nA\001\235\037\276\021K\237$C\272M\306\213x\364\014\246|\035eh\371_\212C""\305\t\332\032\025:>}:6.\264\222\357\317}\354\347rq\235\360\237\307\001\334\376\373\334D\270\345\0204\367}\330\202\340Y\217\212&f\220\235\014\365\250\000\003\034y\343\305\317aC/\312\263e\375<\206<\374\364\346\313@\315\364\236\017\377w\254\365\027R\223,\353xh\247\277\334\227\366E\326\373\376\263|\322p\017\303 \271\017\034\237\001f\022H\251\024v\022\230\016\235u\364\212\361\370\211\034\201\353\217\266\340\002V\001\267\274{[\305\333!\341,\270\227\271\376v\217\207\271\023^Q\247\364\364p\360\266\323m\233c>\341\024\017v\306)1!\313\020\005\027\214\304\314\300\334\311\302\347<\002i\026\032p\357\026\310\021\336q%5z\333+\334q\223\213\326\340\367\"\225\236\037&\241\005\204\0378\267\203\230Ts\203\257\214\333(\222\352\301\215\343n\322\034A\000>>Yx\202x|\017\261\361\223\312\375\212N\342\377\204\207\350FI+\013]n\333\001.\355^\333\360\241E\177\373\275\244\353\356V\273\034l\310\260w\345\031\027\312\347\365\207\277-\313\310/\236 ,\333Cz;}\332\"\016\326\020\006e\342\"\363\022g\0106\200^D\362\017\312\207\225\213t\270\225\327`Y1\004C[\245\007\360\335\323Dv\252>\265H\221a]Y\255\261\332\262gYA\370\347\365S\036\007\304\353\223\363\334\371\217>,\336F.t\310\263\265\365\262^v\020NR\216{\203\316D\276GLu(F\304\nS\365\373s\302\361>,\336\344|,\303\321\301\363\300<\301\013ez\025\275rx\326\000~\370\247\t~\364\360{\036\265O\211\034\376\206W\030\315_\023\361\330h\376*\222n/q\245@\365\223\267G\334\231s\371O\363ho\2024\306A\310\274*\\3-h\211\207\033\334\277\210x\201\"3$\226-J\342\372\036l\222\233\337\337\345\212\262\322\310\357m7nu\0253\346%\211\035\217\"-\246\360\351wHE\034$\343o\260\344\373\310#n \307zq2s\262)R\t\276\267\205\317(-&\025\342{\365\031\022\262!\nByJ\006 \372y\366\312\310\365\267[\010\257\235B\000{\367\035\262\277\243\372\342\357kC\265\3735\343D\253\277^?s\321\365\360tPa\23435\\x^\374\r\366p\004\0327[\211a&\245\032\257M\237\333<\206\034\204l\205\372\235\2155O\347(\255lB\005E[3\356\241\r\304{\241ng\"\376:\275>\232\037BL\255\223T\226\350x\253\307\332\3533K\325\351\252\306\317\300z,\221G5""\024m)y\036\017\177\217Pp\235\007u\254\177=\026D\032\354\305\207\"\010\224a\244NI\341\234\212\203\306k\374\030\305\252z\361\242\027F\"\334\354\311\372M\260.\302n(\366\351\2551RP\356\376(\3239\346'\231\317K\277&']\230\246\353\317_^\031\271\223\327=}\rx\007F\004\035{\205\357\212<\272\234nmf\302\332\364\374\221\010\245?\253\177\246\300\"_T\247\317\250L\247\177\001\260\313\255\363;\216V\303\374x\350:p\031\354?\254?\\\304\036\034\023\3766\314\260\031\252\n_\374\n\325t\260\263\315\375\253\0014\327\313\031\344\220#\325\365\002e\220>\262\326\007\302V{\334FHX_C\332\333\305\307\220\247Z\312\302\374G*\333\325Yh\325lm\377D?\311\324\267\266\317\304\204\227\353M\254\206`\344\317\371\321\316,\235z\362\203\226\313\265\362\355D\365=\367\220(\206\004\210\016g9'\342\324\204\262\035\3277L\210\361c\017\021q\335\245!vq\021\3262\214,h\004\206;^[\257\305OfOt\n\203G?\366\034\210\246\357\362\270m\033>\305=\364\272\323Y\341\255\364\245\233w\322\326\364ll\212G;\343\367\271\241\022\376Rfq\343\266{\222*\302bY\304r\302\343L\234\216M\"\027'\203\301`\230YC\254\224\003\016\227\2279\334\334\027\2079U\335%\336\360\256^\244\030+\270I\310!m\327\227\3740U\361\216*\356\025^\225n\226\247;z\337\251\337\221x>\354:B:\215\345&\364\357\"\t%\371=\245ut\315s\207\3225\212\016\332\307\375'\022\364\241\036\2434\257\303\337\260\364m\250\313\r\361.\202{j\227\213\307P\253\266j\316\005\217#\032\364\304\253\212\026/\377\200\016\"Z|\370\203B+$L\025\304\221K}\234\316i?\025\301\334\033l\311\023l\"6e\262\360k~V\314\221\365\317\020z\240\324\310\331\376\014\237?S\336\252\334\203v\331P\023!\356\237\347z\035\230u\235|\315\365;I\035\313\177\313\317\275\334\256\004\2657\363\023\371\317\021\335\030\360\334+t\000(\216n\002\000\337\307\356\321g\274$\346\377_\376\243\024\271"; + PyObject *data = __Pyx_DecompressString(cstring, 6885, 1); + if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error) + const char* const bytes = __Pyx_PyBytes_AsString(data); + #if !CYTHON_ASSUME_SAFE_MACROS + if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) } + #endif + #else /* compression: none (22843 bytes) */ +const char* const bytes = ", Approximates the arc length for a cubic Bezier segment.\n\n Uses Gauss-Lobatto quadrature with n=5 points to approximate arc length.\n See :func:`calcCubicArcLength` for a slower but more accurate result.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n\n Returns:\n Arc length value.\n\n Example::\n\n >>> approximateCubicArcLength((0, 0), (25, 100), (75, 100), (100, 0))\n 190.04332968932817\n >>> approximateCubicArcLength((0, 0), (50, 0), (100, 50), (100, 100))\n 154.8852074945903\n >>> approximateCubicArcLength((0, 0), (50, 0), (100, 0), (150, 0)) # line; exact result should be 150.\n 149.99999999999991\n >>> approximateCubicArcLength((0, 0), (50, 0), (100, 0), (-50, 0)) # cusp; exact result should be 150.\n 136.9267662156362\n >>> approximateCubicArcLength((0, 0), (50, 0), (100, -50), (-50, 0)) # cusp\n 154.80848416537057\n Calculates the arc length for a quadratic Bezier segment.\n\n Args:\n pt1: Start point of the Bezier as 2D tuple.\n pt2: Handle point of the Bezier as 2D tuple.\n pt3: End point of the Bezier as 2D tuple.\n\n Returns:\n Arc length value.\n\n Example::\n\n >>> calcQuadraticArcLength((0, 0), (0, 0), (0, 0)) # empty segment\n 0.0\n >>> calcQuadraticArcLength((0, 0), (50, 0), (80, 0)) # collinear points\n 80.0\n >>> calcQuadraticArcLength((0, 0), (0, 50), (0, 80)) # collinear points vertical\n 80.0\n >>> calcQuadraticArcLength((0, 0), (50, 20), (100, 40)) # collinear points\n 107.70329614269008\n >>> calcQuadraticArcLength((0, 0), (0, 100), (100, 0))\n 154.02976155645263\n >>> calcQuadraticArcLength((0, 0), (0, 50), (100, 0))\n 120.21581243984076\n >>> calcQuadraticArcLength((0, 0), (50, -10), (80, 50))\n 102.53273816445825\n >>> calcQuadraticArcLength((0, 0), (40, 0), (-40, 0)) # c""ollinear points, control point outside\n 66.66666666666667\n >>> calcQuadraticArcLength((0, 0), (40, 0), (0, 0)) # collinear points, looping back\n 40.0\n Calculates the bounding rectangle for a quadratic Bezier segment.\n\n Args:\n pt1: Start point of the Bezier as a 2D tuple.\n pt2: Handle point of the Bezier as a 2D tuple.\n pt3: End point of the Bezier as a 2D tuple.\n\n Returns:\n A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``.\n\n Example::\n\n >>> calcQuadraticBounds((0, 0), (50, 100), (100, 0))\n (0, 0, 100, 50.0)\n >>> calcQuadraticBounds((0, 0), (100, 0), (100, 100))\n (0.0, 0.0, 100, 100)\n Calculates the bounding rectangle for a quadratic Bezier segment.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n\n Returns:\n A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``.\n\n Example::\n\n >>> calcCubicBounds((0, 0), (25, 100), (75, 100), (100, 0))\n (0, 0, 100, 75.0)\n >>> calcCubicBounds((0, 0), (50, 0), (100, 50), (100, 100))\n (0.0, 0.0, 100, 100)\n >>> print(\"%f %f %f %f\" % calcCubicBounds((50, 0), (0, 100), (100, 100), (50, 0)))\n 35.566243 0.000000 64.433757 75.000000\n Couldn't work out which intersection function to useFinds intersections between a curve and a line.\n\n Args:\n curve: List of coordinates of the curve segment as 2D tuples.\n line: List of coordinates of the line segment as 2D tuples.\n\n Returns:\n A list of ``Intersection`` objects, each object having ``pt``, ``t1``\n and ``t2`` attributes containing the intersection point, time on first\n segment and time on second segment respectively.\n\n Examples::\n >>> curve = [ (100, 240), (30, 60), (210, 230), (160, 30) ]\n >>> line = [ (25, 260), (230, 20) ]\n >>> intersections"" = curveLineIntersections(curve, line)\n >>> len(intersections)\n 3\n >>> intersections[0].pt\n (84.9000930760723, 189.87306176459828)\n Finds intersections between a curve and a curve.\n\n Args:\n curve1: List of coordinates of the first curve segment as 2D tuples.\n curve2: List of coordinates of the second curve segment as 2D tuples.\n\n Returns:\n A list of ``Intersection`` objects, each object having ``pt``, ``t1``\n and ``t2`` attributes containing the intersection point, time on first\n segment and time on second segment respectively.\n\n Examples::\n >>> curve1 = [ (10,100), (90,30), (40,140), (220,220) ]\n >>> curve2 = [ (5,150), (180,20), (80,250), (210,190) ]\n >>> intersections = curveCurveIntersections(curve1, curve2)\n >>> len(intersections)\n 3\n >>> intersections[0].pt\n (81.7831487395506, 109.88904552375288)\n Finds intersections between two line segments.\n\n Args:\n s1, e1: Coordinates of the first line as 2D tuples.\n s2, e2: Coordinates of the second line as 2D tuples.\n\n Returns:\n A list of ``Intersection`` objects, each object having ``pt``, ``t1``\n and ``t2`` attributes containing the intersection point, time on first\n segment and time on second segment respectively.\n\n Examples::\n\n >>> a = lineLineIntersections( (310,389), (453, 222), (289, 251), (447, 367))\n >>> len(a)\n 1\n >>> intersection = a[0]\n >>> intersection.pt\n (374.44882952482897, 313.73458370177315)\n >>> (intersection.t1, intersection.t2)\n (0.45069111555824465, 0.5408153767394238)\n Finds intersections between two segments.\n\n Args:\n seg1: List of coordinates of the first segment as 2D tuples.\n seg2: List of coordinates of the second segment as 2D tuples.\n\n Returns:\n A list of ``Intersection`` objects, each ob""ject having ``pt``, ``t1``\n and ``t2`` attributes containing the intersection point, time on first\n segment and time on second segment respectively.\n\n Examples::\n >>> curve1 = [ (10,100), (90,30), (40,140), (220,220) ]\n >>> curve2 = [ (5,150), (180,20), (80,250), (210,190) ]\n >>> intersections = segmentSegmentIntersections(curve1, curve2)\n >>> len(intersections)\n 3\n >>> intersections[0].pt\n (81.7831487395506, 109.88904552375288)\n >>> curve3 = [ (100, 240), (30, 60), (210, 230), (160, 30) ]\n >>> line = [ (25, 260), (230, 20) ]\n >>> intersections = segmentSegmentIntersections(curve3, line)\n >>> len(intersections)\n 3\n >>> intersections[0].pt\n (84.9000930760723, 189.87306176459828)\n\n Lib/fontTools/misc/bezierTools.pySolve a cubic equation.\n\n Solves *a*x*x*x + b*x*x + c*x + d = 0* where a, b, c and d are real.\n\n Args:\n a: coefficient of *x\302\263*\n b: coefficient of *x\302\262*\n c: coefficient of *x*\n d: constant term\n\n Returns:\n A list of roots. Note that the returned list is neither guaranteed to\n be sorted nor to contain unique values!\n\n Examples::\n\n >>> solveCubic(1, 1, -6, 0)\n [-3.0, -0.0, 2.0]\n >>> solveCubic(-10.0, -9.0, 48.0, -29.0)\n [-2.9, 1.0, 1.0]\n >>> solveCubic(-9.875, -9.0, 47.625, -28.75)\n [-2.911392, 1.0, 1.0]\n >>> solveCubic(1.0, -4.5, 6.75, -3.375)\n [1.5, 1.5, 1.5]\n >>> solveCubic(-12.0, 18.0, -9.0, 1.50023651123)\n [0.5, 0.5, 0.5]\n >>> solveCubic(\n ... 9.0, 0.0, 0.0, -7.62939453125e-05\n ... ) == [-0.0, -0.0, -0.0]\n True\n Split a cubic Bezier curve at a given coordinate.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n where: Position at which to split the curve.\n isHorizontal: Dire""ction of the ray splitting the curve. If true,\n ``where`` is interpreted as a Y coordinate; if false, then\n ``where`` is interpreted as an X coordinate.\n\n Returns:\n A list of two curve segments (each curve segment being four 2D tuples)\n if the curve was successfully split, or a list containing the original\n curve.\n\n Example::\n\n >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 150, False))\n ((0, 0), (25, 100), (75, 100), (100, 0))\n >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 50, False))\n ((0, 0), (12.5, 50), (31.25, 75), (50, 75))\n ((50, 75), (68.75, 75), (87.5, 50), (100, 0))\n >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 25, True))\n ((0, 0), (2.29379, 9.17517), (4.79804, 17.5085), (7.47414, 25))\n ((7.47414, 25), (31.2886, 91.6667), (68.7114, 91.6667), (92.5259, 25))\n ((92.5259, 25), (95.202, 17.5085), (97.7062, 9.17517), (100, 1.77636e-15))\n Split a cubic Bezier curve at one or more values of t.\n\n Args:\n pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples.\n *ts: Positions at which to split the curve.\n\n Returns:\n A list of curve segments (each curve segment being four 2D tuples).\n\n Examples::\n\n >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5))\n ((0, 0), (12.5, 50), (31.25, 75), (50, 75))\n ((50, 75), (68.75, 75), (87.5, 50), (100, 0))\n >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5, 0.75))\n ((0, 0), (12.5, 50), (31.25, 75), (50, 75))\n ((50, 75), (59.375, 75), (68.75, 68.75), (77.3438, 56.25))\n ((77.3438, 56.25), (85.9375, 43.75), (93.75, 25), (100, 0))\n Split a line at a given coordinate.\n\n Args:\n pt1: Start point of line as 2D tuple.\n pt2: End point of line as 2D tuple.\n where:"" Position at which to split the line.\n isHorizontal: Direction of the ray splitting the line. If true,\n ``where`` is interpreted as a Y coordinate; if false, then\n ``where`` is interpreted as an X coordinate.\n\n Returns:\n A list of two line segments (each line segment being two 2D tuples)\n if the line was successfully split, or a list containing the original\n line.\n\n Example::\n\n >>> printSegments(splitLine((0, 0), (100, 100), 50, True))\n ((0, 0), (50, 50))\n ((50, 50), (100, 100))\n >>> printSegments(splitLine((0, 0), (100, 100), 100, True))\n ((0, 0), (100, 100))\n >>> printSegments(splitLine((0, 0), (100, 100), 0, True))\n ((0, 0), (0, 0))\n ((0, 0), (100, 100))\n >>> printSegments(splitLine((0, 0), (100, 100), 0, False))\n ((0, 0), (0, 0))\n ((0, 0), (100, 100))\n >>> printSegments(splitLine((100, 0), (0, 0), 50, False))\n ((100, 0), (50, 0))\n ((50, 0), (0, 0))\n >>> printSegments(splitLine((0, 100), (0, 0), 50, True))\n ((0, 100), (0, 50))\n ((0, 50), (0, 0))\n Split a quadratic Bezier curve at a given coordinate.\n\n Args:\n pt1,pt2,pt3: Control points of the Bezier as 2D tuples.\n where: Position at which to split the curve.\n isHorizontal: Direction of the ray splitting the curve. If true,\n ``where`` is interpreted as a Y coordinate; if false, then\n ``where`` is interpreted as an X coordinate.\n\n Returns:\n A list of two curve segments (each curve segment being three 2D tuples)\n if the curve was successfully split, or a list containing the original\n curve.\n\n Example::\n\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 150, False))\n ((0, 0), (50, 100), (100, 0))\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, False))\n ((0, 0), (25"", 50), (50, 50))\n ((50, 50), (75, 50), (100, 0))\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, False))\n ((0, 0), (12.5, 25), (25, 37.5))\n ((25, 37.5), (62.5, 75), (100, 0))\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, True))\n ((0, 0), (7.32233, 14.6447), (14.6447, 25))\n ((14.6447, 25), (50, 75), (85.3553, 25))\n ((85.3553, 25), (92.6777, 14.6447), (100, -7.10543e-15))\n >>> # XXX I'm not at all sure if the following behavior is desirable:\n >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, True))\n ((0, 0), (25, 50), (50, 50))\n ((50, 50), (50, 50), (50, 50))\n ((50, 50), (75, 50), (100, 0))\n Split a quadratic Bezier curve at one or more values of t.\n\n Args:\n pt1,pt2,pt3: Control points of the Bezier as 2D tuples.\n *ts: Positions at which to split the curve.\n\n Returns:\n A list of curve segments (each curve segment being three 2D tuples).\n\n Examples::\n\n >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5))\n ((0, 0), (25, 50), (50, 50))\n ((50, 50), (75, 50), (100, 0))\n >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5, 0.75))\n ((0, 0), (25, 50), (50, 50))\n ((50, 50), (62.5, 50), (75, 37.5))\n ((75, 37.5), (87.5, 25), (100, 0))\n Unknown curve degree.?approximateCubicArcLength (line 332)calcCubicBounds (line 412)calcQuadraticArcLength (line 151)calcQuadraticBounds (line 298)curveCurveIntersections (line 1385)curveLineIntersections (line 1255)disableenable%ggcisenabledlineLineIntersections (line 1154)(%s)segmentSegmentIntersections (line 1427)\n >>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]])\n '(1, (2, 3), (), ((2, (3, 4), (0.1, 2.2))))'\n _segmentrepr (line 1475)solveCubic (line 848)splitCubicAtT (line 613)splitCubic (line 552)splitLine (line 450)splitQuadr""aticAtT (line 589)splitQuadratic (line 507)_1_t_1_t_2_2_t_1_tCOMPILEDDDEPSILONIdentityIntersectionLen__Pyx_PyDict_NextRefQQ3RR2R2_Q3_aa1a1_3a1xa1ya2a3acosaligned_curve_alignment_transformation__all__angleappendapproximateCubicArcLengthapproximateCubicArcLengthCapproximateQuadraticArcLengthapproximateQuadraticArcLengthCarchasinhasyncio.coroutinesatan2axax2ax3ayay2ay3bb1b1xb1y_both_points_are_on_same_side_of_originbounds1bounds2boxbxbx2byby2cc1c11c11_rangec12c12_rangec1xc1yc21c21_rangec22c22_rangecalcBoundscalcCubicArcLengthcalcCubicArcLengthC_calcCubicArcLengthCRecursecalcCubicBoundscalcCubicParameterscalcCubicPointscalcQuadraticArcLengthcalcQuadraticArcLengthCcalcQuadraticBoundscalcQuadraticParameterscalcQuadraticPoints__class_getitem__cline_in_tracebackclosecollectionscoscubicPointAtTcubicPointAtTCcurvecurve1curve2curveCurveIntersectionscurveLineIntersections_curve_bounds_curve_curve_intersections_t_curve_curve_intersections_t..midpoint_curve_curve_intersections_t.._curve_line_intersections_t_curve_line_intersections_t..genexprcxcydd0d1d1xd1ydeltadelta_2delta_3deriv3doctestdxdyee1e1xe1ye2e2xe2yendepsilonepsilonDigitsexexiteyfailedfontTools.misc.arrayToolsfontTools.misc.bezierToolsfontTools.misc.transformfound__func__genexprhitsiinsertintersection_tsintersectionsintersectsisHorizontal_is_coroutine_is_linelike_is_linelike..genexpriscloseititemskeylineline1line2lineLineIntersectionslinePointAtTline_t_line_t_of_pt__main__mathmaybelinemidmidPtmidpoint__module__multn__name__namedtuplenextobjoff1off2oneorigDistoriginpp0p1p2p3pipointAtTpointFinderpointspopprecisionprintprintSegmentsptpt1pt1xpt1ypt2pt2xpt2ypt3pt4pxpyquadraticPointAtT__qualname__rrDDrQ2range1range2rectArearootsrotateroundss1s1xs1ys2s2xs2yscalesectRectseensegseg1seg2segmentsegmentPointAtTsegmentSegmentIntersections_segmentrepr_segmentrepr..genexprsegmentssend__set_name__setdefaultslope12slope34solutionssolveCubicsolveQuadraticsplitsplitCubic_splitCubicAt""TsplitCubicAtTC_splitCubicAtTCsplitCubicAtTsplitCubicIntoTwoAtTCsplitCubic..genexprsplitLinesplitQuadratic_splitQuadraticAtTsplitQuadraticAtTsplitQuadratic..genexpr_split_cubic_into_two_split_segment_at_tsqrtstartswappedsxsysystt1t1_2t1_3t2__test__testmodthetathrowtolerancetransformPointstranslatetstwounique_keyunique_valuesv0v1v2v3v4valuevalueswherexx0x1x2x3x4xDiffxRootsyy1y2y3y4yDiffyRoots\200\001\3600\000\005\n\210\022\2102\210Q\330\004\013\2102\210R\210q\330\004\r\210U\220\"\220A\330\004\017\210r\220\022\2202\220R\220q\330\004\005\330\010\017\210r\220\025\220b\230\004\230B\230b\240\003\2407\250\"\250B\250b\260\004\260B\260e\2702\270S\300\002\300%\300r\310\023\310B\310b\320PR\320RS\340\004\013\2107\220\"\220D\230\002\230)\2402\240T\250\022\2503\250b\260\001\330\004\013\2107\220\"\220D\230\002\230)\2402\240T\250\022\2503\250b\260\001\340\004\n\210$\210c\220\024\220R\220u\230B\230a\330\004\n\210$\210c\220\024\220R\220u\230B\230a\340\004\014\210A\210U\220%\220v\230\\\250\032\2606\270\025\270a\2301\200\001\360*\000\005\010\200|\2201\220A\330\010\020\220\006\220a\220t\2306\240\022\2401\330\010\013\210<\220q\230\001\330\014\024\220F\230!\2304\230v\240R\240q\330\014\023\320\023(\250\002\250(\260!\340\014\023\320\023)\250\021\250(\260!\360\006\000\r\024\2201\220L\240\001\240\023\240A\240U\250#\250Q\250e\2603\260a\260u\270D\300\005\300Q\330\t\025\220Q\220a\330\010\020\220\006\220a\220t\2306\240\022\2401\330\010\017\320\017%\240Q\240h\250a\340\004\026\320\0262\260!\2608\2701\330\004\013\2101\330\010\024\220A\220S\230\017\240q\250\010\260\002\260!\2605\270\003\2702\270Q\270d\300#\300R\300q\310\001\330\010\014\210F\220!\200\001\360\010\000\005\t\210\013\2201\330\010\r\210Q\210l\230!\2301\320\000+\2501\360\034\000\005\014\320\013\036\230a\330\010\017\210r\220\026\220w\230b\240\006\240g\250R\250v\260W\270B\270f\300A\200\001\330\004\020\320\020)\250\021\250(\3202B\300!\3001\330\004\033\2301\200\001\360&\000\005\n\210\022\2102\210Q\330\004\013\2102\210R\210q\330""\004\r\210U\220\"\220A\330\004\013\2107\220\"\220E\230\022\2304\230r\240\022\2403\240g\250R\250r\260\022\2604\260r\270\025\270b\300\003\3002\300U\310\"\310C\310r\320QS\320SU\320UV\200\001\360\024\000\005\n\210\022\2102\210Q\330\004\013\2102\210R\210q\330\004\r\210U\220\"\220A\330\004\005\330\010\017\210r\220\025\220b\230\003\2301\230A\330\010\n\210\"\210C\210w\220b\230\002\230\"\230C\230q\240\003\2402\240U\250\"\250C\250r\260\023\260A\260Q\330\010\n\210#\210R\210r\220\022\2203\220a\220q\340\004\005\330\010\017\210r\220\025\220b\230\003\2301\230A\330\010\n\210\"\210C\210w\220b\230\002\230\"\230C\230q\240\003\2402\240U\250\"\250C\250r\260\023\260A\260Q\330\010\n\210#\210R\210r\220\022\2203\220a\220q\340\004\014\210C\210q\200\001\360\024\000\005\n\210\022\2102\210S\220\003\2202\220R\220s\230\"\230C\230q\240\003\2402\240R\240s\250\"\250B\250c\260\022\2602\260R\260s\270!\2703\270b\300\002\300\"\300B\300b\310\003\3101\310A\330\004\t\210\022\2102\210S\220\003\2202\220R\220s\230\"\230C\230q\240\003\2402\240R\240s\250\"\250B\250c\260\022\2602\260R\260s\270!\2703\270b\300\002\300\"\300B\300b\310\003\3101\310A\330\004\014\210C\210q\200\001\3602\000\005\014\320\013%\240Q\330\010\017\210r\220\026\220w\230b\240\006\240g\250R\250v\260W\270B\270a\200\001\360\022\000\005\014\2103\210a\210s\220\"\220A\330\004\n\210#\210Q\210c\220\022\2204\220r\230\023\230A\230S\240\002\240$\240b\250\003\2501\250C\250r\260\021\330\004\007\200u\210B\210e\2202\220X\230S\240\001\330\010\020\220\005\220R\220u\230B\230a\340\010\r\210V\320\023(\250\001\250\024\250T\260\024\260Q\330\010\017\320\017*\250!\2507\260%\260r\3209T\320TU\330\014\023\2201\200\001\330\004\013\2103\210b\220\002\220#\220S\230\002\230$\230b\240\004\240B\240a\330\004\016\210c\220\022\2203\220b\230\003\2302\230T\240\022\2401\330\004\005\330\010\t\210\025\210c\220\022\2204\220r\230\025\230d\240\"\240H\250A\330\t\016\210d\220\"\220I\230S\240\002\240$\240b\250\005\250Q\200\001\360\026\000-.\360\024\000\005\014\2104\210r\220\024\220R\220q""\330\004\013\320\013&\240a\240v\250U\260%\260u\270A\200\001\360\034\000\005\014\320\013)\250\021\250'\260\022\2606\270\027\300\002\300&\310\007\310r\320QR\200\001\3606\000\005\010\200s\210#\210T\320\021$\240A\240U\250%\250u\260A\330\004\020\220\n\230!\330\010\t\210\021\210/\230\021\230!\230?\250!\2501\250O\2701\270A\270^\3102\310Q\340\004\026\220a\220q\330\004\007\200t\2101\330\010\017\210r\220\025\220e\2305\240\001\330\004\013\210>\230\021\230#\230S\240\003\2404\240q\200\001\360@\001\000\005\014\320\013\"\240!\2407\250\"\250F\260'\270\022\2706\300\027\310\002\310!\200\001\360\024\000\005\r\210A\210S\220\001\220\023\220C\220r\230\022\2303\230b\240\003\2401\240C\240r\250\025\250c\260\021\260#\260S\270\002\270\"\270C\270r\300\023\300A\300S\310\002\310!\200\001\360>\000\005\n\210\023\210A\210T\220\022\2205\230\002\230!\330\004\t\210\023\210A\330\010\033\2302\230Q\330\010\n\320\n\034\230B\230a\330\010\n\320\n\034\230B\230a\330\010\n\320\n\034\230B\230a\340\004\t\210\023\210A\210T\220\022\2204\220r\230\024\230R\230u\240B\240a\330\004\t\210\023\210A\330\010\033\2302\230Q\330\010\n\320\n\034\230B\230a\330\010\n\320\n\034\230B\230a\330\010\n\320\n\034\230B\230a\340\004\t\210\023\210A\210T\220\022\2205\230\002\230!\340\004\013\2103\210b\220\003\2202\220S\230\002\230#\230R\230q\200A\330\010\017\210t\2203\220a\220q\230\003\2302\230Q\230a\230q\200\001\360B\001\000\005\n\210\023\210A\330\010\033\2302\230T\240\022\320#5\260R\260t\2702\320=P\320PR\320RS\340\004\t\210\023\210A\210T\220\022\2205\230\002\230!\330\004\t\210\023\210A\330\010\034\230B\230d\240\"\320$6\260b\270\004\270B\320>P\320PR\320RS\360\006\000\005\014\2103\210b\220\003\2202\220Q\200\001\360F\001\000\005\010\200s\210$\320\016%\240Q\240e\2505\260\001\330\004\020\220\016\230a\330\010\t\210\021\210/\230\021\230!\230?\250!\2501\250N\270\"\270A\340\004\026\220a\220q\330\004\007\200t\2101\330\010\017\210r\220\025\220e\2301\330\004\013\320\013\035\230Q\230c\240\023\240D\250\001\200\001\360\010\000\005\r\210G\2201\220A\330""\004\n\210'\220\022\2201\330\004\014\210D\220\006\220a\220s\230!\2303\230b\240\005\240Q\240d\250#\250Q\250c\260\022\2605\270\001\270\021\330\004\013\2108\2207\230!\2301\230F\240*\250A\250Q\250e\2601\260D\270\001\270\025\270a\270q\200\001\360H\001\000\005\013\210'\220\021\330\004\n\210'\220\021\340\004\t\210\025\210b\220\001\330\004\t\210\025\210b\220\001\340\004\t\210\021\330\004\t\210\021\340\004\t\210\024\210S\220\001\220\021\340\004\007\200r\210\023\210A\330\010\017\210r\220\025\220a\330\004\t\210\026\210s\220$\220c\230\021\230/\250\022\2501\330\004\007\200r\210\023\210D\220\001\330\010\020\220\003\2202\220R\220r\230\024\230S\240\002\240\"\240B\240a\330\010\017\210r\220\025\220i\230w\240a\340\010\017\210r\220\025\220a\200\001\360L\001\000\005\010\200s\210!\2103\210b\220\001\360\006\000\t\020\210~\230Q\230c\240\023\240A\330\004\010\210\005\210Q\210a\330\004\t\210\022\2102\210Q\330\004\t\210\022\2102\210Q\330\004\t\210\022\2102\210Q\340\004\t\210\023\210B\210c\220\022\2204\220r\230\024\230R\230q\330\004\t\210\024\210R\210s\220\"\220C\220r\230\023\230B\230d\240\"\240C\240r\250\023\250B\250e\2602\260T\270\022\2701\340\004\t\210\022\2102\210Q\330\004\t\210\022\2102\210R\210r\220\021\330\004\t\210\025\210c\220\022\220=\240\001\330\004\t\210\025\210c\220\021\220$\220b\230\r\240Q\340\004\014\210C\210r\220\021\340\004\007\200s\210#\210T\220\024\220S\230\003\2301\330\010\014\210E\220\021\220!\2203\220b\230\005\230Q\330\010\017\210q\220\003\2203\220a\330\t\017\210s\220(\230\"\230A\340\010\020\220\004\220I\230R\230r\240\024\240Q\240e\2506\260\021\330\010\016\210e\2202\220T\230\021\230!\330\010\017\210s\220\"\220A\330\010\r\210T\220\022\2203\220a\220v\230R\230u\240B\240a\330\010\r\210T\220\022\2203\220b\230\006\230b\240\004\240B\240d\250\"\250E\260\022\2601\330\010\r\210T\220\022\2203\220b\230\006\230b\240\004\240B\240d\250\"\250E\260\022\2601\330\010\014\210D\220\013\2301\230A\230T\240\024\240Q\340\010\013\2103\210b\220\003\2202\220X\230T\240\023\240B\240c\250\022\2501\330""\014\021\220\025\220e\2305\240\002\240#\240R\240s\250\"\250D\260\002\260%\260q\330\r\020\220\002\220#\220R\220q\330\014\021\220\025\220e\2302\230S\240\002\240$\240b\250\005\250Q\330\014\021\220\025\220a\220t\2301\330\r\020\220\002\220#\220R\220q\330\014\021\220\025\220a\220t\2301\330\014\021\220\025\220e\2302\230S\240\002\240$\240b\250\005\250Q\340\014\021\220\025\220a\220t\2301\330\014\021\220\025\220a\220t\2301\330\014\021\220\025\220a\220t\2301\330\010\017\210q\220\004\220D\230\001\340\010\014\210C\210q\220\004\220A\220W\230B\230c\240\021\240$\240b\250\002\250!\330\010\014\210B\210b\220\002\220\"\220A\330\010\013\2102\210S\220\001\330\014\020\220\001\220\021\330\010\014\210E\220\021\220\"\220B\220c\230\022\2305\240\001\330\010\017\210q\220\001\200\001\330\024$\240M\260\021\340\004\016\210m\2301\230A\330\004\016\210m\2301\230A\340\004\007\200t\2101\330\010\022\220%\220q\330\004\007\200t\2101\330\010\022\220%\220q\360\006\000\005\021\220\004\220H\230A\230Y\240a\330\004\007\200t\2101\330\010\017\210q\340\004\005\360\010\000\005\010\200x\210q\220\t\230\022\230:\240T\250\030\260\021\260)\2702\270Q\330\010\017\210r\220\030\230\021\230)\2408\2501\250A\340\004\t\210\026\320\017\"\240!\2408\2501\330\004\021\220\026\220q\230\004\230H\240A\240Q\330\004\021\220\030\230\021\230)\2406\250\021\250!\340\004\t\210\026\320\017\"\240!\2408\2501\330\004\021\220\026\220q\230\004\230H\240A\240Q\330\004\021\220\030\230\021\230)\2406\250\021\250!\340\004\014\210A\330\004\t\210\027\220\001\330\010$\240A\330\014\021\220\025\220k\240\027\250\013\2607\270!\360\006\000\005\n\210\027\220\001\330\010$\240A\330\014\021\220\025\220k\240\027\250\013\2607\270!\360\006\000\005\n\210\027\220\001\330\010$\240A\330\014\021\220\025\220k\240\027\250\013\2607\270!\360\006\000\005\n\210\027\220\001\330\010$\240A\330\014\021\220\025\220k\240\027\250\013\2607\270!\360\010\000\005\022\220\021\330\004\016\210a\330\004\024\220A\340\004\010\210\006\210a\330\010\016\210j\230\001\230\021\330\010\013\2104\210s""\220!\330\014\r\330\010\014\210D\220\001\220\021\330\010\025\220W\230A\230Q\340\004\013\2101\200\001\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\n\210#\210R\210t\2202\220Q\330\004\n\210#\210R\210t\2202\220Q\330\004\n\210#\210R\210t\2202\220T\230\022\2301\330\004\n\210#\210R\210t\2202\220T\230\022\2301\330\004\t\210\023\210B\210c\220\022\2203\220b\230\001\330\004\t\210\023\210B\210c\220\022\2203\220b\230\001\330\004\013\2101\210D\220\006\220d\230&\240\004\240F\250$\250a\200\001\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\t\210\021\330\004\t\210\021\330\004\n\210#\210R\210u\220B\220a\330\004\n\210#\210R\210u\220B\220a\330\004\n\210#\210R\210t\2202\220T\230\022\2301\330\004\n\210#\210R\210t\2202\220T\230\022\2301\330\004\t\210\023\210B\210c\220\022\2203\220b\230\001\330\004\t\210\023\210B\210c\220\022\2203\220b\230\001\330\004\013\2101\210D\220\006\220d\230&\240\004\240F\250$\250a\200\001\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\n\210#\210R\210t\2202\220Q\330\004\n\210#\210R\210t\2202\220Q\330\004\t\210\023\210B\210c\220\022\2201\330\004\t\210\023\210B\210c\220\022\2201\330\004\013\2101\210D\220\006\220d\230&\240\004\240A\200\001\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\t\210\021\330\004\t\210\021\330\004\n\210#\210R\210u\220B\220a\330\004\n\210#\210R\210u\220B\220a\330\004\t\210\023\210B\210c\220\022\2201\330\004\t\210\023\210B\210c\220\022\2201\330\004\013\2101\210D\220\006\220d\230&\240\004\240A\200\001\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\007\200s\210!\2103\210b\220\004\220B\220h\230d\240#\240Q\240c\250\022\2504\250r\260\021\340\010\020\220\001\340\004\007\200s\210!\2103\210b\220\004\220B\220c\230\021\230#\230R\230q\330\010\020\220\003\2202\220T\230\023\230C\230r\240\021\340\010\020\220\003\2202\220T\230\023""\230C\230r\240\021\200\001\330\004\t\210\024\210Q\210a\330\004\006\200g\210Q\210c\220\021\330\004\006\200g\210Q\210a\330\004\017\210q\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\010\210\005\210U\220!\2203\220a\220t\2302\230Q\330\010\r\210R\210q\220\001\330\010\r\210R\210q\220\002\220\"\220A\330\010\020\220\003\2202\220Q\340\010\022\220&\230\002\230!\330\010\022\220&\230\002\230!\330\010\017\210s\220\"\220A\330\010\017\210s\220\"\220A\360\006\000\t\017\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\017\210r\220\022\2203\220b\230\003\2302\230T\240\022\2401\330\010\017\210r\220\022\2203\220b\230\003\2302\230T\240\022\2401\330\010\017\210r\220\022\2203\220b\230\003\2302\230S\240\002\240\"\240B\240c\250\022\2506\260\022\2601\330\010\017\210r\220\022\2203\220b\230\003\2302\230S\240\002\240\"\240B\240c\250\022\2506\260\022\2601\330\010\016\210c\220\022\2205\230\002\230#\230R\230u\240B\240c\250\022\2503\250b\260\001\330\010\016\210c\220\022\2205\230\002\230#\230R\230u\240B\240c\250\022\2503\250b\260\001\330\010\r\210U\220%\220v\230_\250A\330\r\022\220'\230\025\230g\240U\250'\260\025\260a\340\010\020\220\007\220r\230\025\230e\2405\250\001\330\004\013\2101\200\001\330\004\t\210\024\210Q\210a\330\004\017\210q\330\004\006\200g\210Q\210c\220\021\330\004\006\200g\210Q\210a\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\010\210\005\210Q\330\004\010\210\005\210U\220!\2203\220a\220t\2302\230Q\330\010\r\210R\210q\220\001\330\010\r\210R\210q\220\002\220\"\220A\330\010\020\220\003\2202\220Q\340\010\022\220&\230\002\230!\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\017\210r\220\022\2203\220b\230\003\2302\230T\240\022\2401\330\010\017\210r\220\022\2203\220b\230\003\2302\230T\240\022\2401\330\010\017\210s\220\"\220A\330\010\016\210c\220\022\2205\230\002\230#\230R\230s\240\"\240A\330\010\016\210c\220\022\2205\230\002\230#\230R\230s\240\"\240A\340\010\r\210U\220&\320\030+\2502\250U""\260'\270\025\270g\300U\310!\330\010\020\220\007\220r\230\025\230e\2401\330\004\013\2101\200\001\330\004\r\210Q\210a\210s\220\"\220F\230!\2304\230s\240!\2401\240C\240r\250\026\250q\260\001\330\004\r\210Q\210a\210s\220\"\220F\230!\2304\230s\240!\2401\240C\240r\250\026\250q\260\001\330\004\013\2105\220\006\220c\230\024\230T\240\026\240s\250!\200\001\330\004\024\320\024-\250Q\250e\3203C\3001\300A\330\004\007\200s\210!\2107\220#\220Q\330\010\013\2103\210d\320\022)\250\022\2501\330\010\030\230\016\240a\240q\250\001\250\024\250Q\250a\250t\2601\260A\260Q\330\t\014\210A\210W\220C\220q\330\010\013\2103\210c\220\024\320\025(\250\002\250!\330\010\030\230\n\240!\2401\240A\240T\250\021\250!\2504\250q\260\001\260\024\260Q\260a\260q\340\010\016\210j\230\001\230\021\330\004\021\220\021\220!\200\001\360@\001\000\005\n\210\024\210R\210q\330\004\t\210\024\210R\210q\330\004\010\210\003\2102\210Q\330\004\010\210\002\210\"\210A\330\004\014\210C\210q\220\001\330\004\007\200v\210S\220\001\330\010\017\210s\220!\2204\220r\230\021\330\004\017\210t\2201\220C\220q\330\004\007\200s\210!\210:\220R\220q\330\010\013\2104\210q\220\004\220D\230\003\2301\330\014\023\2203\220a\220t\2302\230Q\330\010\013\2104\210s\220!\2205\230\003\2301\230A\330\010\020\220\002\220\"\220B\220b\230\002\230\"\230C\230s\240\"\240B\240a\330\004\t\210\024\210Q\210c\220\024\220R\220q\330\004\t\210\024\210Q\210c\220\024\220R\220q\330\004\n\210#\210Q\210b\220\003\220;\230a\230t\2402\240[\260\001\260\025\260b\270\t\300\023\300F\310#\310S\320PR\320RS\330\004\013\2101\220\034\230S\240\001\240\022\2401\240C\240r\250\034\260S\270\001\270\022\2701\270C\270r\300\021\200\001\360$\000\005\006\200T\210\026\210t\2206\230\024\230V\2404\240v\320-@\300\001\300\025\300e\3105\320PQ\340\004\n\210#\210R\210q\330\004\n\210#\210R\210q\330\004\n\210#\210R\210q\330\004\n\210#\210R\210q\330\004\r\210Q\210b\220\004\220E\230\036\240q\250\005\250U\260$\260c\270\022\2703\270d\300!\330\004\r\210Q\210b\220\004\220E\230\036\240q\250\005\250U\260$\260c\270""\022\2703\270d\300!\330\004\014\210G\2202\220Q\340\004\r\210Q\340\014\017\210r\220\022\2202\220R\220r\230\022\2302\230S\240\002\240\"\240B\240b\250\002\250#\250R\250r\260\022\2601\330\014\017\210r\220\022\2202\220R\220r\230\022\2302\230S\240\002\240\"\240B\240b\250\002\250#\250R\250r\260\022\2601\340\010\014\210E\220\021\330\006\010\210\001\210\025\210a\330\004\013\210:\220Q\220a\200\001\360$\000\005\006\200T\210\026\210t\2206\230\024\230V\320#:\270!\2705\300\005\300Q\330\004\n\210#\210R\210q\330\004\n\210#\210R\210q\330\004\014\210A\330\004\007\200t\2103\210a\330\010\r\210W\220A\220Q\220c\230\022\2301\330\004\007\200t\2103\210a\330\010\r\210W\220A\220Q\220c\230\022\2301\330\004\r\210Q\330\t\014\210B\210b\220\002\220\"\220B\220c\230\022\2302\230R\230t\2403\240b\250\002\250\"\250B\250b\260\003\2602\260R\260r\270\021\330\010\014\210E\220\021\330\010\013\2102\210S\220\004\220A\330\006\010\210\001\210\025\210a\330\004\013\210:\220Q\220a\200\001\360\n\000\005\006\330\010\r\210T\220\021\220!\330\013\014\330\010\017\210u\220B\220a\340\010\017\210w\220b\230\004\230E\240\035\250a\200\001\220!\250a\200\001\360<\000\005\017\210a\330\004\007\200s\210!\2106\220\022\2203\220a\220q\330\010\016\210g\220V\2301\330\010\022\220!\330\004\007\200s\210!\2106\220\022\2201\330\010\013\2103\210a\210v\220R\220q\330\014\034\320\0343\2601\260F\270!\340\014\034\320\0342\260!\2606\270\021\330\t\014\210A\210V\2203\220b\230\004\230C\230q\240\006\240c\250\021\330\010\030\320\030-\250R\250w\260a\340\010\016\210j\230\001\230\021\330\004\007\200t\2101\330\010\017\210q\330\004\013\2101\210L\230\001\230\023\230A\230U\240#\240Q\240e\2503\250a\250u\260D\270\005\270Q\220q\200\001\360.\000\005\n\210\026\210q\330\004\t\210\026\210q\330\004\t\210\026\210q\330\004\t\210\026\210q\330\004\005\330\010\014\210H\220A\220U\230%\230t\2404\240x\250q\260\005\260U\270$\270d\300$\300h\310a\310u\320TU\340\010\017\210q\330\004\005\330\010\014\210H\220A\220U\230%\230t\2404\240x\250q\260\005\260U\270$\270d\300$\300h\310a""\310u\320TU\340\010\017\210q\330\004\007\200t\2108\2201\220E\230\025\230d\240$\240h\250a\250u\260A\330\010\017\210q\330\004\007\200t\2108\2201\220E\230\025\230d\240$\240h\250a\250u\260A\330\010\017\210q\330\004\007\200t\2108\2201\220E\230\021\330\010\014\210A\330\010\023\2204\220r\230\025\230c\240\024\240R\240q\330\010\014\210H\220C\220r\230\022\2305\240\002\240!\330\010\016\210c\220\021\330\010\017\210q\330\014\030\230\001\330\020\023\2204\220s\230-\240q\250\004\250D\260\005\260S\270\r\300Q\300d\310$\310a\360\006\000\005\010\200t\2108\2201\220E\230\021\330\010\014\210A\330\010\023\2204\220r\230\025\230c\240\024\240R\240q\330\010\014\210H\220C\220r\230\022\2305\240\002\240!\330\010\016\210c\220\021\330\010\017\210q\330\014\030\230\001\330\020\023\2204\220s\230-\240q\250\004\250D\260\005\260S\270\r\300Q\300d\310$\310a\360\010\000\005\020\210t\2202\220U\230#\230T\240\022\2401\330\004\017\210t\2202\220U\230#\230T\240\022\2401\330\004\007\200t\2108\2201\220I\230Q\330\010\017\210q\330\004\t\210\030\220\022\2204\220r\230\024\230R\230x\240r\250\024\250R\250u\260C\260x\270r\300\021\330\004\010\210\010\220\003\2202\220R\220u\230B\230a\330\004\n\210#\210Q\330\004\007\320\007.\250a\330\010\014\210D\220\001\330\006\n\320\n1\260\021\260$\260d\270!\330\010\017\210q\330\014\030\230\001\330\020\023\2204\220s\230-\240q\250\004\250D\260\005\260S\270\r\300Q\300d\310$\310a\360\006\000\005\014\2101\320\000!\240\021\360\034\000\005\010\200s\210!\2103\210b\220\001\330\010\013\2103\210a\210s\220\"\220A\340\014\024\220A\360\006\000\r\025\220A\220Q\220b\230\002\230!\360\006\000\t\016\210R\210r\220\022\2202\220T\230\022\2302\230R\230q\330\010\013\2103\210c\220\021\330\014\022\220$\220a\220q\330\014\024\220B\220a\220r\230\022\2305\240\002\240$\240b\250\004\250A\250R\250r\260\025\260b\270\004\270B\270a\360\006\000\r\025\220A\330\004\013\2101\200\001\330\004\007\200s\210!\2103\210c\220\021\330\010\013\2104\210q\330\010\023\220<\230q\240\003\2403\240a\330\010\017\210r\220\023\220L\240\n\250!\330""\004\007\200s\210!\2103\210c\220\021\330\010\017\320\017 \240\002\240#\240Q\330\t\014\210A\210S\220\003\2201\330\010\017\210}\230B\230c\240\021\330\004\n\210*\220A\220Q\200\001\330\004\007\200s\210!\2103\210c\220\021\330\010\017\320\017\"\240\"\240A\330\t\014\210A\210S\220\003\2201\330\010\017\210\177\230b\240\001\330\004\n\210*\220A\220Q\200\001\330\004\007\200s\210!\2105\220\003\2201\330\010\017\210|\2302\230U\240!\330\t\014\210A\210U\220#\220Q\330\010\017\320\017 \240\002\240%\240q\330\t\014\210A\210U\220#\220Q\330\010\017\210}\230B\230e\2401\330\004\n\210*\220A\220Q\200\001\360*\000\005\010\200s\210!\2107\220#\220Q\330\010\026\220a\330\t\014\210A\210W\220C\220q\330\010\026\220a\340\010\016\210j\230\001\230\021\330\004\024\220A\330\004\010\210\005\320\r(\250\001\250\027\260\001\330\010\r\210[\230\002\230'\240\021\360\006\000\t\022\220\035\230b\240\006\240a\330\010\r\210\\\230\022\2306\240\021\330\010\025\220W\230A\230\\\250\021\250#\250T\260\023\260C\260s\270!\330\004\013\2101\200\001\360(\000\005\010\200s\210$\320\016%\240Q\240e\2505\260\001\330\004\013\320\013\035\230Q\230c\240\023\240D\250\001\200\001\360(\000\005\010\200s\210#\210T\320\021$\240A\240U\250%\250u\260A\330\004\014\210N\230!\2303\230c\240\023\240D\250\001\360\n\000\005\n\210\021\210&\220\006\220e\2301\230B\230a\230q\330\004\t\210\022\2106\220\021\220%\220r\230\022\2303\230d\240!\330\004\013\2101"; + PyObject *data = NULL; + CYTHON_UNUSED_VAR(__Pyx_DecompressString); + #endif + PyObject **stringtab = __pyx_mstate->__pyx_string_tab; + Py_ssize_t pos = 0; + for (int i = 0; i < 335; i++) { + Py_ssize_t bytes_length = index[i].length; + PyObject *string = PyUnicode_DecodeUTF8(bytes + pos, bytes_length, NULL); + if (likely(string) && i >= 42) PyUnicode_InternInPlace(&string); + if (unlikely(!string)) { + Py_XDECREF(data); + __PYX_ERR(0, 1, __pyx_L1_error) + } + stringtab[i] = string; + pos += bytes_length; + } + for (int i = 335; i < 387; i++) { + Py_ssize_t bytes_length = index[i].length; + PyObject *string = PyBytes_FromStringAndSize(bytes + pos, bytes_length); + stringtab[i] = string; + pos += bytes_length; + if (unlikely(!string)) { + Py_XDECREF(data); + __PYX_ERR(0, 1, __pyx_L1_error) + } + } + Py_XDECREF(data); + for (Py_ssize_t i = 0; i < 387; i++) { + if (unlikely(PyObject_Hash(stringtab[i]) == -1)) { + __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #if CYTHON_IMMORTAL_CONSTANTS + { + PyObject **table = stringtab + 335; + for (Py_ssize_t i=0; i<52; ++i) { + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL); + #else + Py_SET_REFCNT(table[i], _Py_IMMORTAL_INITIAL_REFCNT); + #endif + } + } + #endif + } + { + PyObject **numbertab = __pyx_mstate->__pyx_number_tab; + double const c_constants[] = {0.0,0.5,1.0,-2.0,2.0,3.0,4.0,9.0,1e-3,1e-9,27.0,54.0,0.005,0.125,1e-10}; + for (int i = 0; i < 15; i++) { + numbertab[i] = PyFloat_FromDouble(c_constants[i]); + if (unlikely(!numbertab[i])) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + { + PyObject **numbertab = __pyx_mstate->__pyx_number_tab + 15; + int8_t const cint_constants_1[] = {0,-1,1,2,3,6}; + for (int i = 0; i < 6; i++) { + numbertab[i] = PyLong_FromLong(cint_constants_1[i - 0]); + if (unlikely(!numbertab[i])) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #if CYTHON_IMMORTAL_CONSTANTS + { + PyObject **table = __pyx_mstate->__pyx_number_tab; + for (Py_ssize_t i=0; i<21; ++i) { + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL); + #else + Py_SET_REFCNT(table[i], _Py_IMMORTAL_INITIAL_REFCNT); + #endif + } + } + #endif + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: init_codeobjects ### */ +typedef struct { + unsigned int argcount : 3; + unsigned int num_posonly_args : 1; + unsigned int num_kwonly_args : 1; + unsigned int nlocals : 6; + unsigned int flags : 10; + unsigned int first_line : 11; +} __Pyx_PyCode_New_function_description; +/* NewCodeObj.proto */ +static PyObject* __Pyx_PyCode_New( + const __Pyx_PyCode_New_function_description descr, + PyObject * const *varnames, + PyObject *filename, + PyObject *funcname, + PyObject *line_table, + PyObject *tuple_dedup_map +); + + +static int __Pyx_CreateCodeObjects(__pyx_mstatetype *__pyx_mstate) { + PyObject* tuple_dedup_map = PyDict_New(); + if (unlikely(!tuple_dedup_map)) return -1; + { + const __Pyx_PyCode_New_function_description descr = {0, 0, 0, 1, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS|CO_GENERATOR), 546}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_t}; + __pyx_mstate_global->__pyx_codeobj_tab[0] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_genexpr, __pyx_mstate->__pyx_kp_b_iso88591_q, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[0])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {0, 0, 0, 1, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS|CO_GENERATOR), 583}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_t}; + __pyx_mstate_global->__pyx_codeobj_tab[1] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_genexpr, __pyx_mstate->__pyx_kp_b_iso88591_q, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[1])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 9, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS|CO_VARARGS|CO_GENERATOR), 644}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_pt4, __pyx_mstate->__pyx_n_u_ts, __pyx_mstate->__pyx_n_u_a, __pyx_mstate->__pyx_n_u_b, __pyx_mstate->__pyx_n_u_c, __pyx_mstate->__pyx_n_u_d}; + __pyx_mstate_global->__pyx_codeobj_tab[2] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_splitCubicAtTC, __pyx_mstate->__pyx_kp_b_iso88591__4, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[2])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 21, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS|CO_VARARGS|CO_GENERATOR), 770}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_a, __pyx_mstate->__pyx_n_u_b, __pyx_mstate->__pyx_n_u_c, __pyx_mstate->__pyx_n_u_d, __pyx_mstate->__pyx_n_u_ts, __pyx_mstate->__pyx_n_u_t1, __pyx_mstate->__pyx_n_u_t2, __pyx_mstate->__pyx_n_u_delta, __pyx_mstate->__pyx_n_u_delta_2, __pyx_mstate->__pyx_n_u_delta_3, __pyx_mstate->__pyx_n_u_a1, __pyx_mstate->__pyx_n_u_b1, __pyx_mstate->__pyx_n_u_c1, __pyx_mstate->__pyx_n_u_d1, __pyx_mstate->__pyx_n_u_i, __pyx_mstate->__pyx_n_u_t1_2, __pyx_mstate->__pyx_n_u_t1_3, __pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_pt4}; + __pyx_mstate_global->__pyx_codeobj_tab[3] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_splitCubicAtTC_2, __pyx_mstate->__pyx_kp_b_iso88591__4, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[3])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {0, 0, 0, 1, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS|CO_GENERATOR), 1252}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_i}; + __pyx_mstate_global->__pyx_codeobj_tab[4] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_genexpr, __pyx_mstate->__pyx_kp_b_iso88591__5, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[4])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 1, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1329}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_r}; + __pyx_mstate_global->__pyx_codeobj_tab[5] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_midpoint, __pyx_mstate->__pyx_kp_b_iso88591_A_t3aq_2Qaq, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[5])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 1, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1366}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_ts}; + __pyx_mstate_global->__pyx_codeobj_tab[6] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_lambda, __pyx_mstate->__pyx_kp_b_iso88591_S_1Cr_S_1Cr, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[6])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {0, 0, 0, 1, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS|CO_GENERATOR), 1382}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_p}; + __pyx_mstate_global->__pyx_codeobj_tab[7] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_genexpr, __pyx_mstate->__pyx_kp_b_iso88591_1, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[7])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {0, 0, 0, 1, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS|CO_GENERATOR), 1485}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_x}; + __pyx_mstate_global->__pyx_codeobj_tab[8] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_genexpr, __pyx_mstate->__pyx_kp_b_iso88591_a_2, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[8])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {5, 0, 0, 5, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 56}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_pt4, __pyx_mstate->__pyx_n_u_tolerance}; + __pyx_mstate_global->__pyx_codeobj_tab[9] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_calcCubicArcLength, __pyx_mstate->__pyx_kp_b_iso88591_1_a_r_wb_gRvWBfA, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[9])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 6, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 75}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_p0, __pyx_mstate->__pyx_n_u_p1, __pyx_mstate->__pyx_n_u_p2, __pyx_mstate->__pyx_n_u_p3, __pyx_mstate->__pyx_n_u_mid, __pyx_mstate->__pyx_n_u_deriv3}; + __pyx_mstate_global->__pyx_codeobj_tab[10] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_split_cubic_into_two, __pyx_mstate->__pyx_kp_b_iso88591_3b_S_b_Ba_c_3b_2T_1_c_4r_d_HA_d, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[10])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {5, 0, 0, 9, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 84}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_mult, __pyx_mstate->__pyx_n_u_p0, __pyx_mstate->__pyx_n_u_p1, __pyx_mstate->__pyx_n_u_p2, __pyx_mstate->__pyx_n_u_p3, __pyx_mstate->__pyx_n_u_arch, __pyx_mstate->__pyx_n_u_box, __pyx_mstate->__pyx_n_u_one, __pyx_mstate->__pyx_n_u_two}; + __pyx_mstate_global->__pyx_codeobj_tab[11] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_calcCubicArcLengthCRecurse, __pyx_mstate->__pyx_kp_b_iso88591_3as_A_Qc_4r_AS_b_1Cr_uBe2XS_RuB, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[11])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {5, 0, 0, 6, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 104}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_pt4, __pyx_mstate->__pyx_n_u_tolerance, __pyx_mstate->__pyx_n_u_mult}; + __pyx_mstate_global->__pyx_codeobj_tab[12] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_calcCubicArcLengthC, __pyx_mstate->__pyx_kp_b_iso88591_4r_Rq_avU_uA, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[12])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {3, 0, 0, 3, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 151}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3}; + __pyx_mstate_global->__pyx_codeobj_tab[13] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_calcQuadraticArcLength, __pyx_mstate->__pyx_kp_b_iso88591_7_F_6, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[13])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {3, 0, 0, 14, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 186}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_scale, __pyx_mstate->__pyx_n_u_origDist, __pyx_mstate->__pyx_n_u_a, __pyx_mstate->__pyx_n_u_b, __pyx_mstate->__pyx_n_u_x0, __pyx_mstate->__pyx_n_u_x1, __pyx_mstate->__pyx_n_u_Len, __pyx_mstate->__pyx_n_u_d0, __pyx_mstate->__pyx_n_u_d1, __pyx_mstate->__pyx_n_u_d, __pyx_mstate->__pyx_n_u_n}; + __pyx_mstate_global->__pyx_codeobj_tab[14] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_calcQuadraticArcLengthC, __pyx_mstate->__pyx_kp_b_iso88591_Rq_Rq_2Q_A_Cq_vS_s_4r_t1Cq_s_Rq, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[14])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {3, 0, 0, 3, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 237}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3}; + __pyx_mstate_global->__pyx_codeobj_tab[15] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_approximateQuadraticArcLength, __pyx_mstate->__pyx_kp_b_iso88591_6_rQR, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[15])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {3, 0, 0, 6, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 254}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_v0, __pyx_mstate->__pyx_n_u_v1, __pyx_mstate->__pyx_n_u_v2}; + __pyx_mstate_global->__pyx_codeobj_tab[16] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_approximateQuadraticArcLengthC, __pyx_mstate->__pyx_kp_b_iso88591_B_A_2T_5Rt2_PPRRS_AT_5_A_Bd_6b, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[16])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {3, 0, 0, 14, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 298}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_ax, __pyx_mstate->__pyx_n_u_ay, __pyx_mstate->__pyx_n_u_bx, __pyx_mstate->__pyx_n_u_by, __pyx_mstate->__pyx_n_u_cx, __pyx_mstate->__pyx_n_u_cy, __pyx_mstate->__pyx_n_u_ax2, __pyx_mstate->__pyx_n_u_ay2, __pyx_mstate->__pyx_n_u_roots, __pyx_mstate->__pyx_n_u_points, __pyx_mstate->__pyx_n_u_t}; + __pyx_mstate_global->__pyx_codeobj_tab[17] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_calcQuadraticBounds, __pyx_mstate->__pyx_kp_b_iso88591_T_t6_V_5_Q_Rq_Rq_A_t3a_WAQc_1_t, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[17])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 4, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 332}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_pt4}; + __pyx_mstate_global->__pyx_codeobj_tab[18] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_approximateCubicArcLength, __pyx_mstate->__pyx_kp_b_iso88591_2_Q_r_wb_gRvWBa, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[18])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 9, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 362}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_pt4, __pyx_mstate->__pyx_n_u_v0, __pyx_mstate->__pyx_n_u_v1, __pyx_mstate->__pyx_n_u_v2, __pyx_mstate->__pyx_n_u_v3, __pyx_mstate->__pyx_n_u_v4}; + __pyx_mstate_global->__pyx_codeobj_tab[19] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_approximateCubicArcLengthC, __pyx_mstate->__pyx_kp_b_iso88591_AT_5_A_2Q_Ba_Ba_Ba_AT_4r_RuBa_A, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[19])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 23, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 412}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_pt4, __pyx_mstate->__pyx_n_u_ax, __pyx_mstate->__pyx_n_u_ay, __pyx_mstate->__pyx_n_u_bx, __pyx_mstate->__pyx_n_u_by, __pyx_mstate->__pyx_n_u_cx, __pyx_mstate->__pyx_n_u_cy, __pyx_mstate->__pyx_n_u_dx, __pyx_mstate->__pyx_n_u_dy, __pyx_mstate->__pyx_n_u_ax3, __pyx_mstate->__pyx_n_u_ay3, __pyx_mstate->__pyx_n_u_bx2, __pyx_mstate->__pyx_n_u_by2, __pyx_mstate->__pyx_n_u_xRoots, __pyx_mstate->__pyx_n_u_yRoots, __pyx_mstate->__pyx_n_u_roots, __pyx_mstate->__pyx_n_u_points, __pyx_mstate->__pyx_n_u_t, __pyx_mstate->__pyx_n_u_t, __pyx_mstate->__pyx_n_u_t}; + __pyx_mstate_global->__pyx_codeobj_tab[20] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_calcCubicBounds, __pyx_mstate->__pyx_kp_b_iso88591_T_t6_V4v_e5PQ_Rq_Rq_Rq_Rq_Qb_E, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[20])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 15, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 450}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_where, __pyx_mstate->__pyx_n_u_isHorizontal, __pyx_mstate->__pyx_n_u_pt1x, __pyx_mstate->__pyx_n_u_pt1y, __pyx_mstate->__pyx_n_u_pt2x, __pyx_mstate->__pyx_n_u_pt2y, __pyx_mstate->__pyx_n_u_ax, __pyx_mstate->__pyx_n_u_ay, __pyx_mstate->__pyx_n_u_bx, __pyx_mstate->__pyx_n_u_by, __pyx_mstate->__pyx_n_u_a, __pyx_mstate->__pyx_n_u_t, __pyx_mstate->__pyx_n_u_midPt}; + __pyx_mstate_global->__pyx_codeobj_tab[21] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_splitLine, __pyx_mstate->__pyx_kp_b_iso88591_H_b_b_S_r_A_r_a_s_c_1_r_D_2Rr_S, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[21])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {5, 0, 0, 11, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 507}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_where, __pyx_mstate->__pyx_n_u_isHorizontal, __pyx_mstate->__pyx_n_u_a, __pyx_mstate->__pyx_n_u_b, __pyx_mstate->__pyx_n_u_c, __pyx_mstate->__pyx_n_u_solutions, __pyx_mstate->__pyx_n_u_genexpr, __pyx_mstate->__pyx_n_u_genexpr}; + __pyx_mstate_global->__pyx_codeobj_tab[22] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_splitQuadratic, __pyx_mstate->__pyx_kp_b_iso88591_F_s_Qe5_a_1N_A_aq_t1_r_e1_Qc_D, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[22])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {6, 0, 0, 13, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 552}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_pt4, __pyx_mstate->__pyx_n_u_where, __pyx_mstate->__pyx_n_u_isHorizontal, __pyx_mstate->__pyx_n_u_a, __pyx_mstate->__pyx_n_u_b, __pyx_mstate->__pyx_n_u_c, __pyx_mstate->__pyx_n_u_d, __pyx_mstate->__pyx_n_u_solutions, __pyx_mstate->__pyx_n_u_genexpr, __pyx_mstate->__pyx_n_u_genexpr}; + __pyx_mstate_global->__pyx_codeobj_tab[23] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_splitCubic, __pyx_mstate->__pyx_kp_b_iso88591_6_s_T_AU_uA_1O1A_2Q_aq_t1_r_e5, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[23])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {3, 0, 0, 7, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS|CO_VARARGS), 589}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_ts, __pyx_mstate->__pyx_n_u_a, __pyx_mstate->__pyx_n_u_b, __pyx_mstate->__pyx_n_u_c}; + __pyx_mstate_global->__pyx_codeobj_tab[24] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_splitQuadraticAtT_2, __pyx_mstate->__pyx_kp_b_iso88591_s_Qe5_Qc_D, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[24])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 10, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS|CO_VARARGS), 613}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_pt4, __pyx_mstate->__pyx_n_u_ts, __pyx_mstate->__pyx_n_u_a, __pyx_mstate->__pyx_n_u_b, __pyx_mstate->__pyx_n_u_c, __pyx_mstate->__pyx_n_u_d, __pyx_mstate->__pyx_n_u_split}; + __pyx_mstate_global->__pyx_codeobj_tab[25] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_splitCubicAtT_2, __pyx_mstate->__pyx_kp_b_iso88591_s_T_AU_uA_N_3c_D_e1Baq_6_r_3d_1, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[25])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {5, 0, 0, 12, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 668}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_pt4, __pyx_mstate->__pyx_n_u_t, __pyx_mstate->__pyx_n_u_t2, __pyx_mstate->__pyx_n_u_1_t, __pyx_mstate->__pyx_n_u_1_t_2, __pyx_mstate->__pyx_n_u_2_t_1_t, __pyx_mstate->__pyx_n_u_pointAtT, __pyx_mstate->__pyx_n_u_off1, __pyx_mstate->__pyx_n_u_off2}; + __pyx_mstate_global->__pyx_codeobj_tab[26] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_splitCubicIntoTwoAtTC, __pyx_mstate->__pyx_kp_b_iso88591_0_2Q_2Rq_U_A_r_2Rq_r_b_Bb_7_Bb, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[26])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {3, 0, 0, 26, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS|CO_VARARGS), 708}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_a, __pyx_mstate->__pyx_n_u_b, __pyx_mstate->__pyx_n_u_c, __pyx_mstate->__pyx_n_u_ts, __pyx_mstate->__pyx_n_u_segments, __pyx_mstate->__pyx_n_u_ax, __pyx_mstate->__pyx_n_u_ay, __pyx_mstate->__pyx_n_u_bx, __pyx_mstate->__pyx_n_u_by, __pyx_mstate->__pyx_n_u_cx, __pyx_mstate->__pyx_n_u_cy, __pyx_mstate->__pyx_n_u_i, __pyx_mstate->__pyx_n_u_t1, __pyx_mstate->__pyx_n_u_t2, __pyx_mstate->__pyx_n_u_delta, __pyx_mstate->__pyx_n_u_delta_2, __pyx_mstate->__pyx_n_u_a1x, __pyx_mstate->__pyx_n_u_a1y, __pyx_mstate->__pyx_n_u_b1x, __pyx_mstate->__pyx_n_u_b1y, __pyx_mstate->__pyx_n_u_t1_2, __pyx_mstate->__pyx_n_u_c1x, __pyx_mstate->__pyx_n_u_c1y, __pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3}; + __pyx_mstate_global->__pyx_codeobj_tab[27] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_splitQuadraticAtT, __pyx_mstate->__pyx_kp_b_iso88591_Qa_q_gQc_gQa_Q_Q_Q_U_3at2Q_Rq_R, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[27])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 34, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS|CO_VARARGS), 735}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_a, __pyx_mstate->__pyx_n_u_b, __pyx_mstate->__pyx_n_u_c, __pyx_mstate->__pyx_n_u_d, __pyx_mstate->__pyx_n_u_ts, __pyx_mstate->__pyx_n_u_segments, __pyx_mstate->__pyx_n_u_ax, __pyx_mstate->__pyx_n_u_ay, __pyx_mstate->__pyx_n_u_bx, __pyx_mstate->__pyx_n_u_by, __pyx_mstate->__pyx_n_u_cx, __pyx_mstate->__pyx_n_u_cy, __pyx_mstate->__pyx_n_u_dx, __pyx_mstate->__pyx_n_u_dy, __pyx_mstate->__pyx_n_u_i, __pyx_mstate->__pyx_n_u_t1, __pyx_mstate->__pyx_n_u_t2, __pyx_mstate->__pyx_n_u_delta, __pyx_mstate->__pyx_n_u_delta_2, __pyx_mstate->__pyx_n_u_delta_3, __pyx_mstate->__pyx_n_u_t1_2, __pyx_mstate->__pyx_n_u_t1_3, __pyx_mstate->__pyx_n_u_a1x, __pyx_mstate->__pyx_n_u_a1y, __pyx_mstate->__pyx_n_u_b1x, __pyx_mstate->__pyx_n_u_b1y, __pyx_mstate->__pyx_n_u_c1x, __pyx_mstate->__pyx_n_u_c1y, __pyx_mstate->__pyx_n_u_d1x, __pyx_mstate->__pyx_n_u_d1y, __pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_pt4}; + __pyx_mstate_global->__pyx_codeobj_tab[28] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_splitCubicAtT, __pyx_mstate->__pyx_kp_b_iso88591_Qa_gQc_gQa_q_Q_Q_Q_Q_U_3at2Q_Rq, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[28])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 7, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 815}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_a, __pyx_mstate->__pyx_n_u_b, __pyx_mstate->__pyx_n_u_c, __pyx_mstate->__pyx_n_u_sqrt, __pyx_mstate->__pyx_n_u_roots, __pyx_mstate->__pyx_n_u_DD, __pyx_mstate->__pyx_n_u_rDD}; + __pyx_mstate_global->__pyx_codeobj_tab[29] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_solveQuadratic, __pyx_mstate->__pyx_kp_b_iso88591_s_3b_3as_A_A_AQb_Rr_2T_2Rq_3c_a, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[29])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 19, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 848}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_a, __pyx_mstate->__pyx_n_u_b, __pyx_mstate->__pyx_n_u_c, __pyx_mstate->__pyx_n_u_d, __pyx_mstate->__pyx_n_u_a1, __pyx_mstate->__pyx_n_u_a2, __pyx_mstate->__pyx_n_u_a3, __pyx_mstate->__pyx_n_u_Q, __pyx_mstate->__pyx_n_u_R, __pyx_mstate->__pyx_n_u_R2, __pyx_mstate->__pyx_n_u_Q3, __pyx_mstate->__pyx_n_u_R2_Q3, __pyx_mstate->__pyx_n_u_x, __pyx_mstate->__pyx_n_u_theta, __pyx_mstate->__pyx_n_u_rQ2, __pyx_mstate->__pyx_n_u_a1_3, __pyx_mstate->__pyx_n_u_x0, __pyx_mstate->__pyx_n_u_x1, __pyx_mstate->__pyx_n_u_x2}; + __pyx_mstate_global->__pyx_codeobj_tab[30] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_solveCubic, __pyx_mstate->__pyx_kp_b_iso88591_L_s_3b_Qc_A_Qa_2Q_2Q_2Q_Bc_4r_R, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[30])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {3, 0, 0, 13, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 945}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_x2, __pyx_mstate->__pyx_n_u_y2, __pyx_mstate->__pyx_n_u_x3, __pyx_mstate->__pyx_n_u_y3, __pyx_mstate->__pyx_n_u_cx, __pyx_mstate->__pyx_n_u_cy, __pyx_mstate->__pyx_n_u_bx, __pyx_mstate->__pyx_n_u_by, __pyx_mstate->__pyx_n_u_ax, __pyx_mstate->__pyx_n_u_ay}; + __pyx_mstate_global->__pyx_codeobj_tab[31] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_calcQuadraticParameters, __pyx_mstate->__pyx_kp_b_iso88591_Q_Q_Q_Rt2Q_Rt2Q_Bc_1_Bc_1_1D_d, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[31])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 18, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 956}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_pt4, __pyx_mstate->__pyx_n_u_x2, __pyx_mstate->__pyx_n_u_y2, __pyx_mstate->__pyx_n_u_x3, __pyx_mstate->__pyx_n_u_y3, __pyx_mstate->__pyx_n_u_x4, __pyx_mstate->__pyx_n_u_y4, __pyx_mstate->__pyx_n_u_dx, __pyx_mstate->__pyx_n_u_dy, __pyx_mstate->__pyx_n_u_cx, __pyx_mstate->__pyx_n_u_cy, __pyx_mstate->__pyx_n_u_bx, __pyx_mstate->__pyx_n_u_by, __pyx_mstate->__pyx_n_u_ax, __pyx_mstate->__pyx_n_u_ay}; + __pyx_mstate_global->__pyx_codeobj_tab[32] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_calcCubicParameters, __pyx_mstate->__pyx_kp_b_iso88591_Q_Q_Q_Q_Rt2Q_Rt2Q_Rt2T_1_Rt2T_1, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[32])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {3, 0, 0, 15, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 988}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_a, __pyx_mstate->__pyx_n_u_b, __pyx_mstate->__pyx_n_u_c, __pyx_mstate->__pyx_n_u_ax, __pyx_mstate->__pyx_n_u_ay, __pyx_mstate->__pyx_n_u_bx, __pyx_mstate->__pyx_n_u_by, __pyx_mstate->__pyx_n_u_cx, __pyx_mstate->__pyx_n_u_cy, __pyx_mstate->__pyx_n_u_x1, __pyx_mstate->__pyx_n_u_y1, __pyx_mstate->__pyx_n_u_x2, __pyx_mstate->__pyx_n_u_y2, __pyx_mstate->__pyx_n_u_x3, __pyx_mstate->__pyx_n_u_y3}; + __pyx_mstate_global->__pyx_codeobj_tab[33] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_calcQuadraticPoints, __pyx_mstate->__pyx_kp_b_iso88591_Q_Q_Q_RuBa_RuBa_Bc_1_Bc_1_1D_d, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[33])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 20, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1001}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_a, __pyx_mstate->__pyx_n_u_b, __pyx_mstate->__pyx_n_u_c, __pyx_mstate->__pyx_n_u_d, __pyx_mstate->__pyx_n_u_ax, __pyx_mstate->__pyx_n_u_ay, __pyx_mstate->__pyx_n_u_bx, __pyx_mstate->__pyx_n_u_by, __pyx_mstate->__pyx_n_u_cx, __pyx_mstate->__pyx_n_u_cy, __pyx_mstate->__pyx_n_u_dx, __pyx_mstate->__pyx_n_u_dy, __pyx_mstate->__pyx_n_u_x1, __pyx_mstate->__pyx_n_u_y1, __pyx_mstate->__pyx_n_u_x2, __pyx_mstate->__pyx_n_u_y2, __pyx_mstate->__pyx_n_u_x3, __pyx_mstate->__pyx_n_u_y3, __pyx_mstate->__pyx_n_u_x4, __pyx_mstate->__pyx_n_u_y4}; + __pyx_mstate_global->__pyx_codeobj_tab[34] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_calcCubicPoints, __pyx_mstate->__pyx_kp_b_iso88591_Q_Q_Q_Q_RuBa_RuBa_Rt2T_1_Rt2T_1, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[34])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {3, 0, 0, 3, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1040}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_t}; + __pyx_mstate_global->__pyx_codeobj_tab[35] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_linePointAtT, __pyx_mstate->__pyx_kp_b_iso88591_AS_Cr_3b_1Cr_c_S_Cr_AS, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[35])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 6, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1053}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_t, __pyx_mstate->__pyx_n_u_x, __pyx_mstate->__pyx_n_u_y}; + __pyx_mstate_global->__pyx_codeobj_tab[36] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_quadraticPointAtT, __pyx_mstate->__pyx_kp_b_iso88591_2S_2Rs_Cq_2Rs_Bc_2Rs_3b_Bb_1A_2, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[36])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {5, 0, 0, 10, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1068}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_pt4, __pyx_mstate->__pyx_n_u_t, __pyx_mstate->__pyx_n_u_t2, __pyx_mstate->__pyx_n_u_1_t, __pyx_mstate->__pyx_n_u_1_t_2, __pyx_mstate->__pyx_n_u_x, __pyx_mstate->__pyx_n_u_y}; + __pyx_mstate_global->__pyx_codeobj_tab[37] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_cubicPointAtT, __pyx_mstate->__pyx_kp_b_iso88591_2Q_2Rq_U_A_r_b_1A_Cwb_Cq_2U_Cr, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[37])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {5, 0, 0, 8, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1094}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_pt1, __pyx_mstate->__pyx_n_u_pt2, __pyx_mstate->__pyx_n_u_pt3, __pyx_mstate->__pyx_n_u_pt4, __pyx_mstate->__pyx_n_u_t, __pyx_mstate->__pyx_n_u_t2, __pyx_mstate->__pyx_n_u_1_t, __pyx_mstate->__pyx_n_u_1_t_2}; + __pyx_mstate_global->__pyx_codeobj_tab[38] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_cubicPointAtTC, __pyx_mstate->__pyx_kp_b_iso88591_2Q_2Rq_U_A_7_E_4r_3gRr_4r_b_2U, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[38])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 2, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1119}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_seg, __pyx_mstate->__pyx_n_u_t}; + __pyx_mstate_global->__pyx_codeobj_tab[39] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_segmentPointAtT, __pyx_mstate->__pyx_kp_b_iso88591_s_5_1_2U_AU_Q_q_AU_Q_Be1_AQ, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[39])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {3, 0, 0, 9, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1134}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_s, __pyx_mstate->__pyx_n_u_e, __pyx_mstate->__pyx_n_u_pt, __pyx_mstate->__pyx_n_u_sx, __pyx_mstate->__pyx_n_u_sy, __pyx_mstate->__pyx_n_u_ex, __pyx_mstate->__pyx_n_u_ey, __pyx_mstate->__pyx_n_u_px, __pyx_mstate->__pyx_n_u_py}; + __pyx_mstate_global->__pyx_codeobj_tab[40] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_line_t_of_pt, __pyx_mstate->__pyx_kp_b_iso88591_Q_Q_Q_s_3b_Bhd_Qc_4r_s_3b_Bc_Rq, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[40])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {3, 0, 0, 5, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1148}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_a, __pyx_mstate->__pyx_n_u_b, __pyx_mstate->__pyx_n_u_origin, __pyx_mstate->__pyx_n_u_xDiff, __pyx_mstate->__pyx_n_u_yDiff}; + __pyx_mstate_global->__pyx_codeobj_tab[41] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_both_points_are_on_same_side_of, __pyx_mstate->__pyx_kp_b_iso88591_Qas_F_4s_1Cr_q_Qas_F_4s_1Cr_q_5, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[41])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 17, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1154}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_s1, __pyx_mstate->__pyx_n_u_e1, __pyx_mstate->__pyx_n_u_s2, __pyx_mstate->__pyx_n_u_e2, __pyx_mstate->__pyx_n_u_s1x, __pyx_mstate->__pyx_n_u_s1y, __pyx_mstate->__pyx_n_u_e1x, __pyx_mstate->__pyx_n_u_e1y, __pyx_mstate->__pyx_n_u_s2x, __pyx_mstate->__pyx_n_u_s2y, __pyx_mstate->__pyx_n_u_e2x, __pyx_mstate->__pyx_n_u_e2y, __pyx_mstate->__pyx_n_u_x, __pyx_mstate->__pyx_n_u_slope34, __pyx_mstate->__pyx_n_u_y, __pyx_mstate->__pyx_n_u_pt, __pyx_mstate->__pyx_n_u_slope12}; + __pyx_mstate_global->__pyx_codeobj_tab[42] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_lineLineIntersections, __pyx_mstate->__pyx_kp_b_iso88591_q_q_q_q_HAU_t4xq_U_d_hauTU_q_HA, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[42])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 4, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1232}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_segment, __pyx_mstate->__pyx_n_u_start, __pyx_mstate->__pyx_n_u_end, __pyx_mstate->__pyx_n_u_angle}; + __pyx_mstate_global->__pyx_codeobj_tab[43] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_alignment_transformation, __pyx_mstate->__pyx_kp_b_iso88591_G1A_1_D_as_3b_Qd_Qc_5_87_1F_AQe, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[43])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 10, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1242}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_curve, __pyx_mstate->__pyx_n_u_line, __pyx_mstate->__pyx_n_u_aligned_curve, __pyx_mstate->__pyx_n_u_a, __pyx_mstate->__pyx_n_u_b, __pyx_mstate->__pyx_n_u_c, __pyx_mstate->__pyx_n_u_intersections, __pyx_mstate->__pyx_n_u_d, __pyx_mstate->__pyx_n_u_genexpr, __pyx_mstate->__pyx_n_u_genexpr}; + __pyx_mstate_global->__pyx_codeobj_tab[44] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_curve_line_intersections_t, __pyx_mstate->__pyx_kp_b_iso88591_Qe3C1A_s_7_Q_3d_1_aq_Qat1AQ_AWC, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[44])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 7, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1255}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_curve, __pyx_mstate->__pyx_n_u_line, __pyx_mstate->__pyx_n_u_pointFinder, __pyx_mstate->__pyx_n_u_intersections, __pyx_mstate->__pyx_n_u_t, __pyx_mstate->__pyx_n_u_pt, __pyx_mstate->__pyx_n_u_line_t}; + __pyx_mstate_global->__pyx_codeobj_tab[45] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_curveLineIntersections, __pyx_mstate->__pyx_kp_b_iso88591_s_7_Q_a_AWCq_a_j_A_b_a_6_WA_T_C, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[45])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 1, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1293}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_c}; + __pyx_mstate_global->__pyx_codeobj_tab[46] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_curve_bounds, __pyx_mstate->__pyx_kp_b_iso88591_s_3c_A_AS_1_b_AQ, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[46])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 5, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1301}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_c, __pyx_mstate->__pyx_n_u_t, __pyx_mstate->__pyx_n_u_s, __pyx_mstate->__pyx_n_u_e, __pyx_mstate->__pyx_n_u_midpoint}; + __pyx_mstate_global->__pyx_codeobj_tab[47] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_split_segment_at_t, __pyx_mstate->__pyx_kp_b_iso88591_s_3c_4q_q_3a_r_L_s_3c_Q_AS_1_Bc, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[47])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {5, 0, 0, 25, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1313}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_curve1, __pyx_mstate->__pyx_n_u_curve2, __pyx_mstate->__pyx_n_u_precision, __pyx_mstate->__pyx_n_u_range1, __pyx_mstate->__pyx_n_u_range2, __pyx_mstate->__pyx_n_u_bounds1, __pyx_mstate->__pyx_n_u_bounds2, __pyx_mstate->__pyx_n_u_intersects, __pyx_mstate->__pyx_n_u__6, __pyx_mstate->__pyx_n_u_midpoint, __pyx_mstate->__pyx_n_u_midpoint, __pyx_mstate->__pyx_n_u_c11, __pyx_mstate->__pyx_n_u_c12, __pyx_mstate->__pyx_n_u_c11_range, __pyx_mstate->__pyx_n_u_c12_range, __pyx_mstate->__pyx_n_u_c21, __pyx_mstate->__pyx_n_u_c22, __pyx_mstate->__pyx_n_u_c21_range, __pyx_mstate->__pyx_n_u_c22_range, __pyx_mstate->__pyx_n_u_found, __pyx_mstate->__pyx_n_u_unique_key, __pyx_mstate->__pyx_n_u_seen, __pyx_mstate->__pyx_n_u_unique_values, __pyx_mstate->__pyx_n_u_ts, __pyx_mstate->__pyx_n_u_key}; + __pyx_mstate_global->__pyx_codeobj_tab[48] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_curve_curve_intersections_t, __pyx_mstate->__pyx_kp_b_iso88591_M_m1A_m1A_t1_q_t1_q_HAYa_t1_q_x, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[48])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 4, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1380}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_segment, __pyx_mstate->__pyx_n_u_maybeline, __pyx_mstate->__pyx_n_u_genexpr, __pyx_mstate->__pyx_n_u_genexpr}; + __pyx_mstate_global->__pyx_codeobj_tab[49] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_is_linelike, __pyx_mstate->__pyx_kp_b_iso88591_2B_1_1, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[49])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 8, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1385}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_curve1, __pyx_mstate->__pyx_n_u_curve2, __pyx_mstate->__pyx_n_u_line1, __pyx_mstate->__pyx_n_u_line2, __pyx_mstate->__pyx_n_u_hits, __pyx_mstate->__pyx_n_u_intersection_ts, __pyx_mstate->__pyx_n_u_x, __pyx_mstate->__pyx_n_u_ts}; + __pyx_mstate_global->__pyx_codeobj_tab[50] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_curveCurveIntersections, __pyx_mstate->__pyx_kp_b_iso88591_1A_at6_1_q_F_4vRq_1L_AU_Qe3auD, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[50])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 5, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1427}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_seg1, __pyx_mstate->__pyx_n_u_seg2, __pyx_mstate->__pyx_n_u_swapped, __pyx_mstate->__pyx_n_u_intersections, __pyx_mstate->__pyx_n_u_i}; + __pyx_mstate_global->__pyx_codeobj_tab[51] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_segmentSegmentIntersections, __pyx_mstate->__pyx_kp_b_iso88591_a_s_6_3aq_gV1_s_6_1_3avRq_31F_2, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[51])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 4, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1475}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_obj, __pyx_mstate->__pyx_n_u_it, __pyx_mstate->__pyx_n_u_genexpr, __pyx_mstate->__pyx_n_u_genexpr}; + __pyx_mstate_global->__pyx_codeobj_tab[52] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_segmentrepr, __pyx_mstate->__pyx_kp_b_iso88591_T_uBa_wb_E_a, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[52])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 2, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1488}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_segments, __pyx_mstate->__pyx_n_u_segment}; + __pyx_mstate_global->__pyx_codeobj_tab[53] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_misc_bezierTools_p, __pyx_mstate->__pyx_n_u_printSegments, __pyx_mstate->__pyx_kp_b_iso88591_1_Ql_1, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[53])) goto bad; + } + Py_DECREF(tuple_dedup_map); + return 0; + bad: + Py_DECREF(tuple_dedup_map); + return -1; +} +/* #### Code section: init_globals ### */ + +static int __Pyx_InitGlobals(void) { + /* PythonCompatibility.init */ + if (likely(__Pyx_init_co_variables() == 0)); else + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* CommonTypesMetaclass.init */ + if (likely(__pyx_CommonTypesMetaclass_init(__pyx_m) == 0)); else + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* Generator.init */ + if (likely(__pyx_Generator_init(__pyx_m) == 0)); else + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* CachedMethodType.init */ + #if CYTHON_COMPILING_IN_LIMITED_API + { + PyObject *typesModule=NULL; + typesModule = PyImport_ImportModule("types"); + if (typesModule) { + __pyx_mstate_global->__Pyx_CachedMethodType = PyObject_GetAttrString(typesModule, "MethodType"); + Py_DECREF(typesModule); + } + } // error handling follows + #endif + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* CythonFunctionShared.init */ + if (likely(__pyx_CyFunction_init(__pyx_m) == 0)); else + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: cleanup_globals ### */ +/* #### Code section: cleanup_module ### */ +/* #### Code section: main_method ### */ +/* #### Code section: utility_code_pragmas ### */ +#ifdef _MSC_VER +#pragma warning( push ) +/* Warning 4127: conditional expression is constant + * Cython uses constant conditional expressions to allow in inline functions to be optimized at + * compile-time, so this warning is not useful + */ +#pragma warning( disable : 4127 ) +#endif + + + +/* #### Code section: utility_code_def ### */ + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* PyErrExceptionMatches (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); + for (i=0; i= 0x030C00A6 + PyObject *current_exception = tstate->current_exception; + if (unlikely(!current_exception)) return 0; + exc_type = (PyObject*) Py_TYPE(current_exception); + if (exc_type == err) return 1; +#else + exc_type = tstate->curexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; +#endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(exc_type); + #endif + if (unlikely(PyTuple_Check(err))) { + result = __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + } else { + result = __Pyx_PyErr_GivenExceptionMatches(exc_type, err); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(exc_type); + #endif + return result; +} +#endif + +/* PyErrFetchRestore (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject *tmp_value; + assert(type == NULL || (value != NULL && type == (PyObject*) Py_TYPE(value))); + if (value) { + #if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(((PyBaseExceptionObject*) value)->traceback != tb)) + #endif + PyException_SetTraceback(value, tb); + } + tmp_value = tstate->current_exception; + tstate->current_exception = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#endif +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject* exc_value; + exc_value = tstate->current_exception; + tstate->current_exception = 0; + *value = exc_value; + *type = NULL; + *tb = NULL; + if (exc_value) { + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + #if CYTHON_COMPILING_IN_CPYTHON + *tb = ((PyBaseExceptionObject*) exc_value)->traceback; + Py_XINCREF(*tb); + #else + *tb = PyException_GetTraceback(exc_value); + #endif + } +#else + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#endif +} +#endif + +/* PyObjectGetAttrStr (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* PyObjectGetAttrStrNoError (used by GetBuiltinName) */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d0000 +static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + __Pyx_PyErr_Clear(); +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { + PyObject *result; +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + (void) PyObject_GetOptionalAttr(obj, attr_name, &result); + return result; +#else +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { + return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); + } +#endif + result = __Pyx_PyObject_GetAttrStr(obj, attr_name); + if (unlikely(!result)) { + __Pyx_PyObject_GetAttrStr_ClearAttributeError(); + } + return result; +#endif +} + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStrNoError(__pyx_mstate_global->__pyx_b, name); + if (unlikely(!result) && !PyErr_Occurred()) { + PyErr_Format(PyExc_NameError, + "name '%U' is not defined", name); + } + return result; +} + +/* TupleAndListFromArray (used by fastcall) */ +#if !CYTHON_COMPILING_IN_CPYTHON && CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + Py_ssize_t i; + if (n <= 0) { + return __Pyx_NewRef(__pyx_mstate_global->__pyx_empty_tuple); + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + for (i = 0; i < n; i++) { + if (unlikely(__Pyx_PyTuple_SET_ITEM(res, i, src[i]) < (0))) { + Py_DECREF(res); + return NULL; + } + Py_INCREF(src[i]); + } + return res; +} +#elif CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE void __Pyx_copy_object_array(PyObject *const *CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) { + PyObject *v; + Py_ssize_t i; + for (i = 0; i < length; i++) { + v = dest[i] = src[i]; + Py_INCREF(v); + } +} +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return __Pyx_NewRef(__pyx_mstate_global->__pyx_empty_tuple); + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyTupleObject*)res)->ob_item, n); + return res; +} +static CYTHON_INLINE PyObject * +__Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return PyList_New(0); + } + res = PyList_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyListObject*)res)->ob_item, n); + return res; +} +#endif + +/* BytesEquals (used by UnicodeEquals) */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_GRAAL ||\ + !(CYTHON_ASSUME_SAFE_SIZE && CYTHON_ASSUME_SAFE_MACROS) + return PyObject_RichCompareBool(s1, s2, equals); +#else + if (s1 == s2) { + return (equals == Py_EQ); + } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { + const char *ps1, *ps2; + Py_ssize_t length = PyBytes_GET_SIZE(s1); + if (length != PyBytes_GET_SIZE(s2)) + return (equals == Py_NE); + ps1 = PyBytes_AS_STRING(s1); + ps2 = PyBytes_AS_STRING(s2); + if (ps1[0] != ps2[0]) { + return (equals == Py_NE); + } else if (length == 1) { + return (equals == Py_EQ); + } else { + int result; +#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) + Py_hash_t hash1, hash2; + hash1 = ((PyBytesObject*)s1)->ob_shash; + hash2 = ((PyBytesObject*)s2)->ob_shash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + return (equals == Py_NE); + } +#endif + result = memcmp(ps1, ps2, (size_t)length); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { + return (equals == Py_NE); + } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { + return (equals == Py_NE); + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +#endif +} + +/* UnicodeEquals (used by fastcall) */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_GRAAL + return PyObject_RichCompareBool(s1, s2, equals); +#else + int s1_is_unicode, s2_is_unicode; + if (s1 == s2) { + goto return_eq; + } + s1_is_unicode = PyUnicode_CheckExact(s1); + s2_is_unicode = PyUnicode_CheckExact(s2); + if (s1_is_unicode & s2_is_unicode) { + Py_ssize_t length, length2; + int kind; + void *data1, *data2; + #if !CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) + return -1; + #endif + length = __Pyx_PyUnicode_GET_LENGTH(s1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(length < 0)) return -1; + #endif + length2 = __Pyx_PyUnicode_GET_LENGTH(s2); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(length2 < 0)) return -1; + #endif + if (length != length2) { + goto return_ne; + } +#if CYTHON_USE_UNICODE_INTERNALS + { + Py_hash_t hash1, hash2; + hash1 = ((PyASCIIObject*)s1)->hash; + hash2 = ((PyASCIIObject*)s2)->hash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + goto return_ne; + } + } +#endif + kind = __Pyx_PyUnicode_KIND(s1); + if (kind != __Pyx_PyUnicode_KIND(s2)) { + goto return_ne; + } + data1 = __Pyx_PyUnicode_DATA(s1); + data2 = __Pyx_PyUnicode_DATA(s2); + if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { + goto return_ne; + } else if (length == 1) { + goto return_eq; + } else { + int result = memcmp(data1, data2, (size_t)(length * kind)); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & s2_is_unicode) { + goto return_ne; + } else if ((s2 == Py_None) & s1_is_unicode) { + goto return_ne; + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +return_eq: + return (equals == Py_EQ); +return_ne: + return (equals == Py_NE); +#endif +} + +/* fastcall */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s) +{ + Py_ssize_t i, n = __Pyx_PyTuple_GET_SIZE(kwnames); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(n == -1)) return NULL; + #endif + for (i = 0; i < n; i++) + { + PyObject *namei = __Pyx_PyTuple_GET_ITEM(kwnames, i); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(!namei)) return NULL; + #endif + if (s == namei) return kwvalues[i]; + } + for (i = 0; i < n; i++) + { + PyObject *namei = __Pyx_PyTuple_GET_ITEM(kwnames, i); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(!namei)) return NULL; + #endif + int eq = __Pyx_PyUnicode_Equals(s, namei, Py_EQ); + if (unlikely(eq != 0)) { + if (unlikely(eq < 0)) return NULL; + return kwvalues[i]; + } + } + return NULL; +} +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 || CYTHON_COMPILING_IN_LIMITED_API +CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues) { + Py_ssize_t i, nkwargs; + PyObject *dict; +#if !CYTHON_ASSUME_SAFE_SIZE + nkwargs = PyTuple_Size(kwnames); + if (unlikely(nkwargs < 0)) return NULL; +#else + nkwargs = PyTuple_GET_SIZE(kwnames); +#endif + dict = PyDict_New(); + if (unlikely(!dict)) + return NULL; + for (i=0; itp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallMethO (used by PyObjectFastCall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = __Pyx_CyOrPyCFunction_GET_FUNCTION(func); + self = __Pyx_CyOrPyCFunction_GET_SELF(func); + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectFastCall (used by PyObjectCallOneArg) */ +#if PY_VERSION_HEX < 0x03090000 || CYTHON_COMPILING_IN_LIMITED_API +static PyObject* __Pyx_PyObject_FastCall_fallback(PyObject *func, PyObject * const*args, size_t nargs, PyObject *kwargs) { + PyObject *argstuple; + PyObject *result = 0; + size_t i; + argstuple = PyTuple_New((Py_ssize_t)nargs); + if (unlikely(!argstuple)) return NULL; + for (i = 0; i < nargs; i++) { + Py_INCREF(args[i]); + if (__Pyx_PyTuple_SET_ITEM(argstuple, (Py_ssize_t)i, args[i]) != (0)) goto bad; + } + result = __Pyx_PyObject_Call(func, argstuple, kwargs); + bad: + Py_DECREF(argstuple); + return result; +} +#endif +#if CYTHON_VECTORCALL && !CYTHON_COMPILING_IN_LIMITED_API + #if PY_VERSION_HEX < 0x03090000 + #define __Pyx_PyVectorcall_Function(callable) _PyVectorcall_Function(callable) + #elif CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE vectorcallfunc __Pyx_PyVectorcall_Function(PyObject *callable) { + PyTypeObject *tp = Py_TYPE(callable); + #if defined(__Pyx_CyFunction_USED) + if (__Pyx_CyFunction_CheckExact(callable)) { + return __Pyx_CyFunction_func_vectorcall(callable); + } + #endif + if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) { + return NULL; + } + assert(PyCallable_Check(callable)); + Py_ssize_t offset = tp->tp_vectorcall_offset; + assert(offset > 0); + vectorcallfunc ptr; + memcpy(&ptr, (char *) callable + offset, sizeof(ptr)); + return ptr; +} + #else + #define __Pyx_PyVectorcall_Function(callable) PyVectorcall_Function(callable) + #endif +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject *const *args, size_t _nargs, PyObject *kwargs) { + Py_ssize_t nargs = __Pyx_PyVectorcall_NARGS(_nargs); +#if CYTHON_COMPILING_IN_CPYTHON + if (nargs == 0 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_NOARGS)) + return __Pyx_PyObject_CallMethO(func, NULL); + } + else if (nargs == 1 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_O)) + return __Pyx_PyObject_CallMethO(func, args[0]); + } +#endif + if (kwargs == NULL) { + #if CYTHON_VECTORCALL + #if CYTHON_COMPILING_IN_LIMITED_API + return PyObject_Vectorcall(func, args, _nargs, NULL); + #else + vectorcallfunc f = __Pyx_PyVectorcall_Function(func); + if (f) { + return f(func, args, _nargs, NULL); + } + #endif + #endif + } + if (nargs == 0) { + return __Pyx_PyObject_Call(func, __pyx_mstate_global->__pyx_empty_tuple, kwargs); + } + #if PY_VERSION_HEX >= 0x03090000 && !CYTHON_COMPILING_IN_LIMITED_API + return PyObject_VectorcallDict(func, args, (size_t)nargs, kwargs); + #else + return __Pyx_PyObject_FastCall_fallback(func, args, (size_t)nargs, kwargs); + #endif +} + +/* PyObjectCallOneArg (used by CallUnboundCMethod0) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *args[2] = {NULL, arg}; + return __Pyx_PyObject_FastCall(func, args+1, 1 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* UnpackUnboundCMethod (used by CallUnboundCMethod0) */ +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030C0000 +static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject *args, PyObject *kwargs) { + PyObject *result; + PyObject *selfless_args = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); + if (unlikely(!selfless_args)) return NULL; + result = PyObject_Call(method, selfless_args, kwargs); + Py_DECREF(selfless_args); + return result; +} +#elif CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03090000 +static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { + return _PyObject_Vectorcall + (method, args ? args+1 : NULL, nargs ? nargs-1 : 0, kwnames); +} +#else +static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { + return +#if PY_VERSION_HEX < 0x03090000 + _PyObject_Vectorcall +#else + PyObject_Vectorcall +#endif + (method, args ? args+1 : NULL, nargs ? (size_t) nargs-1 : 0, kwnames); +} +#endif +static PyMethodDef __Pyx_UnboundCMethod_Def = { + "CythonUnboundCMethod", + __PYX_REINTERPRET_FUNCION(PyCFunction, __Pyx_SelflessCall), +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030C0000 + METH_VARARGS | METH_KEYWORDS, +#else + METH_FASTCALL | METH_KEYWORDS, +#endif + NULL +}; +static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) { + PyObject *method, *result=NULL; + method = __Pyx_PyObject_GetAttrStr(target->type, *target->method_name); + if (unlikely(!method)) + return -1; + result = method; +#if CYTHON_COMPILING_IN_CPYTHON + if (likely(__Pyx_TypeCheck(method, &PyMethodDescr_Type))) + { + PyMethodDescrObject *descr = (PyMethodDescrObject*) method; + target->func = descr->d_method->ml_meth; + target->flag = descr->d_method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_STACKLESS); + } else +#endif +#if CYTHON_COMPILING_IN_PYPY +#else + if (PyCFunction_Check(method)) +#endif + { + PyObject *self; + int self_found; +#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY + self = PyObject_GetAttrString(method, "__self__"); + if (!self) { + PyErr_Clear(); + } +#else + self = PyCFunction_GET_SELF(method); +#endif + self_found = (self && self != Py_None); +#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY + Py_XDECREF(self); +#endif + if (self_found) { + PyObject *unbound_method = PyCFunction_New(&__Pyx_UnboundCMethod_Def, method); + if (unlikely(!unbound_method)) return -1; + Py_DECREF(method); + result = unbound_method; + } + } +#if !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + if (unlikely(target->method)) { + Py_DECREF(result); + } else +#endif + target->method = result; + return 0; +} + +/* CallUnboundCMethod0 */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self) { + int was_initialized = __Pyx_CachedCFunction_GetAndSetInitializing(cfunc); + if (likely(was_initialized == 2 && cfunc->func)) { + if (likely(cfunc->flag == METH_NOARGS)) + return __Pyx_CallCFunction(cfunc, self, NULL); + if (likely(cfunc->flag == METH_FASTCALL)) + return __Pyx_CallCFunctionFast(cfunc, self, NULL, 0); + if (cfunc->flag == (METH_FASTCALL | METH_KEYWORDS)) + return __Pyx_CallCFunctionFastWithKeywords(cfunc, self, NULL, 0, NULL); + if (likely(cfunc->flag == (METH_VARARGS | METH_KEYWORDS))) + return __Pyx_CallCFunctionWithKeywords(cfunc, self, __pyx_mstate_global->__pyx_empty_tuple, NULL); + if (cfunc->flag == METH_VARARGS) + return __Pyx_CallCFunction(cfunc, self, __pyx_mstate_global->__pyx_empty_tuple); + return __Pyx__CallUnboundCMethod0(cfunc, self); + } +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + else if (unlikely(was_initialized == 1)) { + __Pyx_CachedCFunction tmp_cfunc = { +#ifndef __cplusplus + 0 +#endif + }; + tmp_cfunc.type = cfunc->type; + tmp_cfunc.method_name = cfunc->method_name; + return __Pyx__CallUnboundCMethod0(&tmp_cfunc, self); + } +#endif + PyObject *result = __Pyx__CallUnboundCMethod0(cfunc, self); + __Pyx_CachedCFunction_SetFinishedInitializing(cfunc); + return result; +} +#endif +static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self) { + PyObject *result; + if (unlikely(!cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; + result = __Pyx_PyObject_CallOneArg(cfunc->method, self); + return result; +} + +/* py_dict_items (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d) { + return __Pyx_CallUnboundCMethod0(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_items, d); +} + +/* py_dict_values (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Values(PyObject* d) { + return __Pyx_CallUnboundCMethod0(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_values, d); +} + +/* OwnedDictNext (used by ParseKeywordsImpl) */ +#if CYTHON_AVOID_BORROWED_REFS +static int __Pyx_PyDict_NextRef(PyObject *p, PyObject **ppos, PyObject **pkey, PyObject **pvalue) { + PyObject *next = NULL; + if (!*ppos) { + if (pvalue) { + PyObject *dictview = pkey ? __Pyx_PyDict_Items(p) : __Pyx_PyDict_Values(p); + if (unlikely(!dictview)) goto bad; + *ppos = PyObject_GetIter(dictview); + Py_DECREF(dictview); + } else { + *ppos = PyObject_GetIter(p); + } + if (unlikely(!*ppos)) goto bad; + } + next = PyIter_Next(*ppos); + if (!next) { + if (PyErr_Occurred()) goto bad; + return 0; + } + if (pkey && pvalue) { + *pkey = __Pyx_PySequence_ITEM(next, 0); + if (unlikely(*pkey)) goto bad; + *pvalue = __Pyx_PySequence_ITEM(next, 1); + if (unlikely(*pvalue)) goto bad; + Py_DECREF(next); + } else if (pkey) { + *pkey = next; + } else { + assert(pvalue); + *pvalue = next; + } + return 1; + bad: + Py_XDECREF(next); +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d0000 + PyErr_FormatUnraisable("Exception ignored in __Pyx_PyDict_NextRef"); +#else + PyErr_WriteUnraisable(__pyx_mstate_global->__pyx_n_u_Pyx_PyDict_NextRef); +#endif + if (pkey) *pkey = NULL; + if (pvalue) *pvalue = NULL; + return 0; +} +#else // !CYTHON_AVOID_BORROWED_REFS +static int __Pyx_PyDict_NextRef(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) { + int result = PyDict_Next(p, ppos, pkey, pvalue); + if (likely(result == 1)) { + if (pkey) Py_INCREF(*pkey); + if (pvalue) Py_INCREF(*pvalue); + } + return result; +} +#endif + +/* RaiseDoubleKeywords (used by ParseKeywordsImpl) */ +static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); +} + +/* CallUnboundCMethod2 */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject *__Pyx_CallUnboundCMethod2(__Pyx_CachedCFunction *cfunc, PyObject *self, PyObject *arg1, PyObject *arg2) { + int was_initialized = __Pyx_CachedCFunction_GetAndSetInitializing(cfunc); + if (likely(was_initialized == 2 && cfunc->func)) { + PyObject *args[2] = {arg1, arg2}; + if (cfunc->flag == METH_FASTCALL) { + return __Pyx_CallCFunctionFast(cfunc, self, args, 2); + } + if (cfunc->flag == (METH_FASTCALL | METH_KEYWORDS)) + return __Pyx_CallCFunctionFastWithKeywords(cfunc, self, args, 2, NULL); + } +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + else if (unlikely(was_initialized == 1)) { + __Pyx_CachedCFunction tmp_cfunc = { +#ifndef __cplusplus + 0 +#endif + }; + tmp_cfunc.type = cfunc->type; + tmp_cfunc.method_name = cfunc->method_name; + return __Pyx__CallUnboundCMethod2(&tmp_cfunc, self, arg1, arg2); + } +#endif + PyObject *result = __Pyx__CallUnboundCMethod2(cfunc, self, arg1, arg2); + __Pyx_CachedCFunction_SetFinishedInitializing(cfunc); + return result; +} +#endif +static PyObject* __Pyx__CallUnboundCMethod2(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg1, PyObject* arg2){ + if (unlikely(!cfunc->func && !cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; +#if CYTHON_COMPILING_IN_CPYTHON + if (cfunc->func && (cfunc->flag & METH_VARARGS)) { + PyObject *result = NULL; + PyObject *args = PyTuple_New(2); + if (unlikely(!args)) return NULL; + Py_INCREF(arg1); + PyTuple_SET_ITEM(args, 0, arg1); + Py_INCREF(arg2); + PyTuple_SET_ITEM(args, 1, arg2); + if (cfunc->flag & METH_KEYWORDS) + result = __Pyx_CallCFunctionWithKeywords(cfunc, self, args, NULL); + else + result = __Pyx_CallCFunction(cfunc, self, args); + Py_DECREF(args); + return result; + } +#endif + { + PyObject *args[4] = {NULL, self, arg1, arg2}; + return __Pyx_PyObject_FastCall(cfunc->method, args+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); + } +} + +/* ParseKeywordsImpl (used by ParseKeywords) */ +static int __Pyx_ValidateDuplicatePosArgs( + PyObject *kwds, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + const char* function_name) +{ + PyObject ** const *name = argnames; + while (name != first_kw_arg) { + PyObject *key = **name; + int found = PyDict_Contains(kwds, key); + if (unlikely(found)) { + if (found == 1) __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; + } + name++; + } + return 0; +bad: + return -1; +} +#if CYTHON_USE_UNICODE_INTERNALS +static CYTHON_INLINE int __Pyx_UnicodeKeywordsEqual(PyObject *s1, PyObject *s2) { + int kind; + Py_ssize_t len = PyUnicode_GET_LENGTH(s1); + if (len != PyUnicode_GET_LENGTH(s2)) return 0; + kind = PyUnicode_KIND(s1); + if (kind != PyUnicode_KIND(s2)) return 0; + const void *data1 = PyUnicode_DATA(s1); + const void *data2 = PyUnicode_DATA(s2); + return (memcmp(data1, data2, (size_t) len * (size_t) kind) == 0); +} +#endif +static int __Pyx_MatchKeywordArg_str( + PyObject *key, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + size_t *index_found, + const char *function_name) +{ + PyObject ** const *name; + #if CYTHON_USE_UNICODE_INTERNALS + Py_hash_t key_hash = ((PyASCIIObject*)key)->hash; + if (unlikely(key_hash == -1)) { + key_hash = PyObject_Hash(key); + if (unlikely(key_hash == -1)) + goto bad; + } + #endif + name = first_kw_arg; + while (*name) { + PyObject *name_str = **name; + #if CYTHON_USE_UNICODE_INTERNALS + if (key_hash == ((PyASCIIObject*)name_str)->hash && __Pyx_UnicodeKeywordsEqual(name_str, key)) { + *index_found = (size_t) (name - argnames); + return 1; + } + #else + #if CYTHON_ASSUME_SAFE_SIZE + if (PyUnicode_GET_LENGTH(name_str) == PyUnicode_GET_LENGTH(key)) + #endif + { + int cmp = PyUnicode_Compare(name_str, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + *index_found = (size_t) (name - argnames); + return 1; + } + } + #endif + name++; + } + name = argnames; + while (name != first_kw_arg) { + PyObject *name_str = **name; + #if CYTHON_USE_UNICODE_INTERNALS + if (unlikely(key_hash == ((PyASCIIObject*)name_str)->hash)) { + if (__Pyx_UnicodeKeywordsEqual(name_str, key)) + goto arg_passed_twice; + } + #else + #if CYTHON_ASSUME_SAFE_SIZE + if (PyUnicode_GET_LENGTH(name_str) == PyUnicode_GET_LENGTH(key)) + #endif + { + if (unlikely(name_str == key)) goto arg_passed_twice; + int cmp = PyUnicode_Compare(name_str, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + } + #endif + name++; + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +bad: + return -1; +} +static int __Pyx_MatchKeywordArg_nostr( + PyObject *key, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + size_t *index_found, + const char *function_name) +{ + PyObject ** const *name; + if (unlikely(!PyUnicode_Check(key))) goto invalid_keyword_type; + name = first_kw_arg; + while (*name) { + int cmp = PyObject_RichCompareBool(**name, key, Py_EQ); + if (cmp == 1) { + *index_found = (size_t) (name - argnames); + return 1; + } + if (unlikely(cmp == -1)) goto bad; + name++; + } + name = argnames; + while (name != first_kw_arg) { + int cmp = PyObject_RichCompareBool(**name, key, Py_EQ); + if (unlikely(cmp != 0)) { + if (cmp == 1) goto arg_passed_twice; + else goto bad; + } + name++; + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +bad: + return -1; +} +static CYTHON_INLINE int __Pyx_MatchKeywordArg( + PyObject *key, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + size_t *index_found, + const char *function_name) +{ + return likely(PyUnicode_CheckExact(key)) ? + __Pyx_MatchKeywordArg_str(key, argnames, first_kw_arg, index_found, function_name) : + __Pyx_MatchKeywordArg_nostr(key, argnames, first_kw_arg, index_found, function_name); +} +static void __Pyx_RejectUnknownKeyword( + PyObject *kwds, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + const char *function_name) +{ + #if CYTHON_AVOID_BORROWED_REFS + PyObject *pos = NULL; + #else + Py_ssize_t pos = 0; + #endif + PyObject *key = NULL; + __Pyx_BEGIN_CRITICAL_SECTION(kwds); + while ( + #if CYTHON_AVOID_BORROWED_REFS + __Pyx_PyDict_NextRef(kwds, &pos, &key, NULL) + #else + PyDict_Next(kwds, &pos, &key, NULL) + #endif + ) { + PyObject** const *name = first_kw_arg; + while (*name && (**name != key)) name++; + if (!*name) { + size_t index_found = 0; + int cmp = __Pyx_MatchKeywordArg(key, argnames, first_kw_arg, &index_found, function_name); + if (cmp != 1) { + if (cmp == 0) { + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(key); + #endif + break; + } + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(key); + #endif + } + __Pyx_END_CRITICAL_SECTION(); + #if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(pos); + #endif + assert(PyErr_Occurred()); +} +static int __Pyx_ParseKeywordDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs) +{ + PyObject** const *name; + PyObject** const *first_kw_arg = argnames + num_pos_args; + Py_ssize_t extracted = 0; +#if !CYTHON_COMPILING_IN_PYPY || defined(PyArg_ValidateKeywordArguments) + if (unlikely(!PyArg_ValidateKeywordArguments(kwds))) return -1; +#endif + name = first_kw_arg; + while (*name && num_kwargs > extracted) { + PyObject * key = **name; + PyObject *value; + int found = 0; + #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + found = PyDict_GetItemRef(kwds, key, &value); + #else + value = PyDict_GetItemWithError(kwds, key); + if (value) { + Py_INCREF(value); + found = 1; + } else { + if (unlikely(PyErr_Occurred())) goto bad; + } + #endif + if (found) { + if (unlikely(found < 0)) goto bad; + values[name-argnames] = value; + extracted++; + } + name++; + } + if (num_kwargs > extracted) { + if (ignore_unknown_kwargs) { + if (unlikely(__Pyx_ValidateDuplicatePosArgs(kwds, argnames, first_kw_arg, function_name) == -1)) + goto bad; + } else { + __Pyx_RejectUnknownKeyword(kwds, argnames, first_kw_arg, function_name); + goto bad; + } + } + return 0; +bad: + return -1; +} +static int __Pyx_ParseKeywordDictToDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject** const *name; + PyObject** const *first_kw_arg = argnames + num_pos_args; + Py_ssize_t len; +#if !CYTHON_COMPILING_IN_PYPY || defined(PyArg_ValidateKeywordArguments) + if (unlikely(!PyArg_ValidateKeywordArguments(kwds))) return -1; +#endif + if (PyDict_Update(kwds2, kwds) < 0) goto bad; + name = first_kw_arg; + while (*name) { + PyObject *key = **name; + PyObject *value; +#if !CYTHON_COMPILING_IN_LIMITED_API && (PY_VERSION_HEX >= 0x030d00A2 || defined(PyDict_Pop)) + int found = PyDict_Pop(kwds2, key, &value); + if (found) { + if (unlikely(found < 0)) goto bad; + values[name-argnames] = value; + } +#elif __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + int found = PyDict_GetItemRef(kwds2, key, &value); + if (found) { + if (unlikely(found < 0)) goto bad; + values[name-argnames] = value; + if (unlikely(PyDict_DelItem(kwds2, key) < 0)) goto bad; + } +#else + #if CYTHON_COMPILING_IN_CPYTHON + value = _PyDict_Pop(kwds2, key, kwds2); + #else + value = __Pyx_CallUnboundCMethod2(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_pop, kwds2, key, kwds2); + #endif + if (value == kwds2) { + Py_DECREF(value); + } else { + if (unlikely(!value)) goto bad; + values[name-argnames] = value; + } +#endif + name++; + } + len = PyDict_Size(kwds2); + if (len > 0) { + return __Pyx_ValidateDuplicatePosArgs(kwds, argnames, first_kw_arg, function_name); + } else if (unlikely(len == -1)) { + goto bad; + } + return 0; +bad: + return -1; +} +static int __Pyx_ParseKeywordsTuple( + PyObject *kwds, + PyObject * const *kwvalues, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs) +{ + PyObject *key = NULL; + PyObject** const * name; + PyObject** const *first_kw_arg = argnames + num_pos_args; + for (Py_ssize_t pos = 0; pos < num_kwargs; pos++) { +#if CYTHON_AVOID_BORROWED_REFS + key = __Pyx_PySequence_ITEM(kwds, pos); +#else + key = __Pyx_PyTuple_GET_ITEM(kwds, pos); +#endif +#if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(!key)) goto bad; +#endif + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + PyObject *value = kwvalues[pos]; + values[name-argnames] = __Pyx_NewRef(value); + } else { + size_t index_found = 0; + int cmp = __Pyx_MatchKeywordArg(key, argnames, first_kw_arg, &index_found, function_name); + if (cmp == 1) { + PyObject *value = kwvalues[pos]; + values[index_found] = __Pyx_NewRef(value); + } else { + if (unlikely(cmp == -1)) goto bad; + if (kwds2) { + PyObject *value = kwvalues[pos]; + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else if (!ignore_unknown_kwargs) { + goto invalid_keyword; + } + } + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(key); + key = NULL; + #endif + } + return 0; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + goto bad; +bad: + #if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(key); + #endif + return -1; +} + +/* ParseKeywords */ +static int __Pyx_ParseKeywords( + PyObject *kwds, + PyObject * const *kwvalues, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs) +{ + if (CYTHON_METH_FASTCALL && likely(PyTuple_Check(kwds))) + return __Pyx_ParseKeywordsTuple(kwds, kwvalues, argnames, kwds2, values, num_pos_args, num_kwargs, function_name, ignore_unknown_kwargs); + else if (kwds2) + return __Pyx_ParseKeywordDictToDict(kwds, argnames, kwds2, values, num_pos_args, function_name); + else + return __Pyx_ParseKeywordDict(kwds, argnames, values, num_pos_args, num_kwargs, function_name, ignore_unknown_kwargs); +} + +/* RaiseArgTupleInvalid */ +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* PyDictVersioning (used by GetModuleGlobalName) */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* GetModuleGlobalName */ +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ + PyObject *result; +#if CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(!__pyx_m)) { + if (!PyErr_Occurred()) + PyErr_SetNone(PyExc_NameError); + return NULL; + } + result = PyObject_GetAttr(__pyx_m, name); + if (likely(result)) { + return result; + } + PyErr_Clear(); +#elif CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + if (unlikely(__Pyx_PyDict_GetItemRef(__pyx_mstate_global->__pyx_d, name, &result) == -1)) PyErr_Clear(); + __PYX_UPDATE_DICT_CACHE(__pyx_mstate_global->__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return result; + } +#else + result = _PyDict_GetItem_KnownHash(__pyx_mstate_global->__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_mstate_global->__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); +} + +/* PyLongBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_Fallback___Pyx_PyLong_MultiplyCObj(PyObject *op1, PyObject *op2, int inplace) { + return (inplace ? PyNumber_InPlaceMultiply : PyNumber_Multiply)(op1, op2); +} +#if CYTHON_USE_PYLONG_INTERNALS +static PyObject* __Pyx_Unpacked___Pyx_PyLong_MultiplyCObj(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + const long a = intval; + long b; + const PY_LONG_LONG lla = intval; + PY_LONG_LONG llb; + if (unlikely(__Pyx_PyLong_IsZero(op2))) { + return __Pyx_NewRef(op2); + } + const int is_positive = __Pyx_PyLong_IsPos(op2); + const digit* digits = __Pyx_PyLong_Digits(op2); + const Py_ssize_t size = __Pyx_PyLong_DigitCount(op2); + if (likely(size == 1)) { + b = (long) digits[0]; + if (!is_positive) b *= -1; + } else { + switch (size) { + case 2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT+30) { + b = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) b *= -1; + goto calculate_long; + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT+30) { + llb = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + if (!is_positive) llb *= -1; + goto calculate_long_long; + } + break; + case 3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT+30) { + b = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) b *= -1; + goto calculate_long; + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT+30) { + llb = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + if (!is_positive) llb *= -1; + goto calculate_long_long; + } + break; + case 4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT+30) { + b = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) b *= -1; + goto calculate_long; + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT+30) { + llb = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + if (!is_positive) llb *= -1; + goto calculate_long_long; + } + break; + } + return PyLong_Type.tp_as_number->nb_multiply(op1, op2); + } + calculate_long: + CYTHON_UNUSED_VAR(a); + CYTHON_UNUSED_VAR(b); + llb = b; + goto calculate_long_long; + calculate_long_long: + { + PY_LONG_LONG llx; + llx = lla * llb; + return PyLong_FromLongLong(llx); + } + +} +#endif +static PyObject* __Pyx_Float___Pyx_PyLong_MultiplyCObj(PyObject *float_val, long intval, int zerodivision_check) { + CYTHON_UNUSED_VAR(zerodivision_check); + const long a = intval; + double b = __Pyx_PyFloat_AS_DOUBLE(float_val); + double result; + + result = ((double)a) * (double)b; + return PyFloat_FromDouble(result); +} +static CYTHON_INLINE PyObject* __Pyx_PyLong_MultiplyCObj(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_UNUSED_VAR(zerodivision_check); + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op2))) { + return __Pyx_Unpacked___Pyx_PyLong_MultiplyCObj(op1, op2, intval, inplace, zerodivision_check); + } + #endif + if (PyFloat_CheckExact(op2)) { + return __Pyx_Float___Pyx_PyLong_MultiplyCObj(op2, intval, zerodivision_check); + } + return __Pyx_Fallback___Pyx_PyLong_MultiplyCObj(op1, op2, inplace); +} +#endif + +/* RaiseTooManyValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +/* RaiseNeedMoreValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +/* IterFinish */ +static CYTHON_INLINE int __Pyx_IterFinish(void) { + PyObject* exc_type; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + exc_type = __Pyx_PyErr_CurrentExceptionType(); + if (unlikely(exc_type)) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) + return -1; + __Pyx_PyErr_Clear(); + return 0; + } + return 0; +} + +/* UnpackItemEndCheck */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { + if (unlikely(retval)) { + Py_DECREF(retval); + __Pyx_RaiseTooManyValuesError(expected); + return -1; + } + return __Pyx_IterFinish(); +} + +/* PyLongBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_Fallback___Pyx_PyLong_TrueDivideObjC(PyObject *op1, PyObject *op2, int inplace) { + return (inplace ? PyNumber_InPlaceTrueDivide : PyNumber_TrueDivide)(op1, op2); +} +#if CYTHON_USE_PYLONG_INTERNALS +static PyObject* __Pyx_Unpacked___Pyx_PyLong_TrueDivideObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + const long b = intval; + long a; + if (unlikely(__Pyx_PyLong_IsZero(op1))) { + } + const int is_positive = __Pyx_PyLong_IsPos(op1); + const digit* digits = __Pyx_PyLong_Digits(op1); + const Py_ssize_t size = __Pyx_PyLong_DigitCount(op1); + if (likely(size == 1)) { + a = (long) digits[0]; + if (!is_positive) a *= -1; + } else { + switch (size) { + case 2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT && 1 * PyLong_SHIFT < 53) { + a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) a *= -1; + goto calculate_long; + } + break; + case 3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT && 2 * PyLong_SHIFT < 53) { + a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) a *= -1; + goto calculate_long; + } + break; + case 4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT && 3 * PyLong_SHIFT < 53) { + a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) a *= -1; + goto calculate_long; + } + break; + } + return PyLong_Type.tp_as_number->nb_true_divide(op1, op2); + } + calculate_long: + if ((8 * sizeof(long) <= 53 || likely(labs(a) <= ((PY_LONG_LONG)1 << 53))) + || __Pyx_PyLong_DigitCount(op1) <= 52 / PyLong_SHIFT) { + return PyFloat_FromDouble((double)a / (double)b); + } + return PyLong_Type.tp_as_number->nb_true_divide(op1, op2); +} +#endif +static PyObject* __Pyx_Float___Pyx_PyLong_TrueDivideObjC(PyObject *float_val, long intval, int zerodivision_check) { + CYTHON_UNUSED_VAR(zerodivision_check); + const long b = intval; + double a = __Pyx_PyFloat_AS_DOUBLE(float_val); + double result; + + result = ((double)a) / (double)b; + return PyFloat_FromDouble(result); +} +static CYTHON_INLINE PyObject* __Pyx_PyLong_TrueDivideObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_UNUSED_VAR(zerodivision_check); + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op1))) { + return __Pyx_Unpacked___Pyx_PyLong_TrueDivideObjC(op1, op2, intval, inplace, zerodivision_check); + } + #endif + if (PyFloat_CheckExact(op1)) { + return __Pyx_Float___Pyx_PyLong_TrueDivideObjC(op1, intval, zerodivision_check); + } + return __Pyx_Fallback___Pyx_PyLong_TrueDivideObjC(op1, op2, inplace); +} +#endif + +/* PyLongCompare */ +static CYTHON_INLINE int __Pyx_PyLong_BoolNeObjC(PyObject *op1, PyObject *op2, long intval, long inplace) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_UNUSED_VAR(inplace); + if (op1 == op2) { + return 0; + } + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op1))) { + int unequal; + unsigned long uintval; + Py_ssize_t size = __Pyx_PyLong_DigitCount(op1); + const digit* digits = __Pyx_PyLong_Digits(op1); + if (intval == 0) { + return (__Pyx_PyLong_IsZero(op1) != 1); + } else if (intval < 0) { + if (__Pyx_PyLong_IsNonNeg(op1)) + return 1; + intval = -intval; + } else { + if (__Pyx_PyLong_IsNeg(op1)) + return 1; + } + uintval = (unsigned long) intval; +#if PyLong_SHIFT * 4 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 4)) { + unequal = (size != 5) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[4] != ((uintval >> (4 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 3 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 3)) { + unequal = (size != 4) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 2 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 2)) { + unequal = (size != 3) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 1 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 1)) { + unequal = (size != 2) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif + unequal = (size != 1) || (((unsigned long) digits[0]) != (uintval & (unsigned long) PyLong_MASK)); + return (unequal != 0); + } + #endif + if (PyFloat_CheckExact(op1)) { + const long b = intval; + double a = __Pyx_PyFloat_AS_DOUBLE(op1); + return ((double)a != (double)b); + } + return __Pyx_PyObject_IsTrueAndDecref( + PyObject_RichCompare(op1, op2, Py_NE)); +} + +/* GetItemInt */ +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { + PyObject *r; + if (unlikely(!j)) return NULL; + r = PyObject_GetItem(o, j); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck, int unsafe_shared) { + CYTHON_MAYBE_UNUSED_VAR(unsafe_shared); +#if CYTHON_ASSUME_SAFE_SIZE + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyList_GET_SIZE(o); + } + if ((CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS || !CYTHON_ASSUME_SAFE_MACROS)) { + return __Pyx_PyList_GetItemRefFast(o, wrapped_i, unsafe_shared); + } else + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { + return __Pyx_NewRef(PyList_GET_ITEM(o, wrapped_i)); + } + return __Pyx_GetItemInt_Generic(o, PyLong_FromSsize_t(i)); +#else + (void)wraparound; + (void)boundscheck; + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck, int unsafe_shared) { + CYTHON_MAYBE_UNUSED_VAR(unsafe_shared); +#if CYTHON_ASSUME_SAFE_SIZE && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyTuple_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { + return __Pyx_NewRef(PyTuple_GET_ITEM(o, wrapped_i)); + } + return __Pyx_GetItemInt_Generic(o, PyLong_FromSsize_t(i)); +#else + (void)wraparound; + (void)boundscheck; + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, + int wraparound, int boundscheck, int unsafe_shared) { + CYTHON_MAYBE_UNUSED_VAR(unsafe_shared); +#if CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); + if ((CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS)) { + return __Pyx_PyList_GetItemRefFast(o, n, unsafe_shared); + } else if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { + return __Pyx_NewRef(PyList_GET_ITEM(o, n)); + } + } else + #if !CYTHON_AVOID_BORROWED_REFS + if (PyTuple_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { + return __Pyx_NewRef(PyTuple_GET_ITEM(o, n)); + } + } else + #endif +#endif +#if CYTHON_USE_TYPE_SLOTS && !CYTHON_COMPILING_IN_PYPY + { + PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping; + PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence; + if (!is_list && mm && mm->mp_subscript) { + PyObject *r, *key = PyLong_FromSsize_t(i); + if (unlikely(!key)) return NULL; + r = mm->mp_subscript(o, key); + Py_DECREF(key); + return r; + } + if (is_list || likely(sm && sm->sq_item)) { + if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) { + Py_ssize_t l = sm->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); + } + } + return sm->sq_item(o, i); + } + } +#else + if (is_list || !PyMapping_Check(o)) { + return PySequence_GetItem(o, i); + } +#endif + (void)wraparound; + (void)boundscheck; + return __Pyx_GetItemInt_Generic(o, PyLong_FromSsize_t(i)); +} + +/* ObjectGetItem */ +#if CYTHON_USE_TYPE_SLOTS +static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject *index) { + PyObject *runerr = NULL; + Py_ssize_t key_value; + key_value = __Pyx_PyIndex_AsSsize_t(index); + if (likely(key_value != -1 || !(runerr = PyErr_Occurred()))) { + return __Pyx_GetItemInt_Fast(obj, key_value, 0, 1, 1, 1); + } + if (PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { + __Pyx_TypeName index_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(index)); + PyErr_Clear(); + PyErr_Format(PyExc_IndexError, + "cannot fit '" __Pyx_FMT_TYPENAME "' into an index-sized integer", index_type_name); + __Pyx_DECREF_TypeName(index_type_name); + } + return NULL; +} +static PyObject *__Pyx_PyObject_GetItem_Slow(PyObject *obj, PyObject *key) { + __Pyx_TypeName obj_type_name; + if (likely(PyType_Check(obj))) { + PyObject *meth = __Pyx_PyObject_GetAttrStrNoError(obj, __pyx_mstate_global->__pyx_n_u_class_getitem); + if (!meth) { + PyErr_Clear(); + } else { + PyObject *result = __Pyx_PyObject_CallOneArg(meth, key); + Py_DECREF(meth); + return result; + } + } + obj_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, + "'" __Pyx_FMT_TYPENAME "' object is not subscriptable", obj_type_name); + __Pyx_DECREF_TypeName(obj_type_name); + return NULL; +} +static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject *key) { + PyTypeObject *tp = Py_TYPE(obj); + PyMappingMethods *mm = tp->tp_as_mapping; + PySequenceMethods *sm = tp->tp_as_sequence; + if (likely(mm && mm->mp_subscript)) { + return mm->mp_subscript(obj, key); + } + if (likely(sm && sm->sq_item)) { + return __Pyx_PyObject_GetIndex(obj, key); + } + return __Pyx_PyObject_GetItem_Slow(obj, key); +} +#endif + +/* PyLongCompare */ +static CYTHON_INLINE int __Pyx_PyLong_BoolEqObjC(PyObject *op1, PyObject *op2, long intval, long inplace) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_UNUSED_VAR(inplace); + if (op1 == op2) { + return 1; + } + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op1))) { + int unequal; + unsigned long uintval; + Py_ssize_t size = __Pyx_PyLong_DigitCount(op1); + const digit* digits = __Pyx_PyLong_Digits(op1); + if (intval == 0) { + return (__Pyx_PyLong_IsZero(op1) == 1); + } else if (intval < 0) { + if (__Pyx_PyLong_IsNonNeg(op1)) + return 0; + intval = -intval; + } else { + if (__Pyx_PyLong_IsNeg(op1)) + return 0; + } + uintval = (unsigned long) intval; +#if PyLong_SHIFT * 4 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 4)) { + unequal = (size != 5) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[4] != ((uintval >> (4 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 3 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 3)) { + unequal = (size != 4) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 2 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 2)) { + unequal = (size != 3) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 1 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 1)) { + unequal = (size != 2) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif + unequal = (size != 1) || (((unsigned long) digits[0]) != (uintval & (unsigned long) PyLong_MASK)); + return (unequal == 0); + } + #endif + if (PyFloat_CheckExact(op1)) { + const long b = intval; + double a = __Pyx_PyFloat_AS_DOUBLE(op1); + return ((double)a == (double)b); + } + return __Pyx_PyObject_IsTrueAndDecref( + PyObject_RichCompare(op1, op2, Py_EQ)); +} + +/* RaiseUnboundLocalError */ +static void __Pyx_RaiseUnboundLocalError(const char *varname) { + PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname); +} + +/* GetException (used by pep479) */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) +#endif +{ + PyObject *local_type = NULL, *local_value, *local_tb = NULL; +#if CYTHON_FAST_THREAD_STATE + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if PY_VERSION_HEX >= 0x030C0000 + local_value = tstate->current_exception; + tstate->current_exception = 0; + #else + local_type = tstate->curexc_type; + local_value = tstate->curexc_value; + local_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; + #endif +#elif __PYX_LIMITED_VERSION_HEX > 0x030C0000 + local_value = PyErr_GetRaisedException(); +#else + PyErr_Fetch(&local_type, &local_value, &local_tb); +#endif +#if __PYX_LIMITED_VERSION_HEX > 0x030C0000 + if (likely(local_value)) { + local_type = (PyObject*) Py_TYPE(local_value); + Py_INCREF(local_type); + local_tb = PyException_GetTraceback(local_value); + } +#else + PyErr_NormalizeException(&local_type, &local_value, &local_tb); +#if CYTHON_FAST_THREAD_STATE + if (unlikely(tstate->curexc_type)) +#else + if (unlikely(PyErr_Occurred())) +#endif + goto bad; + if (local_tb) { + if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) + goto bad; + } +#endif // __PYX_LIMITED_VERSION_HEX > 0x030C0000 + Py_XINCREF(local_tb); + Py_XINCREF(local_type); + Py_XINCREF(local_value); + *type = local_type; + *value = local_value; + *tb = local_tb; +#if CYTHON_FAST_THREAD_STATE + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + #if PY_VERSION_HEX >= 0x030B00a4 + tmp_value = exc_info->exc_value; + exc_info->exc_value = local_value; + tmp_type = NULL; + tmp_tb = NULL; + Py_XDECREF(local_type); + Py_XDECREF(local_tb); + #else + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + #endif + } + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = local_type; + tstate->exc_value = local_value; + tstate->exc_traceback = local_tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#elif __PYX_LIMITED_VERSION_HEX >= 0x030b0000 + PyErr_SetHandledException(local_value); + Py_XDECREF(local_value); + Py_XDECREF(local_type); + Py_XDECREF(local_tb); +#else + PyErr_SetExcInfo(local_type, local_value, local_tb); +#endif + return 0; +#if __PYX_LIMITED_VERSION_HEX <= 0x030C0000 +bad: + *type = 0; + *value = 0; + *tb = 0; + Py_XDECREF(local_type); + Py_XDECREF(local_value); + Py_XDECREF(local_tb); + return -1; +#endif +} + +/* pep479 */ +static void __Pyx_Generator_Replace_StopIteration(int in_async_gen) { + PyObject *exc, *val, *tb, *cur_exc, *new_exc; + __Pyx_PyThreadState_declare + int is_async_stopiteration = 0; + CYTHON_MAYBE_UNUSED_VAR(in_async_gen); + __Pyx_PyThreadState_assign + cur_exc = __Pyx_PyErr_CurrentExceptionType(); + if (likely(!__Pyx_PyErr_GivenExceptionMatches(cur_exc, PyExc_StopIteration))) { + if (in_async_gen && unlikely(__Pyx_PyErr_GivenExceptionMatches(cur_exc, PyExc_StopAsyncIteration))) { + is_async_stopiteration = 1; + } else { + return; + } + } + __Pyx_GetException(&exc, &val, &tb); + Py_XDECREF(exc); + Py_XDECREF(tb); + new_exc = PyObject_CallFunction(PyExc_RuntimeError, "s", + is_async_stopiteration ? "async generator raised StopAsyncIteration" : + in_async_gen ? "async generator raised StopIteration" : + "generator raised StopIteration"); + if (!new_exc) { + Py_XDECREF(val); + return; + } + PyException_SetCause(new_exc, val); // steals ref to val + PyErr_SetObject(PyExc_RuntimeError, new_exc); +} + +/* SliceObject */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(PyObject* obj, + Py_ssize_t cstart, Py_ssize_t cstop, + PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice, + int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) { + __Pyx_TypeName obj_type_name; +#if CYTHON_USE_TYPE_SLOTS + PyMappingMethods* mp = Py_TYPE(obj)->tp_as_mapping; + if (likely(mp && mp->mp_subscript)) +#endif + { + PyObject* result; + PyObject *py_slice, *py_start, *py_stop; + if (_py_slice) { + py_slice = *_py_slice; + } else { + PyObject* owned_start = NULL; + PyObject* owned_stop = NULL; + if (_py_start) { + py_start = *_py_start; + } else { + if (has_cstart) { + owned_start = py_start = PyLong_FromSsize_t(cstart); + if (unlikely(!py_start)) goto bad; + } else + py_start = Py_None; + } + if (_py_stop) { + py_stop = *_py_stop; + } else { + if (has_cstop) { + owned_stop = py_stop = PyLong_FromSsize_t(cstop); + if (unlikely(!py_stop)) { + Py_XDECREF(owned_start); + goto bad; + } + } else + py_stop = Py_None; + } + py_slice = PySlice_New(py_start, py_stop, Py_None); + Py_XDECREF(owned_start); + Py_XDECREF(owned_stop); + if (unlikely(!py_slice)) goto bad; + } +#if CYTHON_USE_TYPE_SLOTS + result = mp->mp_subscript(obj, py_slice); +#else + result = PyObject_GetItem(obj, py_slice); +#endif + if (!_py_slice) { + Py_DECREF(py_slice); + } + return result; + } + obj_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, + "'" __Pyx_FMT_TYPENAME "' object is unsliceable", obj_type_name); + __Pyx_DECREF_TypeName(obj_type_name); +bad: + return NULL; +} + +/* SetItemInt */ +static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) { + int r; + if (unlikely(!j)) return -1; + r = PyObject_SetItem(o, j, v); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int is_list, + int wraparound, int boundscheck, int unsafe_shared) { + CYTHON_MAYBE_UNUSED_VAR(unsafe_shared); +#if CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE && !CYTHON_AVOID_BORROWED_REFS + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o)); + if ((CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS && !__Pyx_IS_UNIQUELY_REFERENCED(o, unsafe_shared))) { + Py_INCREF(v); + return PyList_SetItem(o, n, v); + } else if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o)))) { + PyObject* old; + Py_INCREF(v); + old = PyList_GET_ITEM(o, n); + PyList_SET_ITEM(o, n, v); + Py_DECREF(old); + return 0; + } + } else +#endif +#if CYTHON_USE_TYPE_SLOTS && !CYTHON_COMPILING_IN_PYPY + { + PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping; + PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence; + if (!is_list && mm && mm->mp_ass_subscript) { + int r; + PyObject *key = PyLong_FromSsize_t(i); + if (unlikely(!key)) return -1; + r = mm->mp_ass_subscript(o, key, v); + Py_DECREF(key); + return r; + } + if (is_list || likely(sm && sm->sq_ass_item)) { + if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) { + Py_ssize_t l = sm->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return -1; + PyErr_Clear(); + } + } + return sm->sq_ass_item(o, i, v); + } + } +#else + if (is_list || !PyMapping_Check(o)) { + return PySequence_SetItem(o, i, v); + } +#endif + (void)wraparound; + (void)boundscheck; + return __Pyx_SetItemInt_Generic(o, PyLong_FromSsize_t(i), v); +} + +/* CoroutineSetYieldFrom (used by GeneratorYieldFrom) */ +static void +__Pyx_Coroutine_Set_Owned_Yield_From(__pyx_CoroutineObject *gen, PyObject *yf) { + assert (!gen->yieldfrom); +#if CYTHON_USE_AM_SEND + assert (!gen->yieldfrom_am_send); + #if PY_VERSION_HEX < 0x030A00F0 + if (__Pyx_PyType_HasFeature(Py_TYPE(yf), __Pyx_TPFLAGS_HAVE_AM_SEND)) + #endif + { + __Pyx_pyiter_sendfunc am_send; + #if __PYX_LIMITED_VERSION_HEX >= 0x030A0000 + am_send = __Pyx_PyObject_TryGetSubSlot(yf, tp_as_async, am_send, __Pyx_pyiter_sendfunc); + #else + __Pyx_PyAsyncMethodsStruct* tp_as_async = (__Pyx_PyAsyncMethodsStruct*) Py_TYPE(yf)->tp_as_async; + am_send = tp_as_async ? tp_as_async->am_send : NULL; + #endif + if (likely(am_send)) { + gen->yieldfrom_am_send = am_send; + } + } +#endif + gen->yieldfrom = yf; +} + +/* dict_setdefault (used by FetchCommonType) */ +static CYTHON_INLINE PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value) { + PyObject* value; +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX >= 0x030C0000 + PyObject *args[] = {d, key, default_value}; + value = PyObject_VectorcallMethod(__pyx_mstate_global->__pyx_n_u_setdefault, args, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +#elif CYTHON_COMPILING_IN_LIMITED_API + value = PyObject_CallMethodObjArgs(d, __pyx_mstate_global->__pyx_n_u_setdefault, key, default_value, NULL); +#elif PY_VERSION_HEX >= 0x030d0000 + PyDict_SetDefaultRef(d, key, default_value, &value); +#else + value = PyDict_SetDefault(d, key, default_value); + if (unlikely(!value)) return NULL; + Py_INCREF(value); +#endif + return value; +} + +/* LimitedApiGetTypeDict (used by SetItemOnTypeDict) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static Py_ssize_t __Pyx_GetTypeDictOffset(void) { + PyObject *tp_dictoffset_o; + Py_ssize_t tp_dictoffset; + tp_dictoffset_o = PyObject_GetAttrString((PyObject*)(&PyType_Type), "__dictoffset__"); + if (unlikely(!tp_dictoffset_o)) return -1; + tp_dictoffset = PyLong_AsSsize_t(tp_dictoffset_o); + Py_DECREF(tp_dictoffset_o); + if (unlikely(tp_dictoffset == 0)) { + PyErr_SetString( + PyExc_TypeError, + "'type' doesn't have a dictoffset"); + return -1; + } else if (unlikely(tp_dictoffset < 0)) { + PyErr_SetString( + PyExc_TypeError, + "'type' has an unexpected negative dictoffset. " + "Please report this as Cython bug"); + return -1; + } + return tp_dictoffset; +} +static PyObject *__Pyx_GetTypeDict(PyTypeObject *tp) { + static Py_ssize_t tp_dictoffset = 0; + if (unlikely(tp_dictoffset == 0)) { + tp_dictoffset = __Pyx_GetTypeDictOffset(); + if (unlikely(tp_dictoffset == -1 && PyErr_Occurred())) { + tp_dictoffset = 0; // try again next time? + return NULL; + } + } + return *(PyObject**)((char*)tp + tp_dictoffset); +} +#endif + +/* SetItemOnTypeDict (used by FixUpExtensionType) */ +static int __Pyx__SetItemOnTypeDict(PyTypeObject *tp, PyObject *k, PyObject *v) { + int result; + PyObject *tp_dict; +#if CYTHON_COMPILING_IN_LIMITED_API + tp_dict = __Pyx_GetTypeDict(tp); + if (unlikely(!tp_dict)) return -1; +#else + tp_dict = tp->tp_dict; +#endif + result = PyDict_SetItem(tp_dict, k, v); + if (likely(!result)) { + PyType_Modified(tp); + if (unlikely(PyObject_HasAttr(v, __pyx_mstate_global->__pyx_n_u_set_name))) { + PyObject *setNameResult = PyObject_CallMethodObjArgs(v, __pyx_mstate_global->__pyx_n_u_set_name, (PyObject *) tp, k, NULL); + if (!setNameResult) return -1; + Py_DECREF(setNameResult); + } + } + return result; +} + +/* FixUpExtensionType (used by FetchCommonType) */ +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) { +#if __PYX_LIMITED_VERSION_HEX > 0x030900B1 + CYTHON_UNUSED_VAR(spec); + CYTHON_UNUSED_VAR(type); + CYTHON_UNUSED_VAR(__Pyx__SetItemOnTypeDict); +#else + const PyType_Slot *slot = spec->slots; + int changed = 0; +#if !CYTHON_COMPILING_IN_LIMITED_API + while (slot && slot->slot && slot->slot != Py_tp_members) + slot++; + if (slot && slot->slot == Py_tp_members) { +#if !CYTHON_COMPILING_IN_CPYTHON + const +#endif // !CYTHON_COMPILING_IN_CPYTHON) + PyMemberDef *memb = (PyMemberDef*) slot->pfunc; + while (memb && memb->name) { + if (memb->name[0] == '_' && memb->name[1] == '_') { + if (strcmp(memb->name, "__weaklistoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_weaklistoffset = memb->offset; + changed = 1; + } + else if (strcmp(memb->name, "__dictoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_dictoffset = memb->offset; + changed = 1; + } +#if CYTHON_METH_FASTCALL + else if (strcmp(memb->name, "__vectorcalloffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_vectorcall_offset = memb->offset; + changed = 1; + } +#endif // CYTHON_METH_FASTCALL +#if !CYTHON_COMPILING_IN_PYPY + else if (strcmp(memb->name, "__module__") == 0) { + PyObject *descr; + assert(memb->type == T_OBJECT); + assert(memb->flags == 0 || memb->flags == READONLY); + descr = PyDescr_NewMember(type, memb); + if (unlikely(!descr)) + return -1; + int set_item_result = PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr); + Py_DECREF(descr); + if (unlikely(set_item_result < 0)) { + return -1; + } + changed = 1; + } +#endif // !CYTHON_COMPILING_IN_PYPY + } + memb++; + } + } +#endif // !CYTHON_COMPILING_IN_LIMITED_API +#if !CYTHON_COMPILING_IN_PYPY + slot = spec->slots; + while (slot && slot->slot && slot->slot != Py_tp_getset) + slot++; + if (slot && slot->slot == Py_tp_getset) { + PyGetSetDef *getset = (PyGetSetDef*) slot->pfunc; + while (getset && getset->name) { + if (getset->name[0] == '_' && getset->name[1] == '_' && strcmp(getset->name, "__module__") == 0) { + PyObject *descr = PyDescr_NewGetSet(type, getset); + if (unlikely(!descr)) + return -1; + #if CYTHON_COMPILING_IN_LIMITED_API + PyObject *pyname = PyUnicode_FromString(getset->name); + if (unlikely(!pyname)) { + Py_DECREF(descr); + return -1; + } + int set_item_result = __Pyx_SetItemOnTypeDict(type, pyname, descr); + Py_DECREF(pyname); + #else + CYTHON_UNUSED_VAR(__Pyx__SetItemOnTypeDict); + int set_item_result = PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr); + #endif + Py_DECREF(descr); + if (unlikely(set_item_result < 0)) { + return -1; + } + changed = 1; + } + ++getset; + } + } +#else + CYTHON_UNUSED_VAR(__Pyx__SetItemOnTypeDict); +#endif // !CYTHON_COMPILING_IN_PYPY + if (changed) + PyType_Modified(type); +#endif // PY_VERSION_HEX > 0x030900B1 + return 0; +} + +/* AddModuleRef (used by FetchSharedCythonModule) */ +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + static PyObject *__Pyx_PyImport_AddModuleObjectRef(PyObject *name) { + PyObject *module_dict = PyImport_GetModuleDict(); + PyObject *m; + if (PyMapping_GetOptionalItem(module_dict, name, &m) < 0) { + return NULL; + } + if (m != NULL && PyModule_Check(m)) { + return m; + } + Py_XDECREF(m); + m = PyModule_NewObject(name); + if (m == NULL) + return NULL; + if (PyDict_CheckExact(module_dict)) { + PyObject *new_m; + (void)PyDict_SetDefaultRef(module_dict, name, m, &new_m); + Py_DECREF(m); + return new_m; + } else { + if (PyObject_SetItem(module_dict, name, m) != 0) { + Py_DECREF(m); + return NULL; + } + return m; + } + } + static PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *py_name = PyUnicode_FromString(name); + if (!py_name) return NULL; + PyObject *module = __Pyx_PyImport_AddModuleObjectRef(py_name); + Py_DECREF(py_name); + return module; + } +#elif __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#else + static PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *module = PyImport_AddModule(name); + Py_XINCREF(module); + return module; + } +#endif + +/* FetchSharedCythonModule (used by FetchCommonType) */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void) { + return __Pyx_PyImport_AddModuleRef(__PYX_ABI_MODULE_NAME); +} + +/* FetchCommonType (used by CommonTypesMetaclass) */ +#if __PYX_LIMITED_VERSION_HEX < 0x030C0000 +static PyObject* __Pyx_PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *result = __Pyx_PyType_FromModuleAndSpec(module, spec, bases); + if (result && metaclass) { + PyObject *old_tp = (PyObject*)Py_TYPE(result); + Py_INCREF((PyObject*)metaclass); +#if __PYX_LIMITED_VERSION_HEX >= 0x03090000 + Py_SET_TYPE(result, metaclass); +#else + result->ob_type = metaclass; +#endif + Py_DECREF(old_tp); + } + return result; +} +#else +#define __Pyx_PyType_FromMetaclass(me, mo, s, b) PyType_FromMetaclass(me, mo, s, b) +#endif +static int __Pyx_VerifyCachedType(PyObject *cached_type, + const char *name, + Py_ssize_t expected_basicsize) { + Py_ssize_t basicsize; + if (!PyType_Check(cached_type)) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s is not a type object", name); + return -1; + } + if (expected_basicsize == 0) { + return 0; // size is inherited, nothing useful to check + } +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_basicsize; + py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__"); + if (unlikely(!py_basicsize)) return -1; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = NULL; + if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) return -1; +#else + basicsize = ((PyTypeObject*) cached_type)->tp_basicsize; +#endif + if (basicsize != expected_basicsize) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s has the wrong size, try recompiling", + name); + return -1; + } + return 0; +} +static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *abi_module = NULL, *cached_type = NULL, *abi_module_dict, *new_cached_type, *py_object_name; + int get_item_ref_result; + const char* object_name = strrchr(spec->name, '.'); + object_name = object_name ? object_name+1 : spec->name; + py_object_name = PyUnicode_FromString(object_name); + if (!py_object_name) return NULL; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) goto done; + abi_module_dict = PyModule_GetDict(abi_module); + if (!abi_module_dict) goto done; + get_item_ref_result = __Pyx_PyDict_GetItemRef(abi_module_dict, py_object_name, &cached_type); + if (get_item_ref_result == 1) { + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + spec->basicsize) < 0) { + goto bad; + } + goto done; + } else if (unlikely(get_item_ref_result == -1)) { + goto bad; + } + cached_type = __Pyx_PyType_FromMetaclass( + metaclass, + CYTHON_USE_MODULE_STATE ? module : abi_module, + spec, bases); + if (unlikely(!cached_type)) goto bad; + if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad; + new_cached_type = __Pyx_PyDict_SetDefault(abi_module_dict, py_object_name, cached_type); + if (unlikely(new_cached_type != cached_type)) { + if (unlikely(!new_cached_type)) goto bad; + Py_DECREF(cached_type); + cached_type = new_cached_type; + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + spec->basicsize) < 0) { + goto bad; + } + goto done; + } else { + Py_DECREF(new_cached_type); + } +done: + Py_XDECREF(abi_module); + Py_DECREF(py_object_name); + assert(cached_type == NULL || PyType_Check(cached_type)); + return (PyTypeObject *) cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} + +/* CommonTypesMetaclass (used by CoroutineBase) */ +static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) { + return PyUnicode_FromString(__PYX_ABI_MODULE_NAME); +} +#if __PYX_LIMITED_VERSION_HEX < 0x030A0000 +static PyObject* __pyx_CommonTypesMetaclass_call(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *args, CYTHON_UNUSED PyObject *kwds) { + PyErr_SetString(PyExc_TypeError, "Cannot instantiate Cython internal types"); + return NULL; +} +static int __pyx_CommonTypesMetaclass_setattr(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *attr, CYTHON_UNUSED PyObject *value) { + PyErr_SetString(PyExc_TypeError, "Cython internal types are immutable"); + return -1; +} +#endif +static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = { + {"__module__", __pyx_CommonTypesMetaclass_get_module, NULL, NULL, NULL}, + {0, 0, 0, 0, 0} +}; +static PyType_Slot __pyx_CommonTypesMetaclass_slots[] = { + {Py_tp_getset, (void *)__pyx_CommonTypesMetaclass_getset}, + #if __PYX_LIMITED_VERSION_HEX < 0x030A0000 + {Py_tp_call, (void*)__pyx_CommonTypesMetaclass_call}, + {Py_tp_new, (void*)__pyx_CommonTypesMetaclass_call}, + {Py_tp_setattro, (void*)__pyx_CommonTypesMetaclass_setattr}, + #endif + {0, 0} +}; +static PyType_Spec __pyx_CommonTypesMetaclass_spec = { + __PYX_TYPE_MODULE_PREFIX "_common_types_metatype", + 0, + 0, + Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_DEFAULT, + __pyx_CommonTypesMetaclass_slots +}; +static int __pyx_CommonTypesMetaclass_init(PyObject *module) { + __pyx_mstatetype *mstate = __Pyx_PyModule_GetState(module); + PyObject *bases = PyTuple_Pack(1, &PyType_Type); + if (unlikely(!bases)) { + return -1; + } + mstate->__pyx_CommonTypesMetaclassType = __Pyx_FetchCommonTypeFromSpec(NULL, module, &__pyx_CommonTypesMetaclass_spec, bases); + Py_DECREF(bases); + if (unlikely(mstate->__pyx_CommonTypesMetaclassType == NULL)) { + return -1; + } + return 0; +} + +/* RaiseException (used by CoroutineBase) */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyException_SetTraceback(value, tb); +#elif CYTHON_FAST_THREAD_STATE + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} + +/* GetTopmostException (used by SaveResetException) */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * +__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_value == NULL || exc_info->exc_value == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; + } + return exc_info; +} +#endif + +/* SaveResetException (used by CoroutineBase) */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + PyObject *exc_value = exc_info->exc_value; + if (exc_value == NULL || exc_value == Py_None) { + *value = NULL; + *type = NULL; + *tb = NULL; + } else { + *value = exc_value; + Py_INCREF(*value); + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + *tb = PyException_GetTraceback(exc_value); + } + #elif CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + *type = exc_info->exc_type; + *value = exc_info->exc_value; + *tb = exc_info->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #else + *type = tstate->exc_type; + *value = tstate->exc_value; + *tb = tstate->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #endif +} +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = tstate->exc_info; + PyObject *tmp_value = exc_info->exc_value; + exc_info->exc_value = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); + #else + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = type; + exc_info->exc_value = value; + exc_info->exc_traceback = tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = type; + tstate->exc_value = value; + tstate->exc_traceback = tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); + #endif +} +#endif + +/* SwapException (used by CoroutineBase) */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_value = exc_info->exc_value; + exc_info->exc_value = *value; + if (tmp_value == NULL || tmp_value == Py_None) { + Py_XDECREF(tmp_value); + tmp_value = NULL; + tmp_type = NULL; + tmp_tb = NULL; + } else { + tmp_type = (PyObject*) Py_TYPE(tmp_value); + Py_INCREF(tmp_type); + #if CYTHON_COMPILING_IN_CPYTHON + tmp_tb = ((PyBaseExceptionObject*) tmp_value)->traceback; + Py_XINCREF(tmp_tb); + #else + tmp_tb = PyException_GetTraceback(tmp_value); + #endif + } + #elif CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = *type; + exc_info->exc_value = *value; + exc_info->exc_traceback = *tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = *type; + tstate->exc_value = *value; + tstate->exc_traceback = *tb; + #endif + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); + PyErr_SetExcInfo(*type, *value, *tb); + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#endif + +/* CallTypeTraverse (used by CoroutineBase) */ +#if !CYTHON_USE_TYPE_SPECS || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x03090000) +#else +static int __Pyx_call_type_traverse(PyObject *o, int always_call, visitproc visit, void *arg) { + #if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x03090000 + if (__Pyx_get_runtime_version() < 0x03090000) return 0; + #endif + if (!always_call) { + PyTypeObject *base = __Pyx_PyObject_GetSlot(o, tp_base, PyTypeObject*); + unsigned long flags = PyType_GetFlags(base); + if (flags & Py_TPFLAGS_HEAPTYPE) { + return 0; + } + } + Py_VISIT((PyObject*)Py_TYPE(o)); + return 0; +} +#endif + +/* IterNextPlain (used by CoroutineBase) */ +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 +static PyObject *__Pyx_GetBuiltinNext_LimitedAPI(void) { + if (unlikely(!__pyx_mstate_global->__Pyx_GetBuiltinNext_LimitedAPI_cache)) + __pyx_mstate_global->__Pyx_GetBuiltinNext_LimitedAPI_cache = __Pyx_GetBuiltinName(__pyx_mstate_global->__pyx_n_u_next); + return __pyx_mstate_global->__Pyx_GetBuiltinNext_LimitedAPI_cache; +} +#endif +static CYTHON_INLINE PyObject *__Pyx_PyIter_Next_Plain(PyObject *iterator) { +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 + PyObject *result; + PyObject *next = __Pyx_GetBuiltinNext_LimitedAPI(); + if (unlikely(!next)) return NULL; + result = PyObject_CallFunctionObjArgs(next, iterator, NULL); + return result; +#else + (void)__Pyx_GetBuiltinName; // only for early limited API + iternextfunc iternext = __Pyx_PyObject_GetIterNextFunc(iterator); + assert(iternext); + return iternext(iterator); +#endif +} + +/* PyObjectCall2Args (used by PyObjectCallMethod1) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args[3] = {NULL, arg1, arg2}; + return __Pyx_PyObject_FastCall(function, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectGetMethod (used by PyObjectCallMethod1) */ +#if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))) +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { + PyObject *attr; +#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP + __Pyx_TypeName type_name; + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrgetfunc f = NULL; + PyObject **dictptr, *dict; + int meth_found = 0; + assert (*method == NULL); + if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; + } + if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { + return 0; + } + descr = _PyType_Lookup(tp, name); + if (likely(descr != NULL)) { + Py_INCREF(descr); +#if defined(Py_TPFLAGS_METHOD_DESCRIPTOR) && Py_TPFLAGS_METHOD_DESCRIPTOR + if (__Pyx_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)) +#else + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type))) + #endif +#endif + { + meth_found = 1; + } else { + f = Py_TYPE(descr)->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + } + } + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL && (dict = *dictptr) != NULL) { + Py_INCREF(dict); + attr = __Pyx_PyDict_GetItemStr(dict, name); + if (attr != NULL) { + Py_INCREF(attr); + Py_DECREF(dict); + Py_XDECREF(descr); + goto try_unpack; + } + Py_DECREF(dict); + } + if (meth_found) { + *method = descr; + return 1; + } + if (f != NULL) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + if (likely(descr != NULL)) { + *method = descr; + return 0; + } + type_name = __Pyx_PyType_GetFullyQualifiedName(tp); + PyErr_Format(PyExc_AttributeError, + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", + type_name, name); + __Pyx_DECREF_TypeName(type_name); + return 0; +#else + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; +#endif +try_unpack: +#if CYTHON_UNPACK_METHODS + if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { + PyObject *function = PyMethod_GET_FUNCTION(attr); + Py_INCREF(function); + Py_DECREF(attr); + *method = function; + return 1; + } +#endif + *method = attr; + return 0; +} +#endif + +/* PyObjectCallMethod1 (used by CoroutineBase) */ +#if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))) +static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) { + PyObject *result = __Pyx_PyObject_CallOneArg(method, arg); + Py_DECREF(method); + return result; +} +#endif +static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) { +#if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000)) + PyObject *args[2] = {obj, arg}; + (void) __Pyx_PyObject_CallOneArg; + (void) __Pyx_PyObject_Call2Args; + return PyObject_VectorcallMethod(method_name, args, 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +#else + PyObject *method = NULL, *result; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_Call2Args(method, obj, arg); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) return NULL; + return __Pyx__PyObject_CallMethod1(method, arg); +#endif +} + +/* PyObjectCallNoArg (used by CoroutineBase) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { + PyObject *arg[2] = {NULL, NULL}; + return __Pyx_PyObject_FastCall(func, arg + 1, 0 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* ReturnWithStopIteration (used by CoroutineBase) */ +static void __Pyx__ReturnWithStopIteration(PyObject* value, int async); +static CYTHON_INLINE void __Pyx_ReturnWithStopIteration(PyObject* value, int async, int iternext) { + if (value == Py_None) { + if (async || !iternext) + PyErr_SetNone(async ? PyExc_StopAsyncIteration : PyExc_StopIteration); + return; + } + __Pyx__ReturnWithStopIteration(value, async); +} +static void __Pyx__ReturnWithStopIteration(PyObject* value, int async) { +#if CYTHON_COMPILING_IN_CPYTHON + __Pyx_PyThreadState_declare +#endif + PyObject *exc; + PyObject *exc_type = async ? PyExc_StopAsyncIteration : PyExc_StopIteration; +#if CYTHON_COMPILING_IN_CPYTHON + if ((PY_VERSION_HEX >= (0x030C00A6)) || unlikely(PyTuple_Check(value) || PyExceptionInstance_Check(value))) { + if (PY_VERSION_HEX >= (0x030e00A1)) { + exc = __Pyx_PyObject_CallOneArg(exc_type, value); + } else { + PyObject *args_tuple = PyTuple_New(1); + if (unlikely(!args_tuple)) return; + Py_INCREF(value); + PyTuple_SET_ITEM(args_tuple, 0, value); + exc = PyObject_Call(exc_type, args_tuple, NULL); + Py_DECREF(args_tuple); + } + if (unlikely(!exc)) return; + } else { + Py_INCREF(value); + exc = value; + } + #if CYTHON_FAST_THREAD_STATE + __Pyx_PyThreadState_assign + #if CYTHON_USE_EXC_INFO_STACK + if (!__pyx_tstate->exc_info->exc_value) + #else + if (!__pyx_tstate->exc_type) + #endif + { + Py_INCREF(exc_type); + __Pyx_ErrRestore(exc_type, exc, NULL); + return; + } + #endif +#else + exc = __Pyx_PyObject_CallOneArg(exc_type, value); + if (unlikely(!exc)) return; +#endif + PyErr_SetObject(exc_type, exc); + Py_DECREF(exc); +} + +/* CoroutineBase (used by Generator) */ +#if !CYTHON_COMPILING_IN_LIMITED_API +#include +#if PY_VERSION_HEX >= 0x030b00a6 && !defined(PYPY_VERSION) + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif +#endif // CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE void +__Pyx_Coroutine_Undelegate(__pyx_CoroutineObject *gen) { +#if CYTHON_USE_AM_SEND + gen->yieldfrom_am_send = NULL; +#endif + Py_CLEAR(gen->yieldfrom); +} +static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *__pyx_tstate, PyObject **pvalue) { + PyObject *et, *ev, *tb; + PyObject *value = NULL; + CYTHON_UNUSED_VAR(__pyx_tstate); + __Pyx_ErrFetch(&et, &ev, &tb); + if (!et) { + Py_XDECREF(tb); + Py_XDECREF(ev); + Py_INCREF(Py_None); + *pvalue = Py_None; + return 0; + } + if (likely(et == PyExc_StopIteration)) { + if (!ev) { + Py_INCREF(Py_None); + value = Py_None; + } + else if (likely(__Pyx_IS_TYPE(ev, (PyTypeObject*)PyExc_StopIteration))) { + #if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_GRAAL + value = PyObject_GetAttr(ev, __pyx_mstate_global->__pyx_n_u_value); + if (unlikely(!value)) goto limited_api_failure; + #else + value = ((PyStopIterationObject *)ev)->value; + Py_INCREF(value); + #endif + Py_DECREF(ev); + } + else if (unlikely(PyTuple_Check(ev))) { + Py_ssize_t tuple_size = __Pyx_PyTuple_GET_SIZE(ev); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(tuple_size < 0)) { + Py_XDECREF(tb); + Py_DECREF(ev); + Py_DECREF(et); + return -1; + } + #endif + if (tuple_size >= 1) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + value = PyTuple_GET_ITEM(ev, 0); + Py_INCREF(value); +#elif CYTHON_ASSUME_SAFE_MACROS + value = PySequence_ITEM(ev, 0); +#else + value = PySequence_GetItem(ev, 0); + if (!value) goto limited_api_failure; +#endif + } else { + Py_INCREF(Py_None); + value = Py_None; + } + Py_DECREF(ev); + } + else if (!__Pyx_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration)) { + value = ev; + } + if (likely(value)) { + Py_XDECREF(tb); + Py_DECREF(et); + *pvalue = value; + return 0; + } + } else if (!__Pyx_PyErr_GivenExceptionMatches(et, PyExc_StopIteration)) { + __Pyx_ErrRestore(et, ev, tb); + return -1; + } + PyErr_NormalizeException(&et, &ev, &tb); + if (unlikely(!PyObject_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration))) { + __Pyx_ErrRestore(et, ev, tb); + return -1; + } + Py_XDECREF(tb); + Py_DECREF(et); +#if CYTHON_COMPILING_IN_LIMITED_API + value = PyObject_GetAttr(ev, __pyx_mstate_global->__pyx_n_u_value); +#else + value = ((PyStopIterationObject *)ev)->value; + Py_INCREF(value); +#endif + Py_DECREF(ev); +#if CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(!value)) return -1; +#endif + *pvalue = value; + return 0; +#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_GRAAL || !CYTHON_ASSUME_SAFE_MACROS + limited_api_failure: + Py_XDECREF(et); + Py_XDECREF(tb); + Py_XDECREF(ev); + return -1; +#endif +} +static CYTHON_INLINE +__Pyx_PySendResult __Pyx_Coroutine_status_from_result(PyObject **retval) { + if (*retval) { + return PYGEN_NEXT; + } else if (likely(__Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, retval) == 0)) { + return PYGEN_RETURN; + } else { + return PYGEN_ERROR; + } +} +static CYTHON_INLINE +void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *exc_state) { +#if PY_VERSION_HEX >= 0x030B00a4 + Py_CLEAR(exc_state->exc_value); +#else + PyObject *t, *v, *tb; + t = exc_state->exc_type; + v = exc_state->exc_value; + tb = exc_state->exc_traceback; + exc_state->exc_type = NULL; + exc_state->exc_value = NULL; + exc_state->exc_traceback = NULL; + Py_XDECREF(t); + Py_XDECREF(v); + Py_XDECREF(tb); +#endif +} +#define __Pyx_Coroutine_AlreadyRunningError(gen) (__Pyx__Coroutine_AlreadyRunningError(gen), (PyObject*)NULL) +static void __Pyx__Coroutine_AlreadyRunningError(__pyx_CoroutineObject *gen) { + const char *msg; + CYTHON_MAYBE_UNUSED_VAR(gen); + if ((0)) { + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_Coroutine_Check((PyObject*)gen)) { + msg = "coroutine already executing"; + #endif + #ifdef __Pyx_AsyncGen_USED + } else if (__Pyx_AsyncGen_CheckExact((PyObject*)gen)) { + msg = "async generator already executing"; + #endif + } else { + msg = "generator already executing"; + } + PyErr_SetString(PyExc_ValueError, msg); +} +static void __Pyx_Coroutine_AlreadyTerminatedError(PyObject *gen, PyObject *value, int closing) { + CYTHON_MAYBE_UNUSED_VAR(gen); + CYTHON_MAYBE_UNUSED_VAR(closing); + #ifdef __Pyx_Coroutine_USED + if (!closing && __Pyx_Coroutine_Check(gen)) { + PyErr_SetString(PyExc_RuntimeError, "cannot reuse already awaited coroutine"); + } else + #endif + if (value) { + #ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(gen)) + PyErr_SetNone(PyExc_StopAsyncIteration); + else + #endif + PyErr_SetNone(PyExc_StopIteration); + } +} +static +__Pyx_PySendResult __Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value, PyObject **result, int closing) { + __Pyx_PyThreadState_declare + PyThreadState *tstate; + __Pyx_ExcInfoStruct *exc_state; + PyObject *retval; + assert(__Pyx_Coroutine_get_is_running(self)); // Callers should ensure is_running + if (unlikely(self->resume_label == -1)) { + __Pyx_Coroutine_AlreadyTerminatedError((PyObject*)self, value, closing); + return PYGEN_ERROR; + } +#if CYTHON_FAST_THREAD_STATE + __Pyx_PyThreadState_assign + tstate = __pyx_tstate; +#else + tstate = __Pyx_PyThreadState_Current; +#endif + exc_state = &self->gi_exc_state; + if (exc_state->exc_value) { + #if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY + #else + PyObject *exc_tb; + #if PY_VERSION_HEX >= 0x030B00a4 && !CYTHON_COMPILING_IN_CPYTHON + exc_tb = PyException_GetTraceback(exc_state->exc_value); + #elif PY_VERSION_HEX >= 0x030B00a4 + exc_tb = ((PyBaseExceptionObject*) exc_state->exc_value)->traceback; + #else + exc_tb = exc_state->exc_traceback; + #endif + if (exc_tb) { + PyTracebackObject *tb = (PyTracebackObject *) exc_tb; + PyFrameObject *f = tb->tb_frame; + assert(f->f_back == NULL); + #if PY_VERSION_HEX >= 0x030B00A1 + f->f_back = PyThreadState_GetFrame(tstate); + #else + Py_XINCREF(tstate->frame); + f->f_back = tstate->frame; + #endif + #if PY_VERSION_HEX >= 0x030B00a4 && !CYTHON_COMPILING_IN_CPYTHON + Py_DECREF(exc_tb); + #endif + } + #endif + } +#if CYTHON_USE_EXC_INFO_STACK + exc_state->previous_item = tstate->exc_info; + tstate->exc_info = exc_state; +#else + if (exc_state->exc_type) { + __Pyx_ExceptionSwap(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback); + } else { + __Pyx_Coroutine_ExceptionClear(exc_state); + __Pyx_ExceptionSave(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback); + } +#endif + retval = self->body(self, tstate, value); +#if CYTHON_USE_EXC_INFO_STACK + exc_state = &self->gi_exc_state; + tstate->exc_info = exc_state->previous_item; + exc_state->previous_item = NULL; + __Pyx_Coroutine_ResetFrameBackpointer(exc_state); +#endif + *result = retval; + if (self->resume_label == -1) { + return likely(retval) ? PYGEN_RETURN : PYGEN_ERROR; + } + return PYGEN_NEXT; +} +static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API + CYTHON_UNUSED_VAR(exc_state); +#else + PyObject *exc_tb; + #if PY_VERSION_HEX >= 0x030B00a4 + if (!exc_state->exc_value) return; + exc_tb = PyException_GetTraceback(exc_state->exc_value); + #else + exc_tb = exc_state->exc_traceback; + #endif + if (likely(exc_tb)) { + PyTracebackObject *tb = (PyTracebackObject *) exc_tb; + PyFrameObject *f = tb->tb_frame; + Py_CLEAR(f->f_back); + #if PY_VERSION_HEX >= 0x030B00a4 + Py_DECREF(exc_tb); + #endif + } +#endif +} +#define __Pyx_Coroutine_MethodReturnFromResult(gen, result, retval, iternext)\ + ((result) == PYGEN_NEXT ? (retval) : __Pyx__Coroutine_MethodReturnFromResult(gen, result, retval, iternext)) +static PyObject * +__Pyx__Coroutine_MethodReturnFromResult(PyObject* gen, __Pyx_PySendResult result, PyObject *retval, int iternext) { + CYTHON_MAYBE_UNUSED_VAR(gen); + if (likely(result == PYGEN_RETURN)) { + int is_async = 0; + #ifdef __Pyx_AsyncGen_USED + is_async = __Pyx_AsyncGen_CheckExact(gen); + #endif + __Pyx_ReturnWithStopIteration(retval, is_async, iternext); + Py_XDECREF(retval); + } + return NULL; +} +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE +PyObject *__Pyx_PyGen_Send(PyGenObject *gen, PyObject *arg) { +#if PY_VERSION_HEX <= 0x030A00A1 + return _PyGen_Send(gen, arg); +#else + PyObject *result; + if (PyIter_Send((PyObject*)gen, arg ? arg : Py_None, &result) == PYGEN_RETURN) { + if (PyAsyncGen_CheckExact(gen)) { + assert(result == Py_None); + PyErr_SetNone(PyExc_StopAsyncIteration); + } + else if (result == Py_None) { + PyErr_SetNone(PyExc_StopIteration); + } + else { +#if PY_VERSION_HEX < 0x030d00A1 + _PyGen_SetStopIterationValue(result); +#else + if (!PyTuple_Check(result) && !PyExceptionInstance_Check(result)) { + PyErr_SetObject(PyExc_StopIteration, result); + } else { + PyObject *exc = __Pyx_PyObject_CallOneArg(PyExc_StopIteration, result); + if (likely(exc != NULL)) { + PyErr_SetObject(PyExc_StopIteration, exc); + Py_DECREF(exc); + } + } +#endif + } + Py_DECREF(result); + result = NULL; + } + return result; +#endif +} +#endif +static CYTHON_INLINE __Pyx_PySendResult +__Pyx_Coroutine_FinishDelegation(__pyx_CoroutineObject *gen, PyObject** retval) { + __Pyx_PySendResult result; + PyObject *val = NULL; + assert(__Pyx_Coroutine_get_is_running(gen)); + __Pyx_Coroutine_Undelegate(gen); + __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, &val); + result = __Pyx_Coroutine_SendEx(gen, val, retval, 0); + Py_XDECREF(val); + return result; +} +#if CYTHON_USE_AM_SEND +static __Pyx_PySendResult +__Pyx_Coroutine_SendToDelegate(__pyx_CoroutineObject *gen, __Pyx_pyiter_sendfunc gen_am_send, PyObject *value, PyObject **retval) { + PyObject *ret = NULL; + __Pyx_PySendResult delegate_result, result; + assert(__Pyx_Coroutine_get_is_running(gen)); + delegate_result = gen_am_send(gen->yieldfrom, value, &ret); + if (delegate_result == PYGEN_NEXT) { + assert (ret != NULL); + *retval = ret; + return PYGEN_NEXT; + } + assert (delegate_result != PYGEN_ERROR || ret == NULL); + __Pyx_Coroutine_Undelegate(gen); + result = __Pyx_Coroutine_SendEx(gen, ret, retval, 0); + Py_XDECREF(ret); + return result; +} +#endif +static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value) { + PyObject *retval = NULL; + __Pyx_PySendResult result = __Pyx_Coroutine_AmSend(self, value, &retval); + return __Pyx_Coroutine_MethodReturnFromResult(self, result, retval, 0); +} +static __Pyx_PySendResult +__Pyx_Coroutine_AmSend(PyObject *self, PyObject *value, PyObject **retval) { + __Pyx_PySendResult result; + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self; + if (unlikely(__Pyx_Coroutine_test_and_set_is_running(gen))) { + *retval = __Pyx_Coroutine_AlreadyRunningError(gen); + return PYGEN_ERROR; + } + #if CYTHON_USE_AM_SEND + if (gen->yieldfrom_am_send) { + result = __Pyx_Coroutine_SendToDelegate(gen, gen->yieldfrom_am_send, value, retval); + } else + #endif + if (gen->yieldfrom) { + PyObject *yf = gen->yieldfrom; + PyObject *ret; + #if !CYTHON_USE_AM_SEND + #ifdef __Pyx_Generator_USED + if (__Pyx_Generator_CheckExact(yf)) { + ret = __Pyx_Coroutine_Send(yf, value); + } else + #endif + #ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_Check(yf)) { + ret = __Pyx_Coroutine_Send(yf, value); + } else + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_PyAsyncGenASend_CheckExact(yf)) { + ret = __Pyx_async_gen_asend_send(yf, value); + } else + #endif + #if CYTHON_COMPILING_IN_CPYTHON + if (PyGen_CheckExact(yf)) { + ret = __Pyx_PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value); + } else + if (PyCoro_CheckExact(yf)) { + ret = __Pyx_PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value); + } else + #endif + #endif + { + #if !CYTHON_COMPILING_IN_LIMITED_API || __PYX_LIMITED_VERSION_HEX >= 0x03080000 + if (value == Py_None && PyIter_Check(yf)) + ret = __Pyx_PyIter_Next_Plain(yf); + else + #endif + ret = __Pyx_PyObject_CallMethod1(yf, __pyx_mstate_global->__pyx_n_u_send, value); + } + if (likely(ret)) { + __Pyx_Coroutine_unset_is_running(gen); + *retval = ret; + return PYGEN_NEXT; + } + result = __Pyx_Coroutine_FinishDelegation(gen, retval); + } else { + result = __Pyx_Coroutine_SendEx(gen, value, retval, 0); + } + __Pyx_Coroutine_unset_is_running(gen); + return result; +} +static int __Pyx_Coroutine_CloseIter(__pyx_CoroutineObject *gen, PyObject *yf) { + __Pyx_PySendResult result; + PyObject *retval = NULL; + CYTHON_UNUSED_VAR(gen); + assert(__Pyx_Coroutine_get_is_running(gen)); + #ifdef __Pyx_Generator_USED + if (__Pyx_Generator_CheckExact(yf)) { + result = __Pyx_Coroutine_Close(yf, &retval); + } else + #endif + #ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_Check(yf)) { + result = __Pyx_Coroutine_Close(yf, &retval); + } else + if (__Pyx_CoroutineAwait_CheckExact(yf)) { + result = __Pyx_CoroutineAwait_Close((__pyx_CoroutineAwaitObject*)yf); + } else + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_PyAsyncGenASend_CheckExact(yf)) { + retval = __Pyx_async_gen_asend_close(yf, NULL); + result = PYGEN_RETURN; + } else + if (__pyx_PyAsyncGenAThrow_CheckExact(yf)) { + retval = __Pyx_async_gen_athrow_close(yf, NULL); + result = PYGEN_RETURN; + } else + #endif + { + PyObject *meth; + result = PYGEN_RETURN; + meth = __Pyx_PyObject_GetAttrStrNoError(yf, __pyx_mstate_global->__pyx_n_u_close); + if (unlikely(!meth)) { + if (unlikely(PyErr_Occurred())) { + PyErr_WriteUnraisable(yf); + } + } else { + retval = __Pyx_PyObject_CallNoArg(meth); + Py_DECREF(meth); + if (unlikely(!retval)) { + result = PYGEN_ERROR; + } + } + } + Py_XDECREF(retval); + return result == PYGEN_ERROR ? -1 : 0; +} +static PyObject *__Pyx_Generator_Next(PyObject *self) { + __Pyx_PySendResult result; + PyObject *retval = NULL; + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self; + if (unlikely(__Pyx_Coroutine_test_and_set_is_running(gen))) { + return __Pyx_Coroutine_AlreadyRunningError(gen); + } + #if CYTHON_USE_AM_SEND + if (gen->yieldfrom_am_send) { + result = __Pyx_Coroutine_SendToDelegate(gen, gen->yieldfrom_am_send, Py_None, &retval); + } else + #endif + if (gen->yieldfrom) { + PyObject *yf = gen->yieldfrom; + PyObject *ret; + #ifdef __Pyx_Generator_USED + if (__Pyx_Generator_CheckExact(yf)) { + ret = __Pyx_Generator_Next(yf); + } else + #endif + #ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_CheckExact(yf)) { + ret = __Pyx_Coroutine_Send(yf, Py_None); + } else + #endif + #if CYTHON_COMPILING_IN_CPYTHON && (PY_VERSION_HEX < 0x030A00A3 || !CYTHON_USE_AM_SEND) + if (PyGen_CheckExact(yf)) { + ret = __Pyx_PyGen_Send((PyGenObject*)yf, NULL); + } else + #endif + ret = __Pyx_PyIter_Next_Plain(yf); + if (likely(ret)) { + __Pyx_Coroutine_unset_is_running(gen); + return ret; + } + result = __Pyx_Coroutine_FinishDelegation(gen, &retval); + } else { + result = __Pyx_Coroutine_SendEx(gen, Py_None, &retval, 0); + } + __Pyx_Coroutine_unset_is_running(gen); + return __Pyx_Coroutine_MethodReturnFromResult(self, result, retval, 1); +} +static PyObject *__Pyx_Coroutine_Close_Method(PyObject *self, PyObject *arg) { + PyObject *retval = NULL; + __Pyx_PySendResult result; + CYTHON_UNUSED_VAR(arg); + result = __Pyx_Coroutine_Close(self, &retval); + if (unlikely(result == PYGEN_ERROR)) + return NULL; + Py_XDECREF(retval); + Py_RETURN_NONE; +} +static __Pyx_PySendResult +__Pyx_Coroutine_Close(PyObject *self, PyObject **retval) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + __Pyx_PySendResult result; + PyObject *yf; + int err = 0; + if (unlikely(__Pyx_Coroutine_test_and_set_is_running(gen))) { + *retval = __Pyx_Coroutine_AlreadyRunningError(gen); + return PYGEN_ERROR; + } + yf = gen->yieldfrom; + if (yf) { + Py_INCREF(yf); + err = __Pyx_Coroutine_CloseIter(gen, yf); + __Pyx_Coroutine_Undelegate(gen); + Py_DECREF(yf); + } + if (err == 0) + PyErr_SetNone(PyExc_GeneratorExit); + result = __Pyx_Coroutine_SendEx(gen, NULL, retval, 1); + if (result == PYGEN_ERROR) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_Coroutine_unset_is_running(gen); + if (!__Pyx_PyErr_Occurred()) { + return PYGEN_RETURN; + } else if (likely(__Pyx_PyErr_ExceptionMatches2(PyExc_GeneratorExit, PyExc_StopIteration))) { + __Pyx_PyErr_Clear(); + return PYGEN_RETURN; + } + return PYGEN_ERROR; + } else if (likely(result == PYGEN_RETURN && *retval == Py_None)) { + __Pyx_Coroutine_unset_is_running(gen); + return PYGEN_RETURN; + } else { + const char *msg; + Py_DECREF(*retval); + *retval = NULL; + if ((0)) { + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_Coroutine_Check(self)) { + msg = "coroutine ignored GeneratorExit"; + #endif + #ifdef __Pyx_AsyncGen_USED + } else if (__Pyx_AsyncGen_CheckExact(self)) { + msg = "async generator ignored GeneratorExit"; + #endif + } else { + msg = "generator ignored GeneratorExit"; + } + PyErr_SetString(PyExc_RuntimeError, msg); + __Pyx_Coroutine_unset_is_running(gen); + return PYGEN_ERROR; + } +} +static PyObject *__Pyx__Coroutine_Throw(PyObject *self, PyObject *typ, PyObject *val, PyObject *tb, + PyObject *args, int close_on_genexit) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + PyObject *yf; + if (unlikely(__Pyx_Coroutine_test_and_set_is_running(gen))) + return __Pyx_Coroutine_AlreadyRunningError(gen); + yf = gen->yieldfrom; + if (yf) { + __Pyx_PySendResult result; + PyObject *ret; + Py_INCREF(yf); + if (__Pyx_PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) && close_on_genexit) { + int err = __Pyx_Coroutine_CloseIter(gen, yf); + Py_DECREF(yf); + __Pyx_Coroutine_Undelegate(gen); + if (err < 0) + goto propagate_exception; + goto throw_here; + } + if (0 + #ifdef __Pyx_Generator_USED + || __Pyx_Generator_CheckExact(yf) + #endif + #ifdef __Pyx_Coroutine_USED + || __Pyx_Coroutine_Check(yf) + #endif + ) { + ret = __Pyx__Coroutine_Throw(yf, typ, val, tb, args, close_on_genexit); + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_CoroutineAwait_CheckExact(yf)) { + ret = __Pyx__Coroutine_Throw(((__pyx_CoroutineAwaitObject*)yf)->coroutine, typ, val, tb, args, close_on_genexit); + #endif + } else { + PyObject *meth = __Pyx_PyObject_GetAttrStrNoError(yf, __pyx_mstate_global->__pyx_n_u_throw); + if (unlikely(!meth)) { + Py_DECREF(yf); + if (unlikely(PyErr_Occurred())) { + __Pyx_Coroutine_unset_is_running(gen); + return NULL; + } + __Pyx_Coroutine_Undelegate(gen); + goto throw_here; + } + if (likely(args)) { + ret = __Pyx_PyObject_Call(meth, args, NULL); + } else { + PyObject *cargs[4] = {NULL, typ, val, tb}; + ret = __Pyx_PyObject_FastCall(meth, cargs+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); + } + Py_DECREF(meth); + } + Py_DECREF(yf); + if (ret) { + __Pyx_Coroutine_unset_is_running(gen); + return ret; + } + result = __Pyx_Coroutine_FinishDelegation(gen, &ret); + __Pyx_Coroutine_unset_is_running(gen); + return __Pyx_Coroutine_MethodReturnFromResult(self, result, ret, 0); + } +throw_here: + __Pyx_Raise(typ, val, tb, NULL); +propagate_exception: + { + PyObject *retval = NULL; + __Pyx_PySendResult result = __Pyx_Coroutine_SendEx(gen, NULL, &retval, 0); + __Pyx_Coroutine_unset_is_running(gen); + return __Pyx_Coroutine_MethodReturnFromResult(self, result, retval, 0); + } +} +static PyObject *__Pyx_Coroutine_Throw(PyObject *self, PyObject *args) { + PyObject *typ; + PyObject *val = NULL; + PyObject *tb = NULL; + if (unlikely(!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))) + return NULL; + return __Pyx__Coroutine_Throw(self, typ, val, tb, args, 1); +} +static CYTHON_INLINE int __Pyx_Coroutine_traverse_excstate(__Pyx_ExcInfoStruct *exc_state, visitproc visit, void *arg) { +#if PY_VERSION_HEX >= 0x030B00a4 + Py_VISIT(exc_state->exc_value); +#else + Py_VISIT(exc_state->exc_type); + Py_VISIT(exc_state->exc_value); + Py_VISIT(exc_state->exc_traceback); +#endif + return 0; +} +static int __Pyx_Coroutine_traverse(__pyx_CoroutineObject *gen, visitproc visit, void *arg) { + { + int e = __Pyx_call_type_traverse((PyObject*)gen, 1, visit, arg); + if (e) return e; + } + Py_VISIT(gen->closure); + Py_VISIT(gen->classobj); + Py_VISIT(gen->yieldfrom); + return __Pyx_Coroutine_traverse_excstate(&gen->gi_exc_state, visit, arg); +} +static int __Pyx_Coroutine_clear(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + Py_CLEAR(gen->closure); + Py_CLEAR(gen->classobj); + __Pyx_Coroutine_Undelegate(gen); + __Pyx_Coroutine_ExceptionClear(&gen->gi_exc_state); +#ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(self)) { + Py_CLEAR(((__pyx_PyAsyncGenObject*)gen)->ag_finalizer); + } +#endif + Py_CLEAR(gen->gi_code); + Py_CLEAR(gen->gi_frame); + Py_CLEAR(gen->gi_name); + Py_CLEAR(gen->gi_qualname); + Py_CLEAR(gen->gi_modulename); + return 0; +} +static void __Pyx_Coroutine_dealloc(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + PyObject_GC_UnTrack(gen); + #if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + if (gen->gi_weakreflist != NULL) + #endif + PyObject_ClearWeakRefs(self); + if (gen->resume_label >= 0) { + PyObject_GC_Track(self); +#if CYTHON_USE_TP_FINALIZE + if (unlikely(PyObject_CallFinalizerFromDealloc(self))) +#else + { + destructor del = __Pyx_PyObject_GetSlot(gen, tp_del, destructor); + if (del) del(self); + } + if (unlikely(Py_REFCNT(self) > 0)) +#endif + { + return; + } + PyObject_GC_UnTrack(self); + } +#ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(self)) { + /* We have to handle this case for asynchronous generators + right here, because this code has to be between UNTRACK + and GC_Del. */ + Py_CLEAR(((__pyx_PyAsyncGenObject*)self)->ag_finalizer); + } +#endif + __Pyx_Coroutine_clear(self); + __Pyx_PyHeapTypeObject_GC_Del(gen); +} +#if CYTHON_USE_TP_FINALIZE +static void __Pyx_Coroutine_del(PyObject *self) { + PyObject *error_type, *error_value, *error_traceback; + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + __Pyx_PyThreadState_declare + if (gen->resume_label < 0) { + return; + } + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&error_type, &error_value, &error_traceback); +#ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(self)) { + __pyx_PyAsyncGenObject *agen = (__pyx_PyAsyncGenObject*)self; + PyObject *finalizer = agen->ag_finalizer; + if (finalizer && !agen->ag_closed) { + PyObject *res = __Pyx_PyObject_CallOneArg(finalizer, self); + if (unlikely(!res)) { + PyErr_WriteUnraisable(self); + } else { + Py_DECREF(res); + } + __Pyx_ErrRestore(error_type, error_value, error_traceback); + return; + } + } +#endif + if (unlikely(gen->resume_label == 0 && !error_value)) { +#ifdef __Pyx_Coroutine_USED +#ifdef __Pyx_Generator_USED + if (!__Pyx_Generator_CheckExact(self)) +#endif + { + PyObject_GC_UnTrack(self); + if (unlikely(PyErr_WarnFormat(PyExc_RuntimeWarning, 1, "coroutine '%.50S' was never awaited", gen->gi_qualname) < 0)) + PyErr_WriteUnraisable(self); + PyObject_GC_Track(self); + } +#endif + } else { + PyObject *retval = NULL; + __Pyx_PySendResult result = __Pyx_Coroutine_Close(self, &retval); + if (result == PYGEN_ERROR) { + PyErr_WriteUnraisable(self); + } else { + Py_XDECREF(retval); + } + } + __Pyx_ErrRestore(error_type, error_value, error_traceback); +} +#endif +static PyObject * +__Pyx_Coroutine_get_name(__pyx_CoroutineObject *self, void *context) +{ + PyObject *name = self->gi_name; + CYTHON_UNUSED_VAR(context); + if (unlikely(!name)) name = Py_None; + Py_INCREF(name); + return name; +} +static int +__Pyx_Coroutine_set_name(__pyx_CoroutineObject *self, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL || !PyUnicode_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(self->gi_name, value); + return 0; +} +static PyObject * +__Pyx_Coroutine_get_qualname(__pyx_CoroutineObject *self, void *context) +{ + PyObject *name = self->gi_qualname; + CYTHON_UNUSED_VAR(context); + if (unlikely(!name)) name = Py_None; + Py_INCREF(name); + return name; +} +static int +__Pyx_Coroutine_set_qualname(__pyx_CoroutineObject *self, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL || !PyUnicode_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(self->gi_qualname, value); + return 0; +} +static PyObject * +__Pyx__Coroutine_get_frame(__pyx_CoroutineObject *self) +{ +#if !CYTHON_COMPILING_IN_LIMITED_API + PyObject *frame; + #if PY_VERSION_HEX >= 0x030d0000 + Py_BEGIN_CRITICAL_SECTION(self); + #endif + frame = self->gi_frame; + if (!frame) { + if (unlikely(!self->gi_code)) { + Py_RETURN_NONE; + } + PyObject *globals = PyDict_New(); + if (unlikely(!globals)) return NULL; + frame = (PyObject *) PyFrame_New( + PyThreadState_Get(), /*PyThreadState *tstate,*/ + (PyCodeObject*) self->gi_code, /*PyCodeObject *code,*/ + globals, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + Py_DECREF(globals); + if (unlikely(!frame)) + return NULL; + if (unlikely(self->gi_frame)) { + Py_DECREF(frame); + frame = self->gi_frame; + } else { + self->gi_frame = frame; + } + } + Py_INCREF(frame); + #if PY_VERSION_HEX >= 0x030d0000 + Py_END_CRITICAL_SECTION(); + #endif + return frame; +#else + CYTHON_UNUSED_VAR(self); + Py_RETURN_NONE; +#endif +} +static PyObject * +__Pyx_Coroutine_get_frame(__pyx_CoroutineObject *self, void *context) { + CYTHON_UNUSED_VAR(context); + PyObject *frame = self->gi_frame; + if (frame) + return __Pyx_NewRef(frame); + return __Pyx__Coroutine_get_frame(self); +} +static __pyx_CoroutineObject *__Pyx__Coroutine_New( + PyTypeObject* type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name) { + __pyx_CoroutineObject *gen = PyObject_GC_New(__pyx_CoroutineObject, type); + if (unlikely(!gen)) + return NULL; + return __Pyx__Coroutine_NewInit(gen, body, code, closure, name, qualname, module_name); +} +static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit( + __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name) { + gen->body = body; + gen->closure = closure; + Py_XINCREF(closure); + gen->is_running = 0; + gen->resume_label = 0; + gen->classobj = NULL; + gen->yieldfrom = NULL; + gen->yieldfrom_am_send = NULL; + #if PY_VERSION_HEX >= 0x030B00a4 && !CYTHON_COMPILING_IN_LIMITED_API + gen->gi_exc_state.exc_value = NULL; + #else + gen->gi_exc_state.exc_type = NULL; + gen->gi_exc_state.exc_value = NULL; + gen->gi_exc_state.exc_traceback = NULL; + #endif +#if CYTHON_USE_EXC_INFO_STACK + gen->gi_exc_state.previous_item = NULL; +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + gen->gi_weakreflist = NULL; +#endif + Py_XINCREF(qualname); + gen->gi_qualname = qualname; + Py_XINCREF(name); + gen->gi_name = name; + Py_XINCREF(module_name); + gen->gi_modulename = module_name; + Py_XINCREF(code); + gen->gi_code = code; + gen->gi_frame = NULL; + PyObject_GC_Track(gen); + return gen; +} +static char __Pyx_Coroutine_test_and_set_is_running(__pyx_CoroutineObject *gen) { + char result; + #if PY_VERSION_HEX >= 0x030d0000 && !CYTHON_COMPILING_IN_LIMITED_API + Py_BEGIN_CRITICAL_SECTION(gen); + #endif + result = gen->is_running; + gen->is_running = 1; + #if PY_VERSION_HEX >= 0x030d0000 && !CYTHON_COMPILING_IN_LIMITED_API + Py_END_CRITICAL_SECTION(); + #endif + return result; +} +static void __Pyx_Coroutine_unset_is_running(__pyx_CoroutineObject *gen) { + #if PY_VERSION_HEX >= 0x030d0000 && !CYTHON_COMPILING_IN_LIMITED_API + Py_BEGIN_CRITICAL_SECTION(gen); + #endif + assert(gen->is_running); + gen->is_running = 0; + #if PY_VERSION_HEX >= 0x030d0000 && !CYTHON_COMPILING_IN_LIMITED_API + Py_END_CRITICAL_SECTION(); + #endif +} +static char __Pyx_Coroutine_get_is_running(__pyx_CoroutineObject *gen) { + char result; + #if PY_VERSION_HEX >= 0x030d0000 && !CYTHON_COMPILING_IN_LIMITED_API + Py_BEGIN_CRITICAL_SECTION(gen); + #endif + result = gen->is_running; + #if PY_VERSION_HEX >= 0x030d0000 && !CYTHON_COMPILING_IN_LIMITED_API + Py_END_CRITICAL_SECTION(); + #endif + return result; +} +static PyObject *__Pyx_Coroutine_get_is_running_getter(PyObject *gen, void *closure) { + CYTHON_UNUSED_VAR(closure); + char result = __Pyx_Coroutine_get_is_running((__pyx_CoroutineObject*)gen); + if (result) Py_RETURN_TRUE; + else Py_RETURN_FALSE; +} +#if __PYX_HAS_PY_AM_SEND == 2 +static void __Pyx_SetBackportTypeAmSend(PyTypeObject *type, __Pyx_PyAsyncMethodsStruct *static_amsend_methods, __Pyx_pyiter_sendfunc am_send) { + Py_ssize_t ptr_offset = (char*)(type->tp_as_async) - (char*)type; + if (ptr_offset < 0 || ptr_offset > type->tp_basicsize) { + return; + } + memcpy((void*)static_amsend_methods, (void*)(type->tp_as_async), sizeof(*type->tp_as_async)); + static_amsend_methods->am_send = am_send; + type->tp_as_async = __Pyx_SlotTpAsAsync(static_amsend_methods); +} +#endif +static PyObject *__Pyx_Coroutine_fail_reduce_ex(PyObject *self, PyObject *arg) { + CYTHON_UNUSED_VAR(arg); + __Pyx_TypeName self_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE((PyObject*)self)); + PyErr_Format(PyExc_TypeError, "cannot pickle '" __Pyx_FMT_TYPENAME "' object", + self_type_name); + __Pyx_DECREF_TypeName(self_type_name); + return NULL; +} + +/* Generator (used by GeneratorYieldFrom) */ +static PyMethodDef __pyx_Generator_methods[] = { + {"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O, + PyDoc_STR("send(arg) -> send 'arg' into generator,\nreturn next yielded value or raise StopIteration.")}, + {"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS, + PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in generator,\nreturn next yielded value or raise StopIteration.")}, + {"close", (PyCFunction) __Pyx_Coroutine_Close_Method, METH_NOARGS, + PyDoc_STR("close() -> raise GeneratorExit inside generator.")}, + {"__reduce_ex__", (PyCFunction) __Pyx_Coroutine_fail_reduce_ex, METH_O, 0}, + {"__reduce__", (PyCFunction) __Pyx_Coroutine_fail_reduce_ex, METH_NOARGS, 0}, + {0, 0, 0, 0} +}; +static PyMemberDef __pyx_Generator_memberlist[] = { + {"gi_yieldfrom", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY, + PyDoc_STR("object being iterated by 'yield from', or None")}, + {"gi_code", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_code), READONLY, NULL}, + {"__module__", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_modulename), 0, 0}, +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + {"__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CoroutineObject, gi_weakreflist), READONLY, 0}, +#endif + {0, 0, 0, 0, 0} +}; +static PyGetSetDef __pyx_Generator_getsets[] = { + {"__name__", (getter)__Pyx_Coroutine_get_name, (setter)__Pyx_Coroutine_set_name, + PyDoc_STR("name of the generator"), 0}, + {"__qualname__", (getter)__Pyx_Coroutine_get_qualname, (setter)__Pyx_Coroutine_set_qualname, + PyDoc_STR("qualified name of the generator"), 0}, + {"gi_frame", (getter)__Pyx_Coroutine_get_frame, NULL, + PyDoc_STR("Frame of the generator"), 0}, + {"gi_running", __Pyx_Coroutine_get_is_running_getter, NULL, NULL, NULL}, + {0, 0, 0, 0, 0} +}; +static PyType_Slot __pyx_GeneratorType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_Coroutine_dealloc}, + {Py_tp_traverse, (void *)__Pyx_Coroutine_traverse}, + {Py_tp_iter, (void *)PyObject_SelfIter}, + {Py_tp_iternext, (void *)__Pyx_Generator_Next}, + {Py_tp_methods, (void *)__pyx_Generator_methods}, + {Py_tp_members, (void *)__pyx_Generator_memberlist}, + {Py_tp_getset, (void *)__pyx_Generator_getsets}, + {Py_tp_getattro, (void *) PyObject_GenericGetAttr}, +#if CYTHON_USE_TP_FINALIZE + {Py_tp_finalize, (void *)__Pyx_Coroutine_del}, +#endif +#if __PYX_HAS_PY_AM_SEND == 1 + {Py_am_send, (void *)__Pyx_Coroutine_AmSend}, +#endif + {0, 0}, +}; +static PyType_Spec __pyx_GeneratorType_spec = { + __PYX_TYPE_MODULE_PREFIX "generator", + sizeof(__pyx_CoroutineObject), + 0, +#if PY_VERSION_HEX >= 0x030C0000 && !CYTHON_COMPILING_IN_LIMITED_API + Py_TPFLAGS_MANAGED_WEAKREF | +#endif + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | __Pyx_TPFLAGS_HAVE_AM_SEND, + __pyx_GeneratorType_slots +}; +#if __PYX_HAS_PY_AM_SEND == 2 +static __Pyx_PyAsyncMethodsStruct __pyx_Generator_as_async; +#endif +static int __pyx_Generator_init(PyObject *module) { + __pyx_mstatetype *mstate = __Pyx_PyModule_GetState(module); + mstate->__pyx_GeneratorType = __Pyx_FetchCommonTypeFromSpec( + mstate->__pyx_CommonTypesMetaclassType, module, &__pyx_GeneratorType_spec, NULL); + if (unlikely(!mstate->__pyx_GeneratorType)) { + return -1; + } +#if __PYX_HAS_PY_AM_SEND == 2 + __Pyx_SetBackportTypeAmSend(mstate->__pyx_GeneratorType, &__pyx_Generator_as_async, &__Pyx_Coroutine_AmSend); +#endif + return 0; +} +static PyObject *__Pyx_Generator_GetInlinedResult(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self; + PyObject *retval = NULL; + if (unlikely(__Pyx_Coroutine_test_and_set_is_running(gen))) { + return __Pyx_Coroutine_AlreadyRunningError(gen); + } + __Pyx_PySendResult result = __Pyx_Coroutine_SendEx(gen, Py_None, &retval, 0); + __Pyx_Coroutine_unset_is_running(gen); + (void) result; + assert (result == PYGEN_RETURN || result == PYGEN_ERROR); + assert ((result == PYGEN_RETURN && retval != NULL) || (result == PYGEN_ERROR && retval == NULL)); + return retval; +} + +/* GeneratorYieldFrom */ +#if CYTHON_USE_TYPE_SLOTS +static void __Pyx_PyIter_CheckErrorAndDecref(PyObject *source) { + __Pyx_TypeName source_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(source)); + PyErr_Format(PyExc_TypeError, + "iter() returned non-iterator of type '" __Pyx_FMT_TYPENAME "'", source_type_name); + __Pyx_DECREF_TypeName(source_type_name); + Py_DECREF(source); +} +#endif +static CYTHON_INLINE __Pyx_PySendResult __Pyx_Generator_Yield_From(__pyx_CoroutineObject *gen, PyObject *source, PyObject **retval) { + PyObject *source_gen; + __Pyx_PySendResult result; +#ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_Check(source)) { + Py_INCREF(source); + source_gen = source; + result = __Pyx_Coroutine_AmSend(source, Py_None, retval); + } else +#endif + { +#if CYTHON_USE_TYPE_SLOTS + if (likely(Py_TYPE(source)->tp_iter)) { + source_gen = Py_TYPE(source)->tp_iter(source); + if (unlikely(!source_gen)) { + *retval = NULL; + return PYGEN_ERROR; + } + if (unlikely(!PyIter_Check(source_gen))) { + __Pyx_PyIter_CheckErrorAndDecref(source_gen); + *retval = NULL; + return PYGEN_ERROR; + } + } else +#endif + { + source_gen = PyObject_GetIter(source); + if (unlikely(!source_gen)) { + *retval = NULL; + return PYGEN_ERROR; + } + } + *retval = __Pyx_PyIter_Next_Plain(source_gen); + result = __Pyx_Coroutine_status_from_result(retval); + } + if (likely(result == PYGEN_NEXT)) { + __Pyx_Coroutine_Set_Owned_Yield_From(gen, source_gen); + return PYGEN_NEXT; + } + Py_DECREF(source_gen); + return result; +} + +/* append */ +static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x) { + if (likely(PyList_CheckExact(L))) { + if (unlikely(__Pyx_PyList_Append(L, x) < 0)) return -1; + } else { + PyObject* retval = __Pyx_PyObject_CallMethod1(L, __pyx_mstate_global->__pyx_n_u_append, x); + if (unlikely(!retval)) + return -1; + Py_DECREF(retval); + } + return 0; +} + +/* PyLongBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_Fallback___Pyx_PyLong_AddObjC(PyObject *op1, PyObject *op2, int inplace) { + return (inplace ? PyNumber_InPlaceAdd : PyNumber_Add)(op1, op2); +} +#if CYTHON_USE_PYLONG_INTERNALS +static PyObject* __Pyx_Unpacked___Pyx_PyLong_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + const long b = intval; + long a; + const PY_LONG_LONG llb = intval; + PY_LONG_LONG lla; + if (unlikely(__Pyx_PyLong_IsZero(op1))) { + return __Pyx_NewRef(op2); + } + const int is_positive = __Pyx_PyLong_IsPos(op1); + const digit* digits = __Pyx_PyLong_Digits(op1); + const Py_ssize_t size = __Pyx_PyLong_DigitCount(op1); + if (likely(size == 1)) { + a = (long) digits[0]; + if (!is_positive) a *= -1; + } else { + switch (size) { + case 2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) a *= -1; + goto calculate_long; + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + if (!is_positive) lla *= -1; + goto calculate_long_long; + } + break; + case 3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) a *= -1; + goto calculate_long; + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + if (!is_positive) lla *= -1; + goto calculate_long_long; + } + break; + case 4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) a *= -1; + goto calculate_long; + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { + lla = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + if (!is_positive) lla *= -1; + goto calculate_long_long; + } + break; + } + return PyLong_Type.tp_as_number->nb_add(op1, op2); + } + calculate_long: + { + long x; + x = a + b; + return PyLong_FromLong(x); + } + calculate_long_long: + { + PY_LONG_LONG llx; + llx = lla + llb; + return PyLong_FromLongLong(llx); + } + +} +#endif +static PyObject* __Pyx_Float___Pyx_PyLong_AddObjC(PyObject *float_val, long intval, int zerodivision_check) { + CYTHON_UNUSED_VAR(zerodivision_check); + const long b = intval; + double a = __Pyx_PyFloat_AS_DOUBLE(float_val); + double result; + + result = ((double)a) + (double)b; + return PyFloat_FromDouble(result); +} +static CYTHON_INLINE PyObject* __Pyx_PyLong_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_UNUSED_VAR(zerodivision_check); + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op1))) { + return __Pyx_Unpacked___Pyx_PyLong_AddObjC(op1, op2, intval, inplace, zerodivision_check); + } + #endif + if (PyFloat_CheckExact(op1)) { + return __Pyx_Float___Pyx_PyLong_AddObjC(op1, intval, zerodivision_check); + } + return __Pyx_Fallback___Pyx_PyLong_AddObjC(op1, op2, inplace); +} +#endif + +/* py_abs */ +#if CYTHON_USE_PYLONG_INTERNALS +static PyObject *__Pyx_PyLong_AbsNeg(PyObject *n) { +#if PY_VERSION_HEX >= 0x030C00A7 + if (likely(__Pyx_PyLong_IsCompact(n))) { + return PyLong_FromSize_t(__Pyx_PyLong_CompactValueUnsigned(n)); + } +#else + if (likely(Py_SIZE(n) == -1)) { + return PyLong_FromUnsignedLong(__Pyx_PyLong_Digits(n)[0]); + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + { + PyObject *copy = _PyLong_Copy((PyLongObject*)n); + if (likely(copy)) { + #if PY_VERSION_HEX >= 0x030C00A7 + ((PyLongObject*)copy)->long_value.lv_tag ^= ((PyLongObject*)copy)->long_value.lv_tag & _PyLong_SIGN_MASK; + #else + __Pyx_SET_SIZE(copy, -Py_SIZE(copy)); + #endif + } + return copy; + } +#else + return PyNumber_Negative(n); +#endif +} +#endif + +/* PyFloatBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_PyFloat_TrueDivideObjC(PyObject *op1, PyObject *op2, double floatval, int inplace, int zerodivision_check) { + const double b = floatval; + double a, result; + CYTHON_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + if (likely(PyFloat_CheckExact(op1))) { + a = __Pyx_PyFloat_AS_DOUBLE(op1); + + } else + if (likely(PyLong_CheckExact(op1))) { + #if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsZero(op1)) { + a = 0.0; + + } else if (__Pyx_PyLong_IsCompact(op1)) { + a = (double) __Pyx_PyLong_CompactValue(op1); + } else { + const digit* digits = __Pyx_PyLong_Digits(op1); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(op1); + switch (size) { + case -2: + case 2: + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT && ((8 * sizeof(unsigned long) < 53) || (1 * PyLong_SHIFT < 53))) { + a = (double) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if ((8 * sizeof(unsigned long) < 53) || (2 * PyLong_SHIFT < 53) || (a < (double) ((PY_LONG_LONG)1 << 53))) { + if (size == -2) + a = -a; + break; + } + } + CYTHON_FALLTHROUGH; + case -3: + case 3: + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT && ((8 * sizeof(unsigned long) < 53) || (2 * PyLong_SHIFT < 53))) { + a = (double) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if ((8 * sizeof(unsigned long) < 53) || (3 * PyLong_SHIFT < 53) || (a < (double) ((PY_LONG_LONG)1 << 53))) { + if (size == -3) + a = -a; + break; + } + } + CYTHON_FALLTHROUGH; + case -4: + case 4: + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT && ((8 * sizeof(unsigned long) < 53) || (3 * PyLong_SHIFT < 53))) { + a = (double) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if ((8 * sizeof(unsigned long) < 53) || (4 * PyLong_SHIFT < 53) || (a < (double) ((PY_LONG_LONG)1 << 53))) { + if (size == -4) + a = -a; + break; + } + } + CYTHON_FALLTHROUGH; + default: + #endif + a = PyLong_AsDouble(op1); + if (unlikely(a == -1.0 && PyErr_Occurred())) return NULL; + #if CYTHON_USE_PYLONG_INTERNALS + } + } + #endif + } else { + return (inplace ? PyNumber_InPlaceTrueDivide : PyNumber_TrueDivide)(op1, op2); + } + result = a / b; + return PyFloat_FromDouble(result); +} +#endif + +/* pybytes_as_double (used by pynumber_float) */ +static double __Pyx_SlowPyString_AsDouble(PyObject *obj) { + PyObject *float_value = PyFloat_FromString(obj); + if (likely(float_value)) { + double value = __Pyx_PyFloat_AS_DOUBLE(float_value); + Py_DECREF(float_value); + return value; + } + return (double)-1; +} +static const char* __Pyx__PyBytes_AsDouble_Copy(const char* start, char* buffer, Py_ssize_t length) { + int last_was_punctuation = 1; + int parse_error_found = 0; + Py_ssize_t i; + for (i=0; i < length; i++) { + char chr = start[i]; + int is_punctuation = (chr == '_') | (chr == '.') | (chr == 'e') | (chr == 'E'); + *buffer = chr; + buffer += (chr != '_'); + parse_error_found |= last_was_punctuation & is_punctuation; + last_was_punctuation = is_punctuation; + } + parse_error_found |= last_was_punctuation; + *buffer = '\0'; + return unlikely(parse_error_found) ? NULL : buffer; +} +static double __Pyx__PyBytes_AsDouble_inf_nan(const char* start, Py_ssize_t length) { + int matches = 1; + char sign = start[0]; + int is_signed = (sign == '+') | (sign == '-'); + start += is_signed; + length -= is_signed; + switch (start[0]) { + #ifdef Py_NAN + case 'n': + case 'N': + if (unlikely(length != 3)) goto parse_failure; + matches &= (start[1] == 'a' || start[1] == 'A'); + matches &= (start[2] == 'n' || start[2] == 'N'); + if (unlikely(!matches)) goto parse_failure; + return (sign == '-') ? -Py_NAN : Py_NAN; + #endif + case 'i': + case 'I': + if (unlikely(length < 3)) goto parse_failure; + matches &= (start[1] == 'n' || start[1] == 'N'); + matches &= (start[2] == 'f' || start[2] == 'F'); + if (likely(length == 3 && matches)) + return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL; + if (unlikely(length != 8)) goto parse_failure; + matches &= (start[3] == 'i' || start[3] == 'I'); + matches &= (start[4] == 'n' || start[4] == 'N'); + matches &= (start[5] == 'i' || start[5] == 'I'); + matches &= (start[6] == 't' || start[6] == 'T'); + matches &= (start[7] == 'y' || start[7] == 'Y'); + if (unlikely(!matches)) goto parse_failure; + return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL; + case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + break; + default: + goto parse_failure; + } + return 0.0; +parse_failure: + return -1.0; +} +static CYTHON_INLINE int __Pyx__PyBytes_AsDouble_IsSpace(char ch) { + return (ch == 0x20) | !((ch < 0x9) | (ch > 0xd)); +} +CYTHON_UNUSED static double __Pyx__PyBytes_AsDouble(PyObject *obj, const char* start, Py_ssize_t length) { + double value; + Py_ssize_t i, digits; + const char *last = start + length; + char *end; + while (__Pyx__PyBytes_AsDouble_IsSpace(*start)) + start++; + while (start < last - 1 && __Pyx__PyBytes_AsDouble_IsSpace(last[-1])) + last--; + length = last - start; + if (unlikely(length <= 0)) goto fallback; + value = __Pyx__PyBytes_AsDouble_inf_nan(start, length); + if (unlikely(value == -1.0)) goto fallback; + if (value != 0.0) return value; + digits = 0; + for (i=0; i < length; digits += start[i++] != '_'); + if (likely(digits == length)) { + value = PyOS_string_to_double(start, &end, NULL); + } else if (digits < 40) { + char number[40]; + last = __Pyx__PyBytes_AsDouble_Copy(start, number, length); + if (unlikely(!last)) goto fallback; + value = PyOS_string_to_double(number, &end, NULL); + } else { + char *number = (char*) PyMem_Malloc((digits + 1) * sizeof(char)); + if (unlikely(!number)) goto fallback; + last = __Pyx__PyBytes_AsDouble_Copy(start, number, length); + if (unlikely(!last)) { + PyMem_Free(number); + goto fallback; + } + value = PyOS_string_to_double(number, &end, NULL); + PyMem_Free(number); + } + if (likely(end == last) || (value == (double)-1 && PyErr_Occurred())) { + return value; + } +fallback: + return __Pyx_SlowPyString_AsDouble(obj); +} + +/* pynumber_float */ +static CYTHON_INLINE PyObject* __Pyx__PyNumber_Float(PyObject* obj) { + double val; + if (PyLong_CheckExact(obj)) { +#if CYTHON_USE_PYLONG_INTERNALS + if (likely(__Pyx_PyLong_IsCompact(obj))) { + val = (double) __Pyx_PyLong_CompactValue(obj); + goto no_error; + } +#endif + val = PyLong_AsDouble(obj); + } else if (PyUnicode_CheckExact(obj)) { + val = __Pyx_PyUnicode_AsDouble(obj); + } else if (PyBytes_CheckExact(obj)) { + val = __Pyx_PyBytes_AsDouble(obj); + } else if (PyByteArray_CheckExact(obj)) { + val = __Pyx_PyByteArray_AsDouble(obj); + } else { + return PyNumber_Float(obj); + } + if (unlikely(val == -1 && PyErr_Occurred())) { + return NULL; + } +#if CYTHON_USE_PYLONG_INTERNALS +no_error: +#endif + return PyFloat_FromDouble(val); +} + +/* PyFloatBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static int __Pyx_PyFloat_BoolEqObjC(PyObject *op1, PyObject *op2, double floatval, int inplace, int zerodivision_check) { + const double b = floatval; + double a; + CYTHON_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + if (op1 == op2) { + return 1; + } + if (likely(PyFloat_CheckExact(op1))) { + a = __Pyx_PyFloat_AS_DOUBLE(op1); + + } else + if (likely(PyLong_CheckExact(op1))) { + #if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsZero(op1)) { + a = 0.0; + + } else if (__Pyx_PyLong_IsCompact(op1)) { + a = (double) __Pyx_PyLong_CompactValue(op1); + } else { + const digit* digits = __Pyx_PyLong_Digits(op1); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(op1); + switch (size) { + case -2: + case 2: + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT && ((8 * sizeof(unsigned long) < 53) || (1 * PyLong_SHIFT < 53))) { + a = (double) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if ((8 * sizeof(unsigned long) < 53) || (2 * PyLong_SHIFT < 53) || (a < (double) ((PY_LONG_LONG)1 << 53))) { + if (size == -2) + a = -a; + break; + } + } + CYTHON_FALLTHROUGH; + case -3: + case 3: + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT && ((8 * sizeof(unsigned long) < 53) || (2 * PyLong_SHIFT < 53))) { + a = (double) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if ((8 * sizeof(unsigned long) < 53) || (3 * PyLong_SHIFT < 53) || (a < (double) ((PY_LONG_LONG)1 << 53))) { + if (size == -3) + a = -a; + break; + } + } + CYTHON_FALLTHROUGH; + case -4: + case 4: + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT && ((8 * sizeof(unsigned long) < 53) || (3 * PyLong_SHIFT < 53))) { + a = (double) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if ((8 * sizeof(unsigned long) < 53) || (4 * PyLong_SHIFT < 53) || (a < (double) ((PY_LONG_LONG)1 << 53))) { + if (size == -4) + a = -a; + break; + } + } + CYTHON_FALLTHROUGH; + default: + #endif + { + PyObject *res = + #if CYTHON_USE_TYPE_SLOTS || __PYX_LIMITED_VERSION_HEX >= 0x030A0000 + __Pyx_PyType_GetSlot((&PyFloat_Type), tp_richcompare, richcmpfunc) + #else + PyObject_RichCompare + #endif + (op2, op1, + Py_EQ); + return __Pyx_PyObject_IsTrueAndDecref( + res); + } + #if CYTHON_USE_PYLONG_INTERNALS + } + } + #endif + } else { + return __Pyx_PyObject_IsTrueAndDecref( + PyObject_RichCompare(op1, op2, Py_EQ)); + } + if (a == b) { + return 1; + } else { + return 0; + } +} +#endif + +/* PyLongBinop */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject* __Pyx_Fallback___Pyx_PyLong_SubtractCObj(PyObject *op1, PyObject *op2, int inplace) { + return (inplace ? PyNumber_InPlaceSubtract : PyNumber_Subtract)(op1, op2); +} +#if CYTHON_USE_PYLONG_INTERNALS +static PyObject* __Pyx_Unpacked___Pyx_PyLong_SubtractCObj(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(inplace); + CYTHON_UNUSED_VAR(zerodivision_check); + const long a = intval; + long b; + const PY_LONG_LONG lla = intval; + PY_LONG_LONG llb; + if (unlikely(__Pyx_PyLong_IsZero(op2))) { + return __Pyx_NewRef(op1); + } + const int is_positive = __Pyx_PyLong_IsPos(op2); + const digit* digits = __Pyx_PyLong_Digits(op2); + const Py_ssize_t size = __Pyx_PyLong_DigitCount(op2); + if (likely(size == 1)) { + b = (long) digits[0]; + if (!is_positive) b *= -1; + } else { + switch (size) { + case 2: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + b = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) b *= -1; + goto calculate_long; + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { + llb = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + if (!is_positive) llb *= -1; + goto calculate_long_long; + } + break; + case 3: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + b = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) b *= -1; + goto calculate_long; + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { + llb = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + if (!is_positive) llb *= -1; + goto calculate_long_long; + } + break; + case 4: + if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + b = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); + if (!is_positive) b *= -1; + goto calculate_long; + } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { + llb = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); + if (!is_positive) llb *= -1; + goto calculate_long_long; + } + break; + } + return PyLong_Type.tp_as_number->nb_subtract(op1, op2); + } + calculate_long: + { + long x; + x = a - b; + return PyLong_FromLong(x); + } + calculate_long_long: + { + PY_LONG_LONG llx; + llx = lla - llb; + return PyLong_FromLongLong(llx); + } + +} +#endif +static PyObject* __Pyx_Float___Pyx_PyLong_SubtractCObj(PyObject *float_val, long intval, int zerodivision_check) { + CYTHON_UNUSED_VAR(zerodivision_check); + const long a = intval; + double b = __Pyx_PyFloat_AS_DOUBLE(float_val); + double result; + + result = ((double)a) - (double)b; + return PyFloat_FromDouble(result); +} +static CYTHON_INLINE PyObject* __Pyx_PyLong_SubtractCObj(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) { + CYTHON_MAYBE_UNUSED_VAR(intval); + CYTHON_UNUSED_VAR(zerodivision_check); + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op2))) { + return __Pyx_Unpacked___Pyx_PyLong_SubtractCObj(op1, op2, intval, inplace, zerodivision_check); + } + #endif + if (PyFloat_CheckExact(op2)) { + return __Pyx_Float___Pyx_PyLong_SubtractCObj(op2, intval, zerodivision_check); + } + return __Pyx_Fallback___Pyx_PyLong_SubtractCObj(op1, op2, inplace); +} +#endif + +/* PyObjectVectorCallKwBuilder */ +#if CYTHON_VECTORCALL +static int __Pyx_VectorcallBuilder_AddArg(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n) { + (void)__Pyx_PyObject_FastCallDict; + if (__Pyx_PyTuple_SET_ITEM(builder, n, key) != (0)) return -1; + Py_INCREF(key); + args[n] = value; + return 0; +} +CYTHON_UNUSED static int __Pyx_VectorcallBuilder_AddArg_Check(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n) { + (void)__Pyx_VectorcallBuilder_AddArgStr; + if (unlikely(!PyUnicode_Check(key))) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + return -1; + } + return __Pyx_VectorcallBuilder_AddArg(key, value, builder, args, n); +} +static int __Pyx_VectorcallBuilder_AddArgStr(const char *key, PyObject *value, PyObject *builder, PyObject **args, int n) { + PyObject *pyKey = PyUnicode_FromString(key); + if (!pyKey) return -1; + return __Pyx_VectorcallBuilder_AddArg(pyKey, value, builder, args, n); +} +#else // CYTHON_VECTORCALL +CYTHON_UNUSED static int __Pyx_VectorcallBuilder_AddArg_Check(PyObject *key, PyObject *value, PyObject *builder, CYTHON_UNUSED PyObject **args, CYTHON_UNUSED int n) { + if (unlikely(!PyUnicode_Check(key))) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + return -1; + } + return PyDict_SetItem(builder, key, value); +} +#endif + +/* PyObjectFastCallMethod */ +#if !CYTHON_VECTORCALL || PY_VERSION_HEX < 0x03090000 +static PyObject *__Pyx_PyObject_FastCallMethod(PyObject *name, PyObject *const *args, size_t nargsf) { + PyObject *result; + PyObject *attr = PyObject_GetAttr(args[0], name); + if (unlikely(!attr)) + return NULL; + result = __Pyx_PyObject_FastCall(attr, args+1, nargsf - 1); + Py_DECREF(attr); + return result; +} +#endif + +/* RaiseClosureNameError */ +static void __Pyx_RaiseClosureNameError(const char *varname) { + PyErr_Format(PyExc_NameError, "free variable '%s' referenced before assignment in enclosing scope", varname); +} + +/* PyMethodNew (used by CythonFunctionShared) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + PyObject *result; + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + #if __PYX_LIMITED_VERSION_HEX >= 0x030C0000 + { + PyObject *args[] = {func, self}; + result = PyObject_Vectorcall(__pyx_mstate_global->__Pyx_CachedMethodType, args, 2, NULL); + } + #else + result = PyObject_CallFunctionObjArgs(__pyx_mstate_global->__Pyx_CachedMethodType, func, self, NULL); + #endif + return result; +} +#else +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + return PyMethod_New(func, self); +} +#endif + +/* PyVectorcallFastCallDict (used by CythonFunctionShared) */ +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL +static PyObject *__Pyx_PyVectorcall_FastCallDict_kw(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + PyObject *res = NULL; + PyObject *kwnames; + PyObject **newargs; + PyObject **kwvalues; + Py_ssize_t i; + #if CYTHON_AVOID_BORROWED_REFS + PyObject *pos; + #else + Py_ssize_t pos; + #endif + size_t j; + PyObject *key, *value; + unsigned long keys_are_strings; + #if !CYTHON_ASSUME_SAFE_SIZE + Py_ssize_t nkw = PyDict_Size(kw); + if (unlikely(nkw == -1)) return NULL; + #else + Py_ssize_t nkw = PyDict_GET_SIZE(kw); + #endif + newargs = (PyObject **)PyMem_Malloc((nargs + (size_t)nkw) * sizeof(args[0])); + if (unlikely(newargs == NULL)) { + PyErr_NoMemory(); + return NULL; + } + for (j = 0; j < nargs; j++) newargs[j] = args[j]; + kwnames = PyTuple_New(nkw); + if (unlikely(kwnames == NULL)) { + PyMem_Free(newargs); + return NULL; + } + kwvalues = newargs + nargs; + pos = 0; + i = 0; + keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; + while (__Pyx_PyDict_NextRef(kw, &pos, &key, &value)) { + keys_are_strings &= + #if CYTHON_COMPILING_IN_LIMITED_API + PyType_GetFlags(Py_TYPE(key)); + #else + Py_TYPE(key)->tp_flags; + #endif + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(PyTuple_SetItem(kwnames, i, key) < 0)) goto cleanup; + #else + PyTuple_SET_ITEM(kwnames, i, key); + #endif + kwvalues[i] = value; + i++; + } + if (unlikely(!keys_are_strings)) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + goto cleanup; + } + res = vc(func, newargs, nargs, kwnames); +cleanup: + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(pos); + #endif + Py_DECREF(kwnames); + for (i = 0; i < nkw; i++) + Py_DECREF(kwvalues[i]); + PyMem_Free(newargs); + return res; +} +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + Py_ssize_t kw_size = + likely(kw == NULL) ? + 0 : +#if !CYTHON_ASSUME_SAFE_SIZE + PyDict_Size(kw); +#else + PyDict_GET_SIZE(kw); +#endif + if (kw_size == 0) { + return vc(func, args, nargs, NULL); + } +#if !CYTHON_ASSUME_SAFE_SIZE + else if (unlikely(kw_size == -1)) { + return NULL; + } +#endif + return __Pyx_PyVectorcall_FastCallDict_kw(func, vc, args, nargs, kw); +} +#endif + +/* CythonFunctionShared (used by CythonFunction) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunctionNoMethod(PyObject *func, void (*cfunc)(void)) { + if (__Pyx_CyFunction_Check(func)) { + return PyCFunction_GetFunction(((__pyx_CyFunctionObject*)func)->func) == (PyCFunction) cfunc; + } else if (PyCFunction_Check(func)) { + return PyCFunction_GetFunction(func) == (PyCFunction) cfunc; + } + return 0; +} +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void (*cfunc)(void)) { + if ((PyObject*)Py_TYPE(func) == __pyx_mstate_global->__Pyx_CachedMethodType) { + int result; + PyObject *newFunc = PyObject_GetAttr(func, __pyx_mstate_global->__pyx_n_u_func); + if (unlikely(!newFunc)) { + PyErr_Clear(); // It's only an optimization, so don't throw an error + return 0; + } + result = __Pyx__IsSameCyOrCFunctionNoMethod(newFunc, cfunc); + Py_DECREF(newFunc); + return result; + } + return __Pyx__IsSameCyOrCFunctionNoMethod(func, cfunc); +} +#else +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void (*cfunc)(void)) { + if (PyMethod_Check(func)) { + func = PyMethod_GET_FUNCTION(func); + } + return __Pyx_CyOrPyCFunction_Check(func) && __Pyx_CyOrPyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +} +#endif +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj) { +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + __Pyx_Py_XDECREF_SET( + __Pyx_CyFunction_GetClassObj(f), + ((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#else + __Pyx_Py_XDECREF_SET( + ((PyCMethodObject *) (f))->mm_class, + (PyTypeObject*)((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#endif +} +static PyObject * +__Pyx_CyFunction_get_doc_locked(__pyx_CyFunctionObject *op) +{ + if (unlikely(op->func_doc == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_doc = PyObject_GetAttrString(op->func, "__doc__"); + if (unlikely(!op->func_doc)) return NULL; +#else + if (((PyCFunctionObject*)op)->m_ml->ml_doc) { + op->func_doc = PyUnicode_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); + if (unlikely(op->func_doc == NULL)) + return NULL; + } else { + Py_INCREF(Py_None); + return Py_None; + } +#endif + } + Py_INCREF(op->func_doc); + return op->func_doc; +} +static PyObject * +__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure) { + PyObject *result; + CYTHON_UNUSED_VAR(closure); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_doc_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (value == NULL) { + value = Py_None; + } + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_doc, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_name_locked(__pyx_CyFunctionObject *op) +{ + if (unlikely(op->func_name == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_name = PyObject_GetAttrString(op->func, "__name__"); +#else + op->func_name = PyUnicode_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#endif + if (unlikely(op->func_name == NULL)) + return NULL; + } + Py_INCREF(op->func_name); + return op->func_name; +} +static PyObject * +__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, void *context) +{ + PyObject *result = NULL; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_name_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL || !PyUnicode_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_name, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + PyObject *result; + __Pyx_BEGIN_CRITICAL_SECTION(op); + Py_INCREF(op->func_qualname); + result = op->func_qualname; + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL || !PyUnicode_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_qualname, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 +static PyObject * +__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_dict == NULL)) { + op->func_dict = PyDict_New(); + if (unlikely(op->func_dict == NULL)) + return NULL; + } + Py_INCREF(op->func_dict); + return op->func_dict; +} +#endif +static PyObject * +__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_globals); + return op->func_globals; +} +static PyObject * +__Pyx_CyFunction_get_closure(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(op); + CYTHON_UNUSED_VAR(context); + Py_INCREF(Py_None); + return Py_None; +} +static PyObject * +__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, void *context) +{ + PyObject* result = (op->func_code) ? op->func_code : Py_None; + CYTHON_UNUSED_VAR(context); + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { + int result = 0; + PyObject *res = op->defaults_getter((PyObject *) op); + if (unlikely(!res)) + return -1; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + op->defaults_tuple = PyTuple_GET_ITEM(res, 0); + Py_INCREF(op->defaults_tuple); + op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); + Py_INCREF(op->defaults_kwdict); + #else + op->defaults_tuple = __Pyx_PySequence_ITEM(res, 0); + if (unlikely(!op->defaults_tuple)) result = -1; + else { + op->defaults_kwdict = __Pyx_PySequence_ITEM(res, 1); + if (unlikely(!op->defaults_kwdict)) result = -1; + } + #endif + Py_DECREF(res); + return result; +} +static int +__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyTuple_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__defaults__ must be set to a tuple object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__defaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->defaults_tuple, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_defaults_locked(__pyx_CyFunctionObject *op) { + PyObject* result = op->defaults_tuple; + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_tuple; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = NULL; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_defaults_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__kwdefaults__ must be set to a dict object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__kwdefaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->defaults_kwdict, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults_locked(__pyx_CyFunctionObject *op) { + PyObject* result = op->defaults_kwdict; + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_kwdict; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_kwdefaults_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value || value == Py_None) { + value = NULL; + } else if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__annotations__ must be set to a dict object"); + return -1; + } + Py_XINCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_annotations, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_annotations_locked(__pyx_CyFunctionObject *op) { + PyObject* result = op->func_annotations; + if (unlikely(!result)) { + result = PyDict_New(); + if (unlikely(!result)) return NULL; + op->func_annotations = result; + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, void *context) { + PyObject *result; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_annotations_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static PyObject * +__Pyx_CyFunction_get_is_coroutine_value(__pyx_CyFunctionObject *op) { + int is_coroutine = op->flags & __Pyx_CYFUNCTION_COROUTINE; + if (is_coroutine) { + PyObject *is_coroutine_value, *module, *fromlist, *marker = __pyx_mstate_global->__pyx_n_u_is_coroutine; + fromlist = PyList_New(1); + if (unlikely(!fromlist)) return NULL; + Py_INCREF(marker); +#if CYTHON_ASSUME_SAFE_MACROS + PyList_SET_ITEM(fromlist, 0, marker); +#else + if (unlikely(PyList_SetItem(fromlist, 0, marker) < 0)) { + Py_DECREF(marker); + Py_DECREF(fromlist); + return NULL; + } +#endif + module = PyImport_ImportModuleLevelObject(__pyx_mstate_global->__pyx_n_u_asyncio_coroutines, NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + if (unlikely(!module)) goto ignore; + is_coroutine_value = __Pyx_PyObject_GetAttrStr(module, marker); + Py_DECREF(module); + if (likely(is_coroutine_value)) { + return is_coroutine_value; + } +ignore: + PyErr_Clear(); + } + return __Pyx_PyBool_FromLong(is_coroutine); +} +static PyObject * +__Pyx_CyFunction_get_is_coroutine(__pyx_CyFunctionObject *op, void *context) { + PyObject *result; + CYTHON_UNUSED_VAR(context); + if (op->func_is_coroutine) { + return __Pyx_NewRef(op->func_is_coroutine); + } + result = __Pyx_CyFunction_get_is_coroutine_value(op); + if (unlikely(!result)) + return NULL; + __Pyx_BEGIN_CRITICAL_SECTION(op); + if (op->func_is_coroutine) { + Py_DECREF(result); + result = __Pyx_NewRef(op->func_is_coroutine); + } else { + op->func_is_coroutine = __Pyx_NewRef(result); + } + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static void __Pyx_CyFunction_raise_argument_count_error(__pyx_CyFunctionObject *func, const char* message, Py_ssize_t size) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_name = __Pyx_CyFunction_get_name(func, NULL); + if (!py_name) return; + PyErr_Format(PyExc_TypeError, + "%.200S() %s (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, message, size); + Py_DECREF(py_name); +#else + const char* name = ((PyCFunctionObject*)func)->m_ml->ml_name; + PyErr_Format(PyExc_TypeError, + "%.200s() %s (%" CYTHON_FORMAT_SSIZE_T "d given)", + name, message, size); +#endif +} +static void __Pyx_CyFunction_raise_type_error(__pyx_CyFunctionObject *func, const char* message) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_name = __Pyx_CyFunction_get_name(func, NULL); + if (!py_name) return; + PyErr_Format(PyExc_TypeError, + "%.200S() %s", + py_name, message); + Py_DECREF(py_name); +#else + const char* name = ((PyCFunctionObject*)func)->m_ml->ml_name; + PyErr_Format(PyExc_TypeError, + "%.200s() %s", + name, message); +#endif +} +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject * +__Pyx_CyFunction_get_module(__pyx_CyFunctionObject *op, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_GetAttrString(op->func, "__module__"); +} +static int +__Pyx_CyFunction_set_module(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_SetAttrString(op->func, "__module__", value); +} +#endif +static PyGetSetDef __pyx_CyFunction_getsets[] = { + {"func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {"__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {"func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {"__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {"__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 + {"func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)PyObject_GenericSetDict, 0, 0}, + {"__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)PyObject_GenericSetDict, 0, 0}, +#else + {"func_dict", (getter)PyObject_GenericGetDict, (setter)PyObject_GenericSetDict, 0, 0}, + {"__dict__", (getter)PyObject_GenericGetDict, (setter)PyObject_GenericSetDict, 0, 0}, +#endif + {"func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {"__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {"func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {"__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {"func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {"__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {"func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {"__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {"__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, + {"__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, + {"_is_coroutine", (getter)__Pyx_CyFunction_get_is_coroutine, 0, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API + {"__module__", (getter)__Pyx_CyFunction_get_module, (setter)__Pyx_CyFunction_set_module, 0, 0}, +#endif + {0, 0, 0, 0, 0} +}; +static PyMemberDef __pyx_CyFunction_members[] = { +#if !CYTHON_COMPILING_IN_LIMITED_API + {"__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), 0, 0}, +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + {"__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0}, +#endif +#if CYTHON_METH_FASTCALL +#if CYTHON_COMPILING_IN_LIMITED_API + {"__vectorcalloffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_vectorcall), READONLY, 0}, +#else + {"__vectorcalloffset__", T_PYSSIZET, offsetof(PyCFunctionObject, vectorcall), READONLY, 0}, +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + {"__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0}, +#else + {"__weaklistoffset__", T_PYSSIZET, offsetof(PyCFunctionObject, m_weakreflist), READONLY, 0}, +#endif +#endif + {0, 0, 0, 0, 0} +}; +static PyObject * +__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, PyObject *args) +{ + PyObject *result = NULL; + CYTHON_UNUSED_VAR(args); + __Pyx_BEGIN_CRITICAL_SECTION(m); + Py_INCREF(m->func_qualname); + result = m->func_qualname; + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static PyMethodDef __pyx_CyFunction_methods[] = { + {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, + {0, 0, 0, 0} +}; +#if CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) +#else +#define __Pyx_CyFunction_weakreflist(cyfunc) (((PyCFunctionObject*)cyfunc)->m_weakreflist) +#endif +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { +#if !CYTHON_COMPILING_IN_LIMITED_API + PyCFunctionObject *cf = (PyCFunctionObject*) op; +#endif + if (unlikely(op == NULL)) + return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + op->func = PyCFunction_NewEx(ml, (PyObject*)op, module); + if (unlikely(!op->func)) return NULL; +#endif + op->flags = flags; + __Pyx_CyFunction_weakreflist(op) = NULL; +#if !CYTHON_COMPILING_IN_LIMITED_API + cf->m_ml = ml; + cf->m_self = (PyObject *) op; +#endif + Py_XINCREF(closure); + op->func_closure = closure; +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_XINCREF(module); + cf->m_module = module; +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + op->func_dict = NULL; +#endif + op->func_name = NULL; + Py_INCREF(qualname); + op->func_qualname = qualname; + op->func_doc = NULL; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + op->func_classobj = NULL; +#else + ((PyCMethodObject*)op)->mm_class = NULL; +#endif + op->func_globals = globals; + Py_INCREF(op->func_globals); + Py_XINCREF(code); + op->func_code = code; + op->defaults = NULL; + op->defaults_tuple = NULL; + op->defaults_kwdict = NULL; + op->defaults_getter = NULL; + op->func_annotations = NULL; + op->func_is_coroutine = NULL; +#if CYTHON_METH_FASTCALL + switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { + case METH_NOARGS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS; + break; + case METH_O: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O; + break; + case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD; + break; + case METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS; + break; + case METH_VARARGS | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = NULL; + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + Py_DECREF(op); + return NULL; + } +#endif + return (PyObject *) op; +} +static int +__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) +{ + Py_CLEAR(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func); +#else + Py_CLEAR(((PyCFunctionObject*)m)->m_module); +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func_dict); +#elif PY_VERSION_HEX < 0x030d0000 + _PyObject_ClearManagedDict((PyObject*)m); +#else + PyObject_ClearManagedDict((PyObject*)m); +#endif + Py_CLEAR(m->func_name); + Py_CLEAR(m->func_qualname); + Py_CLEAR(m->func_doc); + Py_CLEAR(m->func_globals); + Py_CLEAR(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API +#if PY_VERSION_HEX < 0x030900B1 + Py_CLEAR(__Pyx_CyFunction_GetClassObj(m)); +#else + { + PyObject *cls = (PyObject*) ((PyCMethodObject *) (m))->mm_class; + ((PyCMethodObject *) (m))->mm_class = NULL; + Py_XDECREF(cls); + } +#endif +#endif + Py_CLEAR(m->defaults_tuple); + Py_CLEAR(m->defaults_kwdict); + Py_CLEAR(m->func_annotations); + Py_CLEAR(m->func_is_coroutine); + Py_CLEAR(m->defaults); + return 0; +} +static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + if (__Pyx_CyFunction_weakreflist(m) != NULL) + PyObject_ClearWeakRefs((PyObject *) m); + __Pyx_CyFunction_clear(m); + __Pyx_PyHeapTypeObject_GC_Del(m); +} +static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + PyObject_GC_UnTrack(m); + __Pyx__CyFunction_dealloc(m); +} +static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) +{ + { + int e = __Pyx_call_type_traverse((PyObject*)m, 1, visit, arg); + if (e) return e; + } + Py_VISIT(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func); +#else + Py_VISIT(((PyCFunctionObject*)m)->m_module); +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func_dict); +#else + { + int e = +#if PY_VERSION_HEX < 0x030d0000 + _PyObject_VisitManagedDict +#else + PyObject_VisitManagedDict +#endif + ((PyObject*)m, visit, arg); + if (e != 0) return e; + } +#endif + __Pyx_VISIT_CONST(m->func_name); + __Pyx_VISIT_CONST(m->func_qualname); + Py_VISIT(m->func_doc); + Py_VISIT(m->func_globals); + __Pyx_VISIT_CONST(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(__Pyx_CyFunction_GetClassObj(m)); +#endif + Py_VISIT(m->defaults_tuple); + Py_VISIT(m->defaults_kwdict); + Py_VISIT(m->func_is_coroutine); + Py_VISIT(m->defaults); + return 0; +} +static PyObject* +__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) +{ + PyObject *repr; + __Pyx_BEGIN_CRITICAL_SECTION(op); + repr = PyUnicode_FromFormat("", + op->func_qualname, (void *)op); + __Pyx_END_CRITICAL_SECTION(); + return repr; +} +static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *f = ((__pyx_CyFunctionObject*)func)->func; + PyCFunction meth; + int flags; + meth = PyCFunction_GetFunction(f); + if (unlikely(!meth)) return NULL; + flags = PyCFunction_GetFlags(f); + if (unlikely(flags < 0)) return NULL; +#else + PyCFunctionObject* f = (PyCFunctionObject*)func; + PyCFunction meth = f->m_ml->ml_meth; + int flags = f->m_ml->ml_flags; +#endif + Py_ssize_t size; + switch (flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { + case METH_VARARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) + return (*meth)(self, arg); + break; + case METH_VARARGS | METH_KEYWORDS: + return (*(PyCFunctionWithKeywords)(void(*)(void))meth)(self, arg, kw); + case METH_NOARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_SIZE + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 0)) + return (*meth)(self, NULL); + __Pyx_CyFunction_raise_argument_count_error( + (__pyx_CyFunctionObject*)func, + "takes no arguments", size); + return NULL; + } + break; + case METH_O: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_SIZE + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 1)) { + PyObject *result, *arg0; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + arg0 = PyTuple_GET_ITEM(arg, 0); + #else + arg0 = __Pyx_PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; + #endif + result = (*meth)(self, arg0); + #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(arg0); + #endif + return result; + } + __Pyx_CyFunction_raise_argument_count_error( + (__pyx_CyFunctionObject*)func, + "takes exactly one argument", size); + return NULL; + } + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + return NULL; + } + __Pyx_CyFunction_raise_type_error( + (__pyx_CyFunctionObject*)func, "takes no keyword arguments"); + return NULL; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *self, *result; +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)func)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)func)->m_self; +#endif + result = __Pyx_CyFunction_CallMethod(func, self, arg, kw); + return result; +} +static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) { + PyObject *result; + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL + __pyx_vectorcallfunc vc = __Pyx_CyFunction_func_vectorcall(cyfunc); + if (vc) { +#if CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE + return __Pyx_PyVectorcall_FastCallDict(func, vc, &PyTuple_GET_ITEM(args, 0), (size_t)PyTuple_GET_SIZE(args), kw); +#else + (void) &__Pyx_PyVectorcall_FastCallDict; + return PyVectorcall_Call(func, args, kw); +#endif + } +#endif + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + Py_ssize_t argc; + PyObject *new_args; + PyObject *self; +#if CYTHON_ASSUME_SAFE_SIZE + argc = PyTuple_GET_SIZE(args); +#else + argc = PyTuple_Size(args); + if (unlikely(argc < 0)) return NULL; +#endif + new_args = PyTuple_GetSlice(args, 1, argc); + if (unlikely(!new_args)) + return NULL; + self = PyTuple_GetItem(args, 0); + if (unlikely(!self)) { + Py_DECREF(new_args); + PyErr_Format(PyExc_TypeError, + "unbound method %.200S() needs an argument", + cyfunc->func_qualname); + return NULL; + } + result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw); + Py_DECREF(new_args); + } else { + result = __Pyx_CyFunction_Call(func, args, kw); + } + return result; +} +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL +static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionObject *cyfunc, Py_ssize_t nargs, PyObject *kwnames) +{ + int ret = 0; + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + if (unlikely(nargs < 1)) { + __Pyx_CyFunction_raise_type_error( + cyfunc, "needs an argument"); + return -1; + } + ret = 1; + } + if (unlikely(kwnames) && unlikely(__Pyx_PyTuple_GET_SIZE(kwnames))) { + __Pyx_CyFunction_raise_type_error( + cyfunc, "takes no keyword arguments"); + return -1; + } + return ret; +} +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + if (unlikely(nargs != 0)) { + __Pyx_CyFunction_raise_argument_count_error( + cyfunc, "takes no arguments", nargs); + return NULL; + } + return meth(self, NULL); +} +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + if (unlikely(nargs != 1)) { + __Pyx_CyFunction_raise_argument_count_error( + cyfunc, "takes exactly one argument", nargs); + return NULL; + } + return meth(self, args[0]); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + return ((__Pyx_PyCFunctionFastWithKeywords)(void(*)(void))meth)(self, args, nargs, kwnames); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyTypeObject *cls = (PyTypeObject *) __Pyx_CyFunction_GetClassObj(cyfunc); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + #if PY_VERSION_HEX < 0x030e00A6 + size_t nargs_value = (size_t) nargs; + #else + Py_ssize_t nargs_value = nargs; + #endif + return ((__Pyx_PyCMethod)(void(*)(void))meth)(self, cls, args, nargs_value, kwnames); +} +#endif +static PyType_Slot __pyx_CyFunctionType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc}, + {Py_tp_repr, (void *)__Pyx_CyFunction_repr}, + {Py_tp_call, (void *)__Pyx_CyFunction_CallAsMethod}, + {Py_tp_traverse, (void *)__Pyx_CyFunction_traverse}, + {Py_tp_clear, (void *)__Pyx_CyFunction_clear}, + {Py_tp_methods, (void *)__pyx_CyFunction_methods}, + {Py_tp_members, (void *)__pyx_CyFunction_members}, + {Py_tp_getset, (void *)__pyx_CyFunction_getsets}, + {Py_tp_descr_get, (void *)__Pyx_PyMethod_New}, + {0, 0}, +}; +static PyType_Spec __pyx_CyFunctionType_spec = { + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if CYTHON_METH_FASTCALL +#if defined(Py_TPFLAGS_HAVE_VECTORCALL) + Py_TPFLAGS_HAVE_VECTORCALL | +#elif defined(_Py_TPFLAGS_HAVE_VECTORCALL) + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif +#endif // CYTHON_METH_FASTCALL +#if PY_VERSION_HEX >= 0x030C0000 && !CYTHON_COMPILING_IN_LIMITED_API + Py_TPFLAGS_MANAGED_DICT | +#endif + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + __pyx_CyFunctionType_slots +}; +static int __pyx_CyFunction_init(PyObject *module) { + __pyx_mstatetype *mstate = __Pyx_PyModule_GetState(module); + mstate->__pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec( + mstate->__pyx_CommonTypesMetaclassType, module, &__pyx_CyFunctionType_spec, NULL); + if (unlikely(mstate->__pyx_CyFunctionType == NULL)) { + return -1; + } + return 0; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_InitDefaults(PyObject *func, PyTypeObject *defaults_type) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults = PyObject_CallObject((PyObject*)defaults_type, NULL); // _PyObject_New(defaults_type); + if (unlikely(!m->defaults)) + return NULL; + return m->defaults; +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_tuple = tuple; + Py_INCREF(tuple); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_kwdict = dict; + Py_INCREF(dict); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->func_annotations = dict; + Py_INCREF(dict); +} + +/* CythonFunction */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { + PyObject *op = __Pyx_CyFunction_Init( + PyObject_GC_New(__pyx_CyFunctionObject, __pyx_mstate_global->__pyx_CyFunctionType), + ml, flags, qualname, closure, module, globals, code + ); + if (likely(op)) { + PyObject_GC_Track(op); + } + return op; +} + +/* pyfrozenset_new (used by PySetContains) */ +static CYTHON_INLINE PyObject* __Pyx_PyFrozenSet_New(PyObject* it) { + if (it) { + PyObject* result; +#if CYTHON_COMPILING_IN_PYPY + PyObject* args; + args = PyTuple_Pack(1, it); + if (unlikely(!args)) + return NULL; + result = PyObject_Call((PyObject*)&PyFrozenSet_Type, args, NULL); + Py_DECREF(args); + return result; +#else + if (PyFrozenSet_CheckExact(it)) { + Py_INCREF(it); + return it; + } + result = PyFrozenSet_New(it); + if (unlikely(!result)) + return NULL; + if ((__PYX_LIMITED_VERSION_HEX >= 0x030A0000) +#if CYTHON_COMPILING_IN_LIMITED_API + || __Pyx_get_runtime_version() >= 0x030A0000 +#endif + ) + return result; + { + Py_ssize_t size = __Pyx_PySet_GET_SIZE(result); + if (likely(size > 0)) + return result; +#if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(size < 0)) { + Py_DECREF(result); + return NULL; + } +#endif + } + Py_DECREF(result); +#endif + } + return __Pyx_PyObject_CallNoArg((PyObject*) &PyFrozenSet_Type); +} + +/* PySetContains */ +static int __Pyx_PySet_ContainsUnhashable(PyObject *set, PyObject *key) { + int result = -1; + if (PySet_Check(key) && PyErr_ExceptionMatches(PyExc_TypeError)) { + PyObject *tmpkey; + PyErr_Clear(); + tmpkey = __Pyx_PyFrozenSet_New(key); + if (tmpkey != NULL) { + result = PySet_Contains(set, tmpkey); + Py_DECREF(tmpkey); + } + } + return result; +} +static CYTHON_INLINE int __Pyx_PySet_ContainsTF(PyObject* key, PyObject* set, int eq) { + int result = PySet_Contains(set, key); + if (unlikely(result < 0)) { + result = __Pyx_PySet_ContainsUnhashable(set, key); + } + return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); +} + +/* AllocateExtensionType */ +static PyObject *__Pyx_AllocateExtensionType(PyTypeObject *t, int is_final) { + if (is_final || likely(!__Pyx_PyType_HasFeature(t, Py_TPFLAGS_IS_ABSTRACT))) { + allocfunc alloc_func = __Pyx_PyType_GetSlot(t, tp_alloc, allocfunc); + return alloc_func(t, 0); + } else { + newfunc tp_new = __Pyx_PyType_TryGetSlot(&PyBaseObject_Type, tp_new, newfunc); + #if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 + if (!tp_new) { + PyObject *new_str = PyUnicode_FromString("__new__"); + if (likely(new_str)) { + PyObject *o = PyObject_CallMethodObjArgs((PyObject *)&PyBaseObject_Type, new_str, t, NULL); + Py_DECREF(new_str); + return o; + } else + return NULL; + } else + #endif + return tp_new(t, __pyx_mstate_global->__pyx_empty_tuple, 0); + } +} + +/* PyObjectCallMethod0 (used by PyType_Ready) */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) { +#if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000)) + PyObject *args[1] = {obj}; + (void) __Pyx_PyObject_CallOneArg; + (void) __Pyx_PyObject_CallNoArg; + return PyObject_VectorcallMethod(method_name, args, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +#else + PyObject *method = NULL, *result = NULL; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_CallOneArg(method, obj); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) goto bad; + result = __Pyx_PyObject_CallNoArg(method); + Py_DECREF(method); +bad: + return result; +#endif +} + +/* ValidateBasesTuple (used by PyType_Ready) */ +#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS +static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases) { + Py_ssize_t i, n; +#if CYTHON_ASSUME_SAFE_SIZE + n = PyTuple_GET_SIZE(bases); +#else + n = PyTuple_Size(bases); + if (unlikely(n < 0)) return -1; +#endif + for (i = 1; i < n; i++) + { + PyTypeObject *b; +#if CYTHON_AVOID_BORROWED_REFS + PyObject *b0 = PySequence_GetItem(bases, i); + if (!b0) return -1; +#elif CYTHON_ASSUME_SAFE_MACROS + PyObject *b0 = PyTuple_GET_ITEM(bases, i); +#else + PyObject *b0 = PyTuple_GetItem(bases, i); + if (!b0) return -1; +#endif + b = (PyTypeObject*) b0; + if (!__Pyx_PyType_HasFeature(b, Py_TPFLAGS_HEAPTYPE)) + { + __Pyx_TypeName b_name = __Pyx_PyType_GetFullyQualifiedName(b); + PyErr_Format(PyExc_TypeError, + "base class '" __Pyx_FMT_TYPENAME "' is not a heap type", b_name); + __Pyx_DECREF_TypeName(b_name); +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + return -1; + } + if (dictoffset == 0) + { + Py_ssize_t b_dictoffset = 0; +#if CYTHON_USE_TYPE_SLOTS + b_dictoffset = b->tp_dictoffset; +#else + PyObject *py_b_dictoffset = PyObject_GetAttrString((PyObject*)b, "__dictoffset__"); + if (!py_b_dictoffset) goto dictoffset_return; + b_dictoffset = PyLong_AsSsize_t(py_b_dictoffset); + Py_DECREF(py_b_dictoffset); + if (b_dictoffset == -1 && PyErr_Occurred()) goto dictoffset_return; +#endif + if (b_dictoffset) { + { + __Pyx_TypeName b_name = __Pyx_PyType_GetFullyQualifiedName(b); + PyErr_Format(PyExc_TypeError, + "extension type '%.200s' has no __dict__ slot, " + "but base type '" __Pyx_FMT_TYPENAME "' has: " + "either add 'cdef dict __dict__' to the extension type " + "or add '__slots__ = [...]' to the base type", + type_name, b_name); + __Pyx_DECREF_TypeName(b_name); + } +#if !CYTHON_USE_TYPE_SLOTS + dictoffset_return: +#endif +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + return -1; + } + } +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + } + return 0; +} +#endif + +/* PyType_Ready */ +CYTHON_UNUSED static int __Pyx_PyType_HasMultipleInheritance(PyTypeObject *t) { + while (t) { + PyObject *bases = __Pyx_PyType_GetSlot(t, tp_bases, PyObject*); + if (bases) { + return 1; + } + t = __Pyx_PyType_GetSlot(t, tp_base, PyTypeObject*); + } + return 0; +} +static int __Pyx_PyType_Ready(PyTypeObject *t) { +#if CYTHON_USE_TYPE_SPECS || !CYTHON_COMPILING_IN_CPYTHON || defined(PYSTON_MAJOR_VERSION) + (void)__Pyx_PyObject_CallMethod0; +#if CYTHON_USE_TYPE_SPECS + (void)__Pyx_validate_bases_tuple; +#endif + return PyType_Ready(t); +#else + int r; + if (!__Pyx_PyType_HasMultipleInheritance(t)) { + return PyType_Ready(t); + } + PyObject *bases = __Pyx_PyType_GetSlot(t, tp_bases, PyObject*); + if (bases && unlikely(__Pyx_validate_bases_tuple(t->tp_name, t->tp_dictoffset, bases) == -1)) + return -1; +#if !defined(PYSTON_MAJOR_VERSION) + { + int gc_was_enabled; + #if PY_VERSION_HEX >= 0x030A00b1 + gc_was_enabled = PyGC_Disable(); + (void)__Pyx_PyObject_CallMethod0; + #else + PyObject *ret, *py_status; + PyObject *gc = NULL; + #if (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM+0 >= 0x07030400) &&\ + !CYTHON_COMPILING_IN_GRAAL + gc = PyImport_GetModule(__pyx_mstate_global->__pyx_kp_u_gc); + #endif + if (unlikely(!gc)) gc = PyImport_Import(__pyx_mstate_global->__pyx_kp_u_gc); + if (unlikely(!gc)) return -1; + py_status = __Pyx_PyObject_CallMethod0(gc, __pyx_mstate_global->__pyx_kp_u_isenabled); + if (unlikely(!py_status)) { + Py_DECREF(gc); + return -1; + } + gc_was_enabled = __Pyx_PyObject_IsTrue(py_status); + Py_DECREF(py_status); + if (gc_was_enabled > 0) { + ret = __Pyx_PyObject_CallMethod0(gc, __pyx_mstate_global->__pyx_kp_u_disable); + if (unlikely(!ret)) { + Py_DECREF(gc); + return -1; + } + Py_DECREF(ret); + } else if (unlikely(gc_was_enabled == -1)) { + Py_DECREF(gc); + return -1; + } + #endif + t->tp_flags |= Py_TPFLAGS_HEAPTYPE; +#if PY_VERSION_HEX >= 0x030A0000 + t->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE; +#endif +#else + (void)__Pyx_PyObject_CallMethod0; +#endif + r = PyType_Ready(t); +#if !defined(PYSTON_MAJOR_VERSION) + t->tp_flags &= ~Py_TPFLAGS_HEAPTYPE; + #if PY_VERSION_HEX >= 0x030A00b1 + if (gc_was_enabled) + PyGC_Enable(); + #else + if (gc_was_enabled) { + PyObject *tp, *v, *tb; + PyErr_Fetch(&tp, &v, &tb); + ret = __Pyx_PyObject_CallMethod0(gc, __pyx_mstate_global->__pyx_kp_u_enable); + if (likely(ret || r == -1)) { + Py_XDECREF(ret); + PyErr_Restore(tp, v, tb); + } else { + Py_XDECREF(tp); + Py_XDECREF(v); + Py_XDECREF(tb); + r = -1; + } + } + Py_DECREF(gc); + #endif + } +#endif + return r; +#endif +} + +/* HasAttr (used by ImportImpl) */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d0000 +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { + PyObject *r; + if (unlikely(!PyUnicode_Check(n))) { + PyErr_SetString(PyExc_TypeError, + "hasattr(): attribute name must be string"); + return -1; + } + r = __Pyx_PyObject_GetAttrStrNoError(o, n); + if (!r) { + return (unlikely(PyErr_Occurred())) ? -1 : 0; + } else { + Py_DECREF(r); + return 1; + } +} +#endif + +/* ImportImpl (used by Import) */ +static int __Pyx__Import_GetModule(PyObject *qualname, PyObject **module) { + PyObject *imported_module = PyImport_GetModule(qualname); + if (unlikely(!imported_module)) { + *module = NULL; + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + *module = imported_module; + return 1; +} +static int __Pyx__Import_Lookup(PyObject *qualname, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject **module) { + PyObject *imported_module; + PyObject *top_level_package_name; + Py_ssize_t i; + int status, module_found; + Py_ssize_t dot_index; + module_found = __Pyx__Import_GetModule(qualname, &imported_module); + if (unlikely(!module_found || module_found == -1)) { + *module = NULL; + return module_found; + } + if (imported_names) { + for (i = 0; i < len_imported_names; i++) { + PyObject *imported_name = imported_names[i]; +#if __PYX_LIMITED_VERSION_HEX < 0x030d0000 + int has_imported_attribute = PyObject_HasAttr(imported_module, imported_name); +#else + int has_imported_attribute = PyObject_HasAttrWithError(imported_module, imported_name); + if (unlikely(has_imported_attribute == -1)) goto error; +#endif + if (!has_imported_attribute) { + goto not_found; + } + } + *module = imported_module; + return 1; + } + dot_index = PyUnicode_FindChar(qualname, '.', 0, PY_SSIZE_T_MAX, 1); + if (dot_index == -1) { + *module = imported_module; + return 1; + } + if (unlikely(dot_index == -2)) goto error; + top_level_package_name = PyUnicode_Substring(qualname, 0, dot_index); + if (unlikely(!top_level_package_name)) goto error; + Py_DECREF(imported_module); + status = __Pyx__Import_GetModule(top_level_package_name, module); + Py_DECREF(top_level_package_name); + return status; +error: + Py_DECREF(imported_module); + *module = NULL; + return -1; +not_found: + Py_DECREF(imported_module); + *module = NULL; + return 0; +} +static PyObject *__Pyx__Import(PyObject *name, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject *qualname, PyObject *moddict, int level) { + PyObject *module = 0; + PyObject *empty_dict = 0; + PyObject *from_list = 0; + int module_found; + if (!qualname) { + qualname = name; + } + module_found = __Pyx__Import_Lookup(qualname, imported_names, len_imported_names, &module); + if (likely(module_found == 1)) { + return module; + } else if (unlikely(module_found == -1)) { + return NULL; + } + empty_dict = PyDict_New(); + if (unlikely(!empty_dict)) + goto bad; + if (imported_names) { +#if CYTHON_COMPILING_IN_CPYTHON + from_list = __Pyx_PyList_FromArray(imported_names, len_imported_names); + if (unlikely(!from_list)) + goto bad; +#else + from_list = PyList_New(len_imported_names); + if (unlikely(!from_list)) goto bad; + for (Py_ssize_t i=0; i__pyx_d, level); +} + +/* ImportFrom */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { + PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); + if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { + const char* module_name_str = 0; + PyObject* module_name = 0; + PyObject* module_dot = 0; + PyObject* full_name = 0; + PyErr_Clear(); + module_name_str = PyModule_GetName(module); + if (unlikely(!module_name_str)) { goto modbad; } + module_name = PyUnicode_FromString(module_name_str); + if (unlikely(!module_name)) { goto modbad; } + module_dot = PyUnicode_Concat(module_name, __pyx_mstate_global->__pyx_kp_u__2); + if (unlikely(!module_dot)) { goto modbad; } + full_name = PyUnicode_Concat(module_dot, name); + if (unlikely(!full_name)) { goto modbad; } + #if (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) ||\ + CYTHON_COMPILING_IN_GRAAL + { + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + goto modbad; + value = PyObject_GetItem(modules, full_name); + } + #else + value = PyImport_GetModule(full_name); + #endif + modbad: + Py_XDECREF(full_name); + Py_XDECREF(module_dot); + Py_XDECREF(module_name); + } + if (unlikely(!value)) { + PyErr_Format(PyExc_ImportError, "cannot import name %S", name); + } + return value; +} + +/* ListPack */ +static PyObject *__Pyx_PyList_Pack(Py_ssize_t n, ...) { + va_list va; + PyObject *l = PyList_New(n); + va_start(va, n); + if (unlikely(!l)) goto end; + for (Py_ssize_t i=0; i__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + cython_runtime_dict = __Pyx_PyProbablyModule_GetDict(__pyx_mstate_global->__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, cython_runtime_dict, + __Pyx_PyDict_SetDefault(cython_runtime_dict, __pyx_mstate_global->__pyx_n_u_cline_in_traceback, Py_False)) + } + if (use_cline == NULL || use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + Py_XDECREF(use_cline); + Py_XDECREF(cython_runtime_dict); + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache (used by AddTraceback) */ +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static __Pyx_CachedCodeObjectType *__pyx__find_code_object(struct __Pyx_CodeObjectCache *code_cache, int code_line) { + __Pyx_CachedCodeObjectType* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!code_cache->entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(code_cache->entries, code_cache->count, code_line); + if (unlikely(pos >= code_cache->count) || unlikely(code_cache->entries[pos].code_line != code_line)) { + return NULL; + } + code_object = code_cache->entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static __Pyx_CachedCodeObjectType *__pyx_find_code_object(int code_line) { +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && !CYTHON_ATOMICS + (void)__pyx__find_code_object; + return NULL; // Most implementation should have atomics. But otherwise, don't make it thread-safe, just miss. +#else + struct __Pyx_CodeObjectCache *code_cache = &__pyx_mstate_global->__pyx_code_cache; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_nonatomic_int_type old_count = __pyx_atomic_incr_acq_rel(&code_cache->accessor_count); + if (old_count < 0) { + __pyx_atomic_decr_acq_rel(&code_cache->accessor_count); + return NULL; + } +#endif + __Pyx_CachedCodeObjectType *result = __pyx__find_code_object(code_cache, code_line); +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_atomic_decr_acq_rel(&code_cache->accessor_count); +#endif + return result; +#endif +} +static void __pyx__insert_code_object(struct __Pyx_CodeObjectCache *code_cache, int code_line, __Pyx_CachedCodeObjectType* code_object) +{ + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = code_cache->entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + code_cache->entries = entries; + code_cache->max_count = 64; + code_cache->count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(code_cache->entries, code_cache->count, code_line); + if ((pos < code_cache->count) && unlikely(code_cache->entries[pos].code_line == code_line)) { + __Pyx_CachedCodeObjectType* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_INCREF(code_object); + Py_DECREF(tmp); + return; + } + if (code_cache->count == code_cache->max_count) { + int new_max = code_cache->max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + code_cache->entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + code_cache->entries = entries; + code_cache->max_count = new_max; + } + for (i=code_cache->count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + code_cache->count++; + Py_INCREF(code_object); +} +static void __pyx_insert_code_object(int code_line, __Pyx_CachedCodeObjectType* code_object) { +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && !CYTHON_ATOMICS + (void)__pyx__insert_code_object; + return; // Most implementation should have atomics. But otherwise, don't make it thread-safe, just fail. +#else + struct __Pyx_CodeObjectCache *code_cache = &__pyx_mstate_global->__pyx_code_cache; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_nonatomic_int_type expected = 0; + if (!__pyx_atomic_int_cmp_exchange(&code_cache->accessor_count, &expected, INT_MIN)) { + return; + } +#endif + __pyx__insert_code_object(code_cache, code_line, code_object); +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_atomic_sub(&code_cache->accessor_count, INT_MIN); +#endif +#endif +} + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION) + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyCode_Replace_For_AddTraceback(PyObject *code, PyObject *scratch_dict, + PyObject *firstlineno, PyObject *name) { + PyObject *replace = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_firstlineno", firstlineno))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_name", name))) return NULL; + replace = PyObject_GetAttrString(code, "replace"); + if (likely(replace)) { + PyObject *result = PyObject_Call(replace, __pyx_mstate_global->__pyx_empty_tuple, scratch_dict); + Py_DECREF(replace); + return result; + } + PyErr_Clear(); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyObject *code_object = NULL, *py_py_line = NULL, *py_funcname = NULL, *dict = NULL; + PyObject *replace = NULL, *getframe = NULL, *frame = NULL; + PyObject *exc_type, *exc_value, *exc_traceback; + int success = 0; + if (c_line) { + c_line = __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line); + } + PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); + code_object = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!code_object) { + code_object = Py_CompileString("_getframe()", filename, Py_eval_input); + if (unlikely(!code_object)) goto bad; + py_py_line = PyLong_FromLong(py_line); + if (unlikely(!py_py_line)) goto bad; + if (c_line) { + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + } else { + py_funcname = PyUnicode_FromString(funcname); + } + if (unlikely(!py_funcname)) goto bad; + dict = PyDict_New(); + if (unlikely(!dict)) goto bad; + { + PyObject *old_code_object = code_object; + code_object = __Pyx_PyCode_Replace_For_AddTraceback(code_object, dict, py_py_line, py_funcname); + Py_DECREF(old_code_object); + } + if (unlikely(!code_object)) goto bad; + __pyx_insert_code_object(c_line ? -c_line : py_line, code_object); + } else { + dict = PyDict_New(); + } + getframe = PySys_GetObject("_getframe"); + if (unlikely(!getframe)) goto bad; + if (unlikely(PyDict_SetItemString(dict, "_getframe", getframe))) goto bad; + frame = PyEval_EvalCode(code_object, dict, dict); + if (unlikely(!frame) || frame == Py_None) goto bad; + success = 1; + bad: + PyErr_Restore(exc_type, exc_value, exc_traceback); + Py_XDECREF(code_object); + Py_XDECREF(py_py_line); + Py_XDECREF(py_funcname); + Py_XDECREF(dict); + Py_XDECREF(replace); + if (success) { + PyTraceBack_Here( + (struct _frame*)frame); + } + Py_XDECREF(frame); +} +#else +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = NULL; + PyObject *py_funcname = NULL; + if (c_line) { + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + funcname = PyUnicode_AsUTF8(py_funcname); + if (!funcname) goto bad; + } + py_code = PyCode_NewEmpty(filename, funcname, py_line); + Py_XDECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_funcname); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject *ptype, *pvalue, *ptraceback; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) { + /* If the code object creation fails, then we should clear the + fetched exception references and propagate the new exception */ + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + goto bad; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_mstate_global->__pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} +#endif + +/* Declarations */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) + #ifdef __cplusplus + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return ::std::complex< double >(x, y); + } + #else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return x + y*(__pyx_t_double_complex)_Complex_I; + } + #endif +#else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + __pyx_t_double_complex z; + z.real = x; + z.imag = y; + return z; + } +#endif + +/* Arithmetic */ +#if CYTHON_CCOMPLEX && (1) && (!0 || __cplusplus) +#else + static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + return (a.real == b.real) && (a.imag == b.imag); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real + b.real; + z.imag = a.imag + b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real - b.real; + z.imag = a.imag - b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real * b.real - a.imag * b.imag; + z.imag = a.real * b.imag + a.imag * b.real; + return z; + } + #if 1 + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + if (b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); + } else if (fabs(b.real) >= fabs(b.imag)) { + if (b.real == 0 && b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.imag); + } else { + double r = b.imag / b.real; + double s = (double)(1.0) / (b.real + b.imag * r); + return __pyx_t_double_complex_from_parts( + (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); + } + } else { + double r = b.real / b.imag; + double s = (double)(1.0) / (b.imag + b.real * r); + return __pyx_t_double_complex_from_parts( + (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); + } + } + #else + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + if (b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); + } else { + double denom = b.real * b.real + b.imag * b.imag; + return __pyx_t_double_complex_from_parts( + (a.real * b.real + a.imag * b.imag) / denom, + (a.imag * b.real - a.real * b.imag) / denom); + } + } + #endif + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = -a.real; + z.imag = -a.imag; + return z; + } + static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex a) { + return (a.real == 0) && (a.imag == 0); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = a.real; + z.imag = -a.imag; + return z; + } + #if 1 + static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex z) { + #if !defined(HAVE_HYPOT) || defined(_MSC_VER) + return sqrt(z.real*z.real + z.imag*z.imag); + #else + return hypot(z.real, z.imag); + #endif + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + double r, lnr, theta, z_r, z_theta; + if (b.imag == 0 && b.real == (int)b.real) { + if (b.real < 0) { + double denom = a.real * a.real + a.imag * a.imag; + a.real = a.real / denom; + a.imag = -a.imag / denom; + b.real = -b.real; + } + switch ((int)b.real) { + case 0: + z.real = 1; + z.imag = 0; + return z; + case 1: + return a; + case 2: + return __Pyx_c_prod_double(a, a); + case 3: + z = __Pyx_c_prod_double(a, a); + return __Pyx_c_prod_double(z, a); + case 4: + z = __Pyx_c_prod_double(a, a); + return __Pyx_c_prod_double(z, z); + } + } + if (a.imag == 0) { + if (a.real == 0) { + return a; + } else if ((b.imag == 0) && (a.real >= 0)) { + z.real = pow(a.real, b.real); + z.imag = 0; + return z; + } else if (a.real > 0) { + r = a.real; + theta = 0; + } else { + r = -a.real; + theta = atan2(0.0, -1.0); + } + } else { + r = __Pyx_c_abs_double(a); + theta = atan2(a.imag, a.real); + } + lnr = log(r); + z_r = exp(lnr * b.real - theta * b.imag); + z_theta = theta * b.real + lnr * b.imag; + z.real = z_r * cos(z_theta); + z.imag = z_r * sin(z_theta); + return z; + } + #endif +#endif + +/* FromPy */ +static __pyx_t_double_complex __Pyx_PyComplex_As___pyx_t_double_complex(PyObject* o) { +#if CYTHON_COMPILING_IN_LIMITED_API + double real=-1.0, imag=-1.0; + real = PyComplex_RealAsDouble(o); + if (unlikely(real == -1.0 && PyErr_Occurred())) goto end; + imag = PyComplex_ImagAsDouble(o); + end: + return __pyx_t_double_complex_from_parts( + (double)real, (double)imag + ); +#else + Py_complex cval; +#if !CYTHON_COMPILING_IN_PYPY && !CYTHON_COMPILING_IN_GRAAL + if (PyComplex_CheckExact(o)) + cval = ((PyComplexObject *)o)->cval; + else +#endif + cval = PyComplex_AsCComplex(o); + return __pyx_t_double_complex_from_parts( + (double)cval.real, + (double)cval.imag); +#endif +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyLong_From_long(long value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyLong_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#if !CYTHON_COMPILING_IN_PYPY + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyLong_FromLong((long) value); + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); + } + } + { + unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d00A4 + if (is_unsigned) { + return PyLong_FromUnsignedNativeBytes(bytes, sizeof(value), -1); + } else { + return PyLong_FromNativeBytes(bytes, sizeof(value), -1); + } +#elif !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 + int one = 1; int little = (int)*(unsigned char *)&one; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); +#else + int one = 1; int little = (int)*(unsigned char *)&one; + PyObject *from_bytes, *result = NULL, *kwds = NULL; + PyObject *py_bytes = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(long)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + { + PyObject *args[3+(CYTHON_VECTORCALL ? 1 : 0)] = { NULL, py_bytes, order_str }; + if (!is_unsigned) { + kwds = __Pyx_MakeVectorcallBuilderKwds(1); + if (!kwds) goto limited_bad; + if (__Pyx_VectorcallBuilder_AddArgStr("signed", __Pyx_NewRef(Py_True), kwds, args+3, 0) < 0) goto limited_bad; + } + result = __Pyx_Object_Vectorcall_CallFromBuilder(from_bytes, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET, kwds); + } + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif + } +} + +/* FormatTypeName */ +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030d0000 +static __Pyx_TypeName +__Pyx_PyType_GetFullyQualifiedName(PyTypeObject* tp) +{ + PyObject *module = NULL, *name = NULL, *result = NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030b0000 + name = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_mstate_global->__pyx_n_u_qualname); + #else + name = PyType_GetQualName(tp); + #endif + if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) goto bad; + module = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_mstate_global->__pyx_n_u_module); + if (unlikely(module == NULL) || unlikely(!PyUnicode_Check(module))) goto bad; + if (PyUnicode_CompareWithASCIIString(module, "builtins") == 0) { + result = name; + name = NULL; + goto done; + } + result = PyUnicode_FromFormat("%U.%U", module, name); + if (unlikely(result == NULL)) goto bad; + done: + Py_XDECREF(name); + Py_XDECREF(module); + return result; + bad: + PyErr_Clear(); + if (name) { + result = name; + name = NULL; + } else { + result = __Pyx_NewRef(__pyx_mstate_global->__pyx_kp_u__3); + } + goto done; +} +#endif + +/* CIntFromPyVerify (used by CIntFromPy) */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyLong_As_long(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (unlikely(!PyLong_Check(x))) { + long val; + PyObject *tmp = __Pyx_PyNumber_Long(x); + if (!tmp) return (long) -1; + val = __Pyx_PyLong_As_long(tmp); + Py_DECREF(tmp); + return val; + } + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 2 * PyLong_SHIFT)) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 3 * PyLong_SHIFT)) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 4 * PyLong_SHIFT)) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(long) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) + } else if ((sizeof(long) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(long) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(long) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) + } else if ((sizeof(long) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) + } + } + { + long val; + int ret = -1; +#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API + Py_ssize_t bytes_copied = PyLong_AsNativeBytes( + x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0)); + if (unlikely(bytes_copied == -1)) { + } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) { + goto raise_overflow; + } else { + ret = 0; + } +#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)x, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *v; + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (likely(PyLong_CheckExact(x))) { + v = __Pyx_NewRef(x); + } else { + v = PyNumber_Long(x); + if (unlikely(!v)) return (long) -1; + assert(PyLong_CheckExact(v)); + } + { + int result = PyObject_RichCompareBool(v, Py_False, Py_LT); + if (unlikely(result < 0)) { + Py_DECREF(v); + return (long) -1; + } + is_negative = result == 1; + } + if (is_unsigned && unlikely(is_negative)) { + Py_DECREF(v); + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + Py_DECREF(v); + if (unlikely(!stepval)) + return (long) -1; + } else { + stepval = v; + } + v = NULL; + val = (long) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(long) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + long idigit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + val |= ((long) idigit) << bits; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + } + Py_DECREF(shift); shift = NULL; + Py_DECREF(mask); mask = NULL; + { + long idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(long) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((long) idigit) << bits; + } + if (!is_unsigned) { + if (unlikely(val & (((long) 1) << (sizeof(long) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + if (unlikely(ret)) + return (long) -1; + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyLong_As_int(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (unlikely(!PyLong_Check(x))) { + int val; + PyObject *tmp = __Pyx_PyNumber_Long(x); + if (!tmp) return (int) -1; + val = __Pyx_PyLong_As_int(tmp); + Py_DECREF(tmp); + return val; + } + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 2 * PyLong_SHIFT)) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 3 * PyLong_SHIFT)) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 4 * PyLong_SHIFT)) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(int) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) + } else if ((sizeof(int) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(int) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(int) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) + } else if ((sizeof(int) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) + } + } + { + int val; + int ret = -1; +#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API + Py_ssize_t bytes_copied = PyLong_AsNativeBytes( + x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0)); + if (unlikely(bytes_copied == -1)) { + } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) { + goto raise_overflow; + } else { + ret = 0; + } +#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)x, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *v; + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (likely(PyLong_CheckExact(x))) { + v = __Pyx_NewRef(x); + } else { + v = PyNumber_Long(x); + if (unlikely(!v)) return (int) -1; + assert(PyLong_CheckExact(v)); + } + { + int result = PyObject_RichCompareBool(v, Py_False, Py_LT); + if (unlikely(result < 0)) { + Py_DECREF(v); + return (int) -1; + } + is_negative = result == 1; + } + if (is_unsigned && unlikely(is_negative)) { + Py_DECREF(v); + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + Py_DECREF(v); + if (unlikely(!stepval)) + return (int) -1; + } else { + stepval = v; + } + v = NULL; + val = (int) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(int) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + long idigit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + val |= ((int) idigit) << bits; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + } + Py_DECREF(shift); shift = NULL; + Py_DECREF(mask); mask = NULL; + { + long idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(int) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((int) idigit) << bits; + } + if (!is_unsigned) { + if (unlikely(val & (((int) 1) << (sizeof(int) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + if (unlikely(ret)) + return (int) -1; + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = __Pyx_PyType_GetSlot(a, tp_base, PyTypeObject*); + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (cls == a || cls == b) return 1; + mro = cls->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + PyObject *base = PyTuple_GET_ITEM(mro, i); + if (base == (PyObject *)a || base == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(cls, a) || __Pyx_InBases(cls, b); +} +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + if (exc_type1) { + return __Pyx_IsAnySubtype2((PyTypeObject*)err, (PyTypeObject*)exc_type1, (PyTypeObject*)exc_type2); + } else { + return __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } +} +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); + for (i=0; i>= 8; + ++i; + } + __Pyx_cached_runtime_version = version; + } +} +#endif +static unsigned long __Pyx_get_runtime_version(void) { +#if __PYX_LIMITED_VERSION_HEX >= 0x030b0000 + return Py_Version & ~0xFFUL; +#else + return __Pyx_cached_runtime_version; +#endif +} + +/* CheckBinaryVersion */ +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer) { + const unsigned long MAJOR_MINOR = 0xFFFF0000UL; + if ((rt_version & MAJOR_MINOR) == (ct_version & MAJOR_MINOR)) + return 0; + if (likely(allow_newer && (rt_version & MAJOR_MINOR) > (ct_version & MAJOR_MINOR))) + return 1; + { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compile time Python version %d.%d " + "of module '%.100s' " + "%s " + "runtime version %d.%d", + (int) (ct_version >> 24), (int) ((ct_version >> 16) & 0xFF), + __Pyx_MODULE_NAME, + (allow_newer) ? "was newer than" : "does not match", + (int) (rt_version >> 24), (int) ((rt_version >> 16) & 0xFF) + ); + return PyErr_WarnEx(NULL, message, 1); + } +} + +/* NewCodeObj */ +#if CYTHON_COMPILING_IN_LIMITED_API + static PyObject* __Pyx__PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyObject *exception_table = NULL; + PyObject *types_module=NULL, *code_type=NULL, *result=NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030b0000 + PyObject *version_info; + PyObject *py_minor_version = NULL; + #endif + long minor_version = 0; + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + #if __PYX_LIMITED_VERSION_HEX >= 0x030b0000 + minor_version = 11; + #else + if (!(version_info = PySys_GetObject("version_info"))) goto end; + if (!(py_minor_version = PySequence_GetItem(version_info, 1))) goto end; + minor_version = PyLong_AsLong(py_minor_version); + Py_DECREF(py_minor_version); + if (minor_version == -1 && PyErr_Occurred()) goto end; + #endif + if (!(types_module = PyImport_ImportModule("types"))) goto end; + if (!(code_type = PyObject_GetAttrString(types_module, "CodeType"))) goto end; + if (minor_version <= 7) { + (void)p; + result = PyObject_CallFunction(code_type, "iiiiiOOOOOOiOOO", a, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else if (minor_version <= 10) { + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOiOOO", a,p, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else { + if (!(exception_table = PyBytes_FromStringAndSize(NULL, 0))) goto end; + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOOiOOOO", a,p, k, l, s, f, code, + c, n, v, fn, name, name, fline, lnos, exception_table, fv, cell); + } + end: + Py_XDECREF(code_type); + Py_XDECREF(exception_table); + Py_XDECREF(types_module); + if (type) { + PyErr_Restore(type, value, traceback); + } + return result; + } +#elif PY_VERSION_HEX >= 0x030B0000 + static PyCodeObject* __Pyx__PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyCodeObject *result; + result = + #if PY_VERSION_HEX >= 0x030C0000 + PyUnstable_Code_NewWithPosOnlyArgs + #else + PyCode_NewWithPosOnlyArgs + #endif + (a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, __pyx_mstate_global->__pyx_empty_bytes); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030c00A1 + if (likely(result)) + result->_co_firsttraceable = 0; + #endif + return result; + } +#elif !CYTHON_COMPILING_IN_PYPY + #define __Pyx__PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_NewWithPosOnlyArgs(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx__PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif +static PyObject* __Pyx_PyCode_New( + const __Pyx_PyCode_New_function_description descr, + PyObject * const *varnames, + PyObject *filename, + PyObject *funcname, + PyObject *line_table, + PyObject *tuple_dedup_map +) { + PyObject *code_obj = NULL, *varnames_tuple_dedup = NULL, *code_bytes = NULL; + Py_ssize_t var_count = (Py_ssize_t) descr.nlocals; + PyObject *varnames_tuple = PyTuple_New(var_count); + if (unlikely(!varnames_tuple)) return NULL; + for (Py_ssize_t i=0; i < var_count; i++) { + Py_INCREF(varnames[i]); + if (__Pyx_PyTuple_SET_ITEM(varnames_tuple, i, varnames[i]) != (0)) goto done; + } + #if CYTHON_COMPILING_IN_LIMITED_API + varnames_tuple_dedup = PyDict_GetItem(tuple_dedup_map, varnames_tuple); + if (!varnames_tuple_dedup) { + if (unlikely(PyDict_SetItem(tuple_dedup_map, varnames_tuple, varnames_tuple) < 0)) goto done; + varnames_tuple_dedup = varnames_tuple; + } + #else + varnames_tuple_dedup = PyDict_SetDefault(tuple_dedup_map, varnames_tuple, varnames_tuple); + if (unlikely(!varnames_tuple_dedup)) goto done; + #endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(varnames_tuple_dedup); + #endif + if (__PYX_LIMITED_VERSION_HEX >= (0x030b0000) && line_table != NULL && !CYTHON_COMPILING_IN_GRAAL) { + Py_ssize_t line_table_length = __Pyx_PyBytes_GET_SIZE(line_table); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(line_table_length == -1)) goto done; + #endif + Py_ssize_t code_len = (line_table_length * 2 + 4) & ~3LL; + code_bytes = PyBytes_FromStringAndSize(NULL, code_len); + if (unlikely(!code_bytes)) goto done; + char* c_code_bytes = PyBytes_AsString(code_bytes); + if (unlikely(!c_code_bytes)) goto done; + memset(c_code_bytes, 0, (size_t) code_len); + } + code_obj = (PyObject*) __Pyx__PyCode_New( + (int) descr.argcount, + (int) descr.num_posonly_args, + (int) descr.num_kwonly_args, + (int) descr.nlocals, + 0, + (int) descr.flags, + code_bytes ? code_bytes : __pyx_mstate_global->__pyx_empty_bytes, + __pyx_mstate_global->__pyx_empty_tuple, + __pyx_mstate_global->__pyx_empty_tuple, + varnames_tuple_dedup, + __pyx_mstate_global->__pyx_empty_tuple, + __pyx_mstate_global->__pyx_empty_tuple, + filename, + funcname, + (int) descr.first_line, + (__PYX_LIMITED_VERSION_HEX >= (0x030b0000) && line_table) ? line_table : __pyx_mstate_global->__pyx_empty_bytes + ); +done: + Py_XDECREF(code_bytes); + #if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(varnames_tuple_dedup); + #endif + Py_DECREF(varnames_tuple); + return code_obj; +} + +/* DecompressString */ +static PyObject *__Pyx_DecompressString(const char *s, Py_ssize_t length, int algo) { + PyObject *module, *decompress, *compressed_bytes, *decompressed; + const char* module_name = algo == 3 ? "compression.zstd" : algo == 2 ? "bz2" : "zlib"; + PyObject *methodname = PyUnicode_FromString("decompress"); + if (unlikely(!methodname)) return NULL; + #if __PYX_LIMITED_VERSION_HEX >= 0x030e0000 + if (algo == 3) { + PyObject *fromlist = Py_BuildValue("[O]", methodname); + if (unlikely(!fromlist)) return NULL; + module = PyImport_ImportModuleLevel("compression.zstd", NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + } else + #endif + module = PyImport_ImportModule(module_name); + if (unlikely(!module)) goto import_failed; + decompress = PyObject_GetAttr(module, methodname); + if (unlikely(!decompress)) goto import_failed; + { + #ifdef __cplusplus + char *memview_bytes = const_cast(s); + #else + #if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wcast-qual" + #elif !defined(__INTEL_COMPILER) && defined(__GNUC__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-qual" + #endif + char *memview_bytes = (char*) s; + #if defined(__clang__) + #pragma clang diagnostic pop + #elif !defined(__INTEL_COMPILER) && defined(__GNUC__) + #pragma GCC diagnostic pop + #endif + #endif + #if CYTHON_COMPILING_IN_LIMITED_API && !defined(PyBUF_READ) + int memview_flags = 0x100; + #else + int memview_flags = PyBUF_READ; + #endif + compressed_bytes = PyMemoryView_FromMemory(memview_bytes, length, memview_flags); + } + if (unlikely(!compressed_bytes)) { + Py_DECREF(decompress); + goto bad; + } + decompressed = PyObject_CallFunctionObjArgs(decompress, compressed_bytes, NULL); + Py_DECREF(compressed_bytes); + Py_DECREF(decompress); + Py_DECREF(module); + Py_DECREF(methodname); + return decompressed; +import_failed: + PyErr_Format(PyExc_ImportError, + "Failed to import '%.20s.decompress' - cannot initialise module strings. " + "String compression was configured with the C macro 'CYTHON_COMPRESS_STRINGS=%d'.", + module_name, algo); +bad: + Py_XDECREF(module); + Py_DECREF(methodname); + return NULL; +} + +#include +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s) { + size_t len = strlen(s); + if (unlikely(len > (size_t) PY_SSIZE_T_MAX)) { + PyErr_SetString(PyExc_OverflowError, "byte string is too long"); + return -1; + } + return (Py_ssize_t) len; +} +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return __Pyx_PyUnicode_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return PyByteArray_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + { + const char* result; + Py_ssize_t unicode_length; + CYTHON_MAYBE_UNUSED_VAR(unicode_length); // only for __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + #if __PYX_LIMITED_VERSION_HEX < 0x030A0000 + if (unlikely(PyArg_Parse(o, "s#", &result, length) < 0)) return NULL; + #else + result = PyUnicode_AsUTF8AndSize(o, length); + #endif + #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + unicode_length = PyUnicode_GetLength(o); + if (unlikely(unicode_length < 0)) return NULL; + if (unlikely(unicode_length != *length)) { + PyUnicode_AsASCIIString(o); + return NULL; + } + #endif + return result; + } +#else +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +#endif +} +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 + if (PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif + if (PyByteArray_Check(o)) { +#if (CYTHON_ASSUME_SAFE_SIZE && CYTHON_ASSUME_SAFE_MACROS) || (CYTHON_COMPILING_IN_PYPY && (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE))) + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); +#else + *length = PyByteArray_Size(o); + if (*length == -1) return NULL; + return PyByteArray_AsString(o); +#endif + } else + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_LongWrongResultType(PyObject* result) { + __Pyx_TypeName result_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(result)); + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME "). " + "The ability to return an instance of a strict subclass of int is deprecated, " + "and may be removed in a future version of Python.", + result_type_name)) { + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; + } + __Pyx_DECREF_TypeName(result_type_name); + return result; + } + PyErr_Format(PyExc_TypeError, + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME ")", + result_type_name); + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_Long(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + PyObject *res = NULL; + if (likely(PyLong_Check(x))) + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + if (likely(m && m->nb_int)) { + res = m->nb_int(x); + } +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Long(x); + } +#endif + if (likely(res)) { + if (unlikely(!PyLong_CheckExact(res))) { + return __Pyx_PyNumber_LongWrongResultType(res); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(__Pyx_PyLong_IsCompact(b))) { + return __Pyx_PyLong_CompactValue(b); + } else { + const digit* digits = __Pyx_PyLong_Digits(b); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(b); + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyLong_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) { + if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) { + return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o); + } else { + Py_ssize_t ival; + PyObject *x; + x = PyNumber_Index(o); + if (!x) return -1; + ival = PyLong_AsLong(x); + Py_DECREF(x); + return ival; + } +} +static CYTHON_INLINE PyObject *__Pyx_Owned_Py_None(int b) { + CYTHON_UNUSED_VAR(b); + return __Pyx_NewRef(Py_None); +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return __Pyx_NewRef(b ? Py_True: Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyLong_FromSize_t(size_t ival) { + return PyLong_FromSize_t(ival); +} + + +/* MultiPhaseInitModuleState */ +#if CYTHON_PEP489_MULTI_PHASE_INIT && CYTHON_USE_MODULE_STATE +#ifndef CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +#if (CYTHON_COMPILING_IN_LIMITED_API || PY_VERSION_HEX >= 0x030C0000) + #define CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE 1 +#else + #define CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE 0 +#endif +#endif +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE && !CYTHON_ATOMICS +#error "Module state with PEP489 requires atomics. Currently that's one of\ + C11, C++11, gcc atomic intrinsics or MSVC atomic intrinsics" +#endif +#if !CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +#define __Pyx_ModuleStateLookup_Lock() +#define __Pyx_ModuleStateLookup_Unlock() +#elif !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d0000 +static PyMutex __Pyx_ModuleStateLookup_mutex = {0}; +#define __Pyx_ModuleStateLookup_Lock() PyMutex_Lock(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() PyMutex_Unlock(&__Pyx_ModuleStateLookup_mutex) +#elif defined(__cplusplus) && __cplusplus >= 201103L +#include +static std::mutex __Pyx_ModuleStateLookup_mutex; +#define __Pyx_ModuleStateLookup_Lock() __Pyx_ModuleStateLookup_mutex.lock() +#define __Pyx_ModuleStateLookup_Unlock() __Pyx_ModuleStateLookup_mutex.unlock() +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201112L) && !defined(__STDC_NO_THREADS__) +#include +static mtx_t __Pyx_ModuleStateLookup_mutex; +static once_flag __Pyx_ModuleStateLookup_mutex_once_flag = ONCE_FLAG_INIT; +static void __Pyx_ModuleStateLookup_initialize_mutex(void) { + mtx_init(&__Pyx_ModuleStateLookup_mutex, mtx_plain); +} +#define __Pyx_ModuleStateLookup_Lock()\ + call_once(&__Pyx_ModuleStateLookup_mutex_once_flag, __Pyx_ModuleStateLookup_initialize_mutex);\ + mtx_lock(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() mtx_unlock(&__Pyx_ModuleStateLookup_mutex) +#elif defined(HAVE_PTHREAD_H) +#include +static pthread_mutex_t __Pyx_ModuleStateLookup_mutex = PTHREAD_MUTEX_INITIALIZER; +#define __Pyx_ModuleStateLookup_Lock() pthread_mutex_lock(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() pthread_mutex_unlock(&__Pyx_ModuleStateLookup_mutex) +#elif defined(_WIN32) +#include // synchapi.h on its own doesn't work +static SRWLOCK __Pyx_ModuleStateLookup_mutex = SRWLOCK_INIT; +#define __Pyx_ModuleStateLookup_Lock() AcquireSRWLockExclusive(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() ReleaseSRWLockExclusive(&__Pyx_ModuleStateLookup_mutex) +#else +#error "No suitable lock available for CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE.\ + Requires C standard >= C11, or C++ standard >= C++11,\ + or pthreads, or the Windows 32 API, or Python >= 3.13." +#endif +typedef struct { + int64_t id; + PyObject *module; +} __Pyx_InterpreterIdAndModule; +typedef struct { + char interpreter_id_as_index; + Py_ssize_t count; + Py_ssize_t allocated; + __Pyx_InterpreterIdAndModule table[1]; +} __Pyx_ModuleStateLookupData; +#define __PYX_MODULE_STATE_LOOKUP_SMALL_SIZE 32 +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +static __pyx_atomic_int_type __Pyx_ModuleStateLookup_read_counter = 0; +#endif +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +static __pyx_atomic_ptr_type __Pyx_ModuleStateLookup_data = 0; +#else +static __Pyx_ModuleStateLookupData* __Pyx_ModuleStateLookup_data = NULL; +#endif +static __Pyx_InterpreterIdAndModule* __Pyx_State_FindModuleStateLookupTableLowerBound( + __Pyx_InterpreterIdAndModule* table, + Py_ssize_t count, + int64_t interpreterId) { + __Pyx_InterpreterIdAndModule* begin = table; + __Pyx_InterpreterIdAndModule* end = begin + count; + if (begin->id == interpreterId) { + return begin; + } + while ((end - begin) > __PYX_MODULE_STATE_LOOKUP_SMALL_SIZE) { + __Pyx_InterpreterIdAndModule* halfway = begin + (end - begin)/2; + if (halfway->id == interpreterId) { + return halfway; + } + if (halfway->id < interpreterId) { + begin = halfway; + } else { + end = halfway; + } + } + for (; begin < end; ++begin) { + if (begin->id >= interpreterId) return begin; + } + return begin; +} +static PyObject *__Pyx_State_FindModule(CYTHON_UNUSED void* dummy) { + int64_t interpreter_id = PyInterpreterState_GetID(__Pyx_PyInterpreterState_Get()); + if (interpreter_id == -1) return NULL; +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __Pyx_ModuleStateLookupData* data = (__Pyx_ModuleStateLookupData*)__pyx_atomic_pointer_load_relaxed(&__Pyx_ModuleStateLookup_data); + { + __pyx_atomic_incr_acq_rel(&__Pyx_ModuleStateLookup_read_counter); + if (likely(data)) { + __Pyx_ModuleStateLookupData* new_data = (__Pyx_ModuleStateLookupData*)__pyx_atomic_pointer_load_acquire(&__Pyx_ModuleStateLookup_data); + if (likely(data == new_data)) { + goto read_finished; + } + } + __pyx_atomic_decr_acq_rel(&__Pyx_ModuleStateLookup_read_counter); + __Pyx_ModuleStateLookup_Lock(); + __pyx_atomic_incr_relaxed(&__Pyx_ModuleStateLookup_read_counter); + data = (__Pyx_ModuleStateLookupData*)__pyx_atomic_pointer_load_relaxed(&__Pyx_ModuleStateLookup_data); + __Pyx_ModuleStateLookup_Unlock(); + } + read_finished:; +#else + __Pyx_ModuleStateLookupData* data = __Pyx_ModuleStateLookup_data; +#endif + __Pyx_InterpreterIdAndModule* found = NULL; + if (unlikely(!data)) goto end; + if (data->interpreter_id_as_index) { + if (interpreter_id < data->count) { + found = data->table+interpreter_id; + } + } else { + found = __Pyx_State_FindModuleStateLookupTableLowerBound( + data->table, data->count, interpreter_id); + } + end: + { + PyObject *result=NULL; + if (found && found->id == interpreter_id) { + result = found->module; + } +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __pyx_atomic_decr_acq_rel(&__Pyx_ModuleStateLookup_read_counter); +#endif + return result; + } +} +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +static void __Pyx_ModuleStateLookup_wait_until_no_readers(void) { + while (__pyx_atomic_load(&__Pyx_ModuleStateLookup_read_counter) != 0); +} +#else +#define __Pyx_ModuleStateLookup_wait_until_no_readers() +#endif +static int __Pyx_State_AddModuleInterpIdAsIndex(__Pyx_ModuleStateLookupData **old_data, PyObject* module, int64_t interpreter_id) { + Py_ssize_t to_allocate = (*old_data)->allocated; + while (to_allocate <= interpreter_id) { + if (to_allocate == 0) to_allocate = 1; + else to_allocate *= 2; + } + __Pyx_ModuleStateLookupData *new_data = *old_data; + if (to_allocate != (*old_data)->allocated) { + new_data = (__Pyx_ModuleStateLookupData *)realloc( + *old_data, + sizeof(__Pyx_ModuleStateLookupData)+(to_allocate-1)*sizeof(__Pyx_InterpreterIdAndModule)); + if (!new_data) { + PyErr_NoMemory(); + return -1; + } + for (Py_ssize_t i = new_data->allocated; i < to_allocate; ++i) { + new_data->table[i].id = i; + new_data->table[i].module = NULL; + } + new_data->allocated = to_allocate; + } + new_data->table[interpreter_id].module = module; + if (new_data->count < interpreter_id+1) { + new_data->count = interpreter_id+1; + } + *old_data = new_data; + return 0; +} +static void __Pyx_State_ConvertFromInterpIdAsIndex(__Pyx_ModuleStateLookupData *data) { + __Pyx_InterpreterIdAndModule *read = data->table; + __Pyx_InterpreterIdAndModule *write = data->table; + __Pyx_InterpreterIdAndModule *end = read + data->count; + for (; readmodule) { + write->id = read->id; + write->module = read->module; + ++write; + } + } + data->count = write - data->table; + for (; writeid = 0; + write->module = NULL; + } + data->interpreter_id_as_index = 0; +} +static int __Pyx_State_AddModule(PyObject* module, CYTHON_UNUSED void* dummy) { + int64_t interpreter_id = PyInterpreterState_GetID(__Pyx_PyInterpreterState_Get()); + if (interpreter_id == -1) return -1; + int result = 0; + __Pyx_ModuleStateLookup_Lock(); +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __Pyx_ModuleStateLookupData *old_data = (__Pyx_ModuleStateLookupData *) + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, 0); +#else + __Pyx_ModuleStateLookupData *old_data = __Pyx_ModuleStateLookup_data; +#endif + __Pyx_ModuleStateLookupData *new_data = old_data; + if (!new_data) { + new_data = (__Pyx_ModuleStateLookupData *)calloc(1, sizeof(__Pyx_ModuleStateLookupData)); + if (!new_data) { + result = -1; + PyErr_NoMemory(); + goto end; + } + new_data->allocated = 1; + new_data->interpreter_id_as_index = 1; + } + __Pyx_ModuleStateLookup_wait_until_no_readers(); + if (new_data->interpreter_id_as_index) { + if (interpreter_id < __PYX_MODULE_STATE_LOOKUP_SMALL_SIZE) { + result = __Pyx_State_AddModuleInterpIdAsIndex(&new_data, module, interpreter_id); + goto end; + } + __Pyx_State_ConvertFromInterpIdAsIndex(new_data); + } + { + Py_ssize_t insert_at = 0; + { + __Pyx_InterpreterIdAndModule* lower_bound = __Pyx_State_FindModuleStateLookupTableLowerBound( + new_data->table, new_data->count, interpreter_id); + assert(lower_bound); + insert_at = lower_bound - new_data->table; + if (unlikely(insert_at < new_data->count && lower_bound->id == interpreter_id)) { + lower_bound->module = module; + goto end; // already in table, nothing more to do + } + } + if (new_data->count+1 >= new_data->allocated) { + Py_ssize_t to_allocate = (new_data->count+1)*2; + new_data = + (__Pyx_ModuleStateLookupData*)realloc( + new_data, + sizeof(__Pyx_ModuleStateLookupData) + + (to_allocate-1)*sizeof(__Pyx_InterpreterIdAndModule)); + if (!new_data) { + result = -1; + new_data = old_data; + PyErr_NoMemory(); + goto end; + } + new_data->allocated = to_allocate; + } + ++new_data->count; + int64_t last_id = interpreter_id; + PyObject *last_module = module; + for (Py_ssize_t i=insert_at; icount; ++i) { + int64_t current_id = new_data->table[i].id; + new_data->table[i].id = last_id; + last_id = current_id; + PyObject *current_module = new_data->table[i].module; + new_data->table[i].module = last_module; + last_module = current_module; + } + } + end: +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, new_data); +#else + __Pyx_ModuleStateLookup_data = new_data; +#endif + __Pyx_ModuleStateLookup_Unlock(); + return result; +} +static int __Pyx_State_RemoveModule(CYTHON_UNUSED void* dummy) { + int64_t interpreter_id = PyInterpreterState_GetID(__Pyx_PyInterpreterState_Get()); + if (interpreter_id == -1) return -1; + __Pyx_ModuleStateLookup_Lock(); +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __Pyx_ModuleStateLookupData *data = (__Pyx_ModuleStateLookupData *) + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, 0); +#else + __Pyx_ModuleStateLookupData *data = __Pyx_ModuleStateLookup_data; +#endif + if (data->interpreter_id_as_index) { + if (interpreter_id < data->count) { + data->table[interpreter_id].module = NULL; + } + goto done; + } + { + __Pyx_ModuleStateLookup_wait_until_no_readers(); + __Pyx_InterpreterIdAndModule* lower_bound = __Pyx_State_FindModuleStateLookupTableLowerBound( + data->table, data->count, interpreter_id); + if (!lower_bound) goto done; + if (lower_bound->id != interpreter_id) goto done; + __Pyx_InterpreterIdAndModule *end = data->table+data->count; + for (;lower_boundid = (lower_bound+1)->id; + lower_bound->module = (lower_bound+1)->module; + } + } + --data->count; + if (data->count == 0) { + free(data); + data = NULL; + } + done: +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, data); +#else + __Pyx_ModuleStateLookup_data = data; +#endif + __Pyx_ModuleStateLookup_Unlock(); + return 0; +} +#endif + +/* #### Code section: utility_code_pragmas_end ### */ +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + + + +/* #### Code section: end ### */ +#endif /* Py_PYTHON_H */ diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/bezierTools.py b/.venv/lib/python3.13/site-packages/fontTools/misc/bezierTools.py new file mode 100644 index 0000000000000000000000000000000000000000..efdbdaaeaf3bad275204dabda4cb8f024b31ed91 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/bezierTools.py @@ -0,0 +1,1500 @@ +# -*- coding: utf-8 -*- +"""fontTools.misc.bezierTools.py -- tools for working with Bezier path segments. +""" + +from fontTools.misc.arrayTools import calcBounds, sectRect, rectArea +from fontTools.misc.transform import Identity +import math +from collections import namedtuple + +try: + import cython +except (AttributeError, ImportError): + # if cython not installed, use mock module with no-op decorators and types + from fontTools.misc import cython +COMPILED = cython.compiled + + +EPSILON = 1e-9 + + +Intersection = namedtuple("Intersection", ["pt", "t1", "t2"]) + + +__all__ = [ + "approximateCubicArcLength", + "approximateCubicArcLengthC", + "approximateQuadraticArcLength", + "approximateQuadraticArcLengthC", + "calcCubicArcLength", + "calcCubicArcLengthC", + "calcQuadraticArcLength", + "calcQuadraticArcLengthC", + "calcCubicBounds", + "calcQuadraticBounds", + "splitLine", + "splitQuadratic", + "splitCubic", + "splitQuadraticAtT", + "splitCubicAtT", + "splitCubicAtTC", + "splitCubicIntoTwoAtTC", + "solveQuadratic", + "solveCubic", + "quadraticPointAtT", + "cubicPointAtT", + "cubicPointAtTC", + "linePointAtT", + "segmentPointAtT", + "lineLineIntersections", + "curveLineIntersections", + "curveCurveIntersections", + "segmentSegmentIntersections", +] + + +def calcCubicArcLength(pt1, pt2, pt3, pt4, tolerance=0.005): + """Calculates the arc length for a cubic Bezier segment. + + Whereas :func:`approximateCubicArcLength` approximates the length, this + function calculates it by "measuring", recursively dividing the curve + until the divided segments are shorter than ``tolerance``. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples. + tolerance: Controls the precision of the calcuation. + + Returns: + Arc length value. + """ + return calcCubicArcLengthC( + complex(*pt1), complex(*pt2), complex(*pt3), complex(*pt4), tolerance + ) + + +def _split_cubic_into_two(p0, p1, p2, p3): + mid = (p0 + 3 * (p1 + p2) + p3) * 0.125 + deriv3 = (p3 + p2 - p1 - p0) * 0.125 + return ( + (p0, (p0 + p1) * 0.5, mid - deriv3, mid), + (mid, mid + deriv3, (p2 + p3) * 0.5, p3), + ) + + +@cython.returns(cython.double) +@cython.locals( + p0=cython.complex, + p1=cython.complex, + p2=cython.complex, + p3=cython.complex, +) +@cython.locals(mult=cython.double, arch=cython.double, box=cython.double) +def _calcCubicArcLengthCRecurse(mult, p0, p1, p2, p3): + arch = abs(p0 - p3) + box = abs(p0 - p1) + abs(p1 - p2) + abs(p2 - p3) + if arch * mult + EPSILON >= box: + return (arch + box) * 0.5 + else: + one, two = _split_cubic_into_two(p0, p1, p2, p3) + return _calcCubicArcLengthCRecurse(mult, *one) + _calcCubicArcLengthCRecurse( + mult, *two + ) + + +@cython.returns(cython.double) +@cython.locals( + pt1=cython.complex, + pt2=cython.complex, + pt3=cython.complex, + pt4=cython.complex, +) +@cython.locals( + tolerance=cython.double, + mult=cython.double, +) +def calcCubicArcLengthC(pt1, pt2, pt3, pt4, tolerance=0.005): + """Calculates the arc length for a cubic Bezier segment. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers. + tolerance: Controls the precision of the calcuation. + + Returns: + Arc length value. + """ + mult = 1.0 + 1.5 * tolerance # The 1.5 is a empirical hack; no math + return _calcCubicArcLengthCRecurse(mult, pt1, pt2, pt3, pt4) + + +epsilonDigits = 6 +epsilon = 1e-10 + + +@cython.cfunc +@cython.inline +@cython.returns(cython.double) +@cython.locals(v1=cython.complex, v2=cython.complex) +def _dot(v1, v2): + return (v1 * v2.conjugate()).real + + +@cython.cfunc +@cython.inline +@cython.returns(cython.double) +@cython.locals(x=cython.double) +def _intSecAtan(x): + # In : sympy.integrate(sp.sec(sp.atan(x))) + # Out: x*sqrt(x**2 + 1)/2 + asinh(x)/2 + return x * math.sqrt(x**2 + 1) / 2 + math.asinh(x) / 2 + + +def calcQuadraticArcLength(pt1, pt2, pt3): + """Calculates the arc length for a quadratic Bezier segment. + + Args: + pt1: Start point of the Bezier as 2D tuple. + pt2: Handle point of the Bezier as 2D tuple. + pt3: End point of the Bezier as 2D tuple. + + Returns: + Arc length value. + + Example:: + + >>> calcQuadraticArcLength((0, 0), (0, 0), (0, 0)) # empty segment + 0.0 + >>> calcQuadraticArcLength((0, 0), (50, 0), (80, 0)) # collinear points + 80.0 + >>> calcQuadraticArcLength((0, 0), (0, 50), (0, 80)) # collinear points vertical + 80.0 + >>> calcQuadraticArcLength((0, 0), (50, 20), (100, 40)) # collinear points + 107.70329614269008 + >>> calcQuadraticArcLength((0, 0), (0, 100), (100, 0)) + 154.02976155645263 + >>> calcQuadraticArcLength((0, 0), (0, 50), (100, 0)) + 120.21581243984076 + >>> calcQuadraticArcLength((0, 0), (50, -10), (80, 50)) + 102.53273816445825 + >>> calcQuadraticArcLength((0, 0), (40, 0), (-40, 0)) # collinear points, control point outside + 66.66666666666667 + >>> calcQuadraticArcLength((0, 0), (40, 0), (0, 0)) # collinear points, looping back + 40.0 + """ + return calcQuadraticArcLengthC(complex(*pt1), complex(*pt2), complex(*pt3)) + + +@cython.returns(cython.double) +@cython.locals( + pt1=cython.complex, + pt2=cython.complex, + pt3=cython.complex, + d0=cython.complex, + d1=cython.complex, + d=cython.complex, + n=cython.complex, +) +@cython.locals( + scale=cython.double, + origDist=cython.double, + a=cython.double, + b=cython.double, + x0=cython.double, + x1=cython.double, + Len=cython.double, +) +def calcQuadraticArcLengthC(pt1, pt2, pt3): + """Calculates the arc length for a quadratic Bezier segment. + + Args: + pt1: Start point of the Bezier as a complex number. + pt2: Handle point of the Bezier as a complex number. + pt3: End point of the Bezier as a complex number. + + Returns: + Arc length value. + """ + # Analytical solution to the length of a quadratic bezier. + # Documentation: https://github.com/fonttools/fonttools/issues/3055 + d0 = pt2 - pt1 + d1 = pt3 - pt2 + d = d1 - d0 + n = d * 1j + scale = abs(n) + if scale == 0.0: + return abs(pt3 - pt1) + origDist = _dot(n, d0) + if abs(origDist) < epsilon: + if _dot(d0, d1) >= 0: + return abs(pt3 - pt1) + a, b = abs(d0), abs(d1) + return (a * a + b * b) / (a + b) + x0 = _dot(d, d0) / origDist + x1 = _dot(d, d1) / origDist + Len = abs(2 * (_intSecAtan(x1) - _intSecAtan(x0)) * origDist / (scale * (x1 - x0))) + return Len + + +def approximateQuadraticArcLength(pt1, pt2, pt3): + """Calculates the arc length for a quadratic Bezier segment. + + Uses Gauss-Legendre quadrature for a branch-free approximation. + See :func:`calcQuadraticArcLength` for a slower but more accurate result. + + Args: + pt1: Start point of the Bezier as 2D tuple. + pt2: Handle point of the Bezier as 2D tuple. + pt3: End point of the Bezier as 2D tuple. + + Returns: + Approximate arc length value. + """ + return approximateQuadraticArcLengthC(complex(*pt1), complex(*pt2), complex(*pt3)) + + +@cython.returns(cython.double) +@cython.locals( + pt1=cython.complex, + pt2=cython.complex, + pt3=cython.complex, +) +@cython.locals( + v0=cython.double, + v1=cython.double, + v2=cython.double, +) +def approximateQuadraticArcLengthC(pt1, pt2, pt3): + """Calculates the arc length for a quadratic Bezier segment. + + Uses Gauss-Legendre quadrature for a branch-free approximation. + See :func:`calcQuadraticArcLength` for a slower but more accurate result. + + Args: + pt1: Start point of the Bezier as a complex number. + pt2: Handle point of the Bezier as a complex number. + pt3: End point of the Bezier as a complex number. + + Returns: + Approximate arc length value. + """ + # This, essentially, approximates the length-of-derivative function + # to be integrated with the best-matching fifth-degree polynomial + # approximation of it. + # + # https://en.wikipedia.org/wiki/Gaussian_quadrature#Gauss.E2.80.93Legendre_quadrature + + # abs(BezierCurveC[2].diff(t).subs({t:T})) for T in sorted(.5, .5±sqrt(3/5)/2), + # weighted 5/18, 8/18, 5/18 respectively. + v0 = abs( + -0.492943519233745 * pt1 + 0.430331482911935 * pt2 + 0.0626120363218102 * pt3 + ) + v1 = abs(pt3 - pt1) * 0.4444444444444444 + v2 = abs( + -0.0626120363218102 * pt1 - 0.430331482911935 * pt2 + 0.492943519233745 * pt3 + ) + + return v0 + v1 + v2 + + +def calcQuadraticBounds(pt1, pt2, pt3): + """Calculates the bounding rectangle for a quadratic Bezier segment. + + Args: + pt1: Start point of the Bezier as a 2D tuple. + pt2: Handle point of the Bezier as a 2D tuple. + pt3: End point of the Bezier as a 2D tuple. + + Returns: + A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``. + + Example:: + + >>> calcQuadraticBounds((0, 0), (50, 100), (100, 0)) + (0, 0, 100, 50.0) + >>> calcQuadraticBounds((0, 0), (100, 0), (100, 100)) + (0.0, 0.0, 100, 100) + """ + (ax, ay), (bx, by), (cx, cy) = calcQuadraticParameters(pt1, pt2, pt3) + ax2 = ax * 2.0 + ay2 = ay * 2.0 + roots = [] + if ax2 != 0: + roots.append(-bx / ax2) + if ay2 != 0: + roots.append(-by / ay2) + points = [ + (ax * t * t + bx * t + cx, ay * t * t + by * t + cy) + for t in roots + if 0 <= t < 1 + ] + [pt1, pt3] + return calcBounds(points) + + +def approximateCubicArcLength(pt1, pt2, pt3, pt4): + """Approximates the arc length for a cubic Bezier segment. + + Uses Gauss-Lobatto quadrature with n=5 points to approximate arc length. + See :func:`calcCubicArcLength` for a slower but more accurate result. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples. + + Returns: + Arc length value. + + Example:: + + >>> approximateCubicArcLength((0, 0), (25, 100), (75, 100), (100, 0)) + 190.04332968932817 + >>> approximateCubicArcLength((0, 0), (50, 0), (100, 50), (100, 100)) + 154.8852074945903 + >>> approximateCubicArcLength((0, 0), (50, 0), (100, 0), (150, 0)) # line; exact result should be 150. + 149.99999999999991 + >>> approximateCubicArcLength((0, 0), (50, 0), (100, 0), (-50, 0)) # cusp; exact result should be 150. + 136.9267662156362 + >>> approximateCubicArcLength((0, 0), (50, 0), (100, -50), (-50, 0)) # cusp + 154.80848416537057 + """ + return approximateCubicArcLengthC( + complex(*pt1), complex(*pt2), complex(*pt3), complex(*pt4) + ) + + +@cython.returns(cython.double) +@cython.locals( + pt1=cython.complex, + pt2=cython.complex, + pt3=cython.complex, + pt4=cython.complex, +) +@cython.locals( + v0=cython.double, + v1=cython.double, + v2=cython.double, + v3=cython.double, + v4=cython.double, +) +def approximateCubicArcLengthC(pt1, pt2, pt3, pt4): + """Approximates the arc length for a cubic Bezier segment. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers. + + Returns: + Arc length value. + """ + # This, essentially, approximates the length-of-derivative function + # to be integrated with the best-matching seventh-degree polynomial + # approximation of it. + # + # https://en.wikipedia.org/wiki/Gaussian_quadrature#Gauss.E2.80.93Lobatto_rules + + # abs(BezierCurveC[3].diff(t).subs({t:T})) for T in sorted(0, .5±(3/7)**.5/2, .5, 1), + # weighted 1/20, 49/180, 32/90, 49/180, 1/20 respectively. + v0 = abs(pt2 - pt1) * 0.15 + v1 = abs( + -0.558983582205757 * pt1 + + 0.325650248872424 * pt2 + + 0.208983582205757 * pt3 + + 0.024349751127576 * pt4 + ) + v2 = abs(pt4 - pt1 + pt3 - pt2) * 0.26666666666666666 + v3 = abs( + -0.024349751127576 * pt1 + - 0.208983582205757 * pt2 + - 0.325650248872424 * pt3 + + 0.558983582205757 * pt4 + ) + v4 = abs(pt4 - pt3) * 0.15 + + return v0 + v1 + v2 + v3 + v4 + + +def calcCubicBounds(pt1, pt2, pt3, pt4): + """Calculates the bounding rectangle for a quadratic Bezier segment. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples. + + Returns: + A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``. + + Example:: + + >>> calcCubicBounds((0, 0), (25, 100), (75, 100), (100, 0)) + (0, 0, 100, 75.0) + >>> calcCubicBounds((0, 0), (50, 0), (100, 50), (100, 100)) + (0.0, 0.0, 100, 100) + >>> print("%f %f %f %f" % calcCubicBounds((50, 0), (0, 100), (100, 100), (50, 0))) + 35.566243 0.000000 64.433757 75.000000 + """ + (ax, ay), (bx, by), (cx, cy), (dx, dy) = calcCubicParameters(pt1, pt2, pt3, pt4) + # calc first derivative + ax3 = ax * 3.0 + ay3 = ay * 3.0 + bx2 = bx * 2.0 + by2 = by * 2.0 + xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1] + yRoots = [t for t in solveQuadratic(ay3, by2, cy) if 0 <= t < 1] + roots = xRoots + yRoots + + points = [ + ( + ax * t * t * t + bx * t * t + cx * t + dx, + ay * t * t * t + by * t * t + cy * t + dy, + ) + for t in roots + ] + [pt1, pt4] + return calcBounds(points) + + +def splitLine(pt1, pt2, where, isHorizontal): + """Split a line at a given coordinate. + + Args: + pt1: Start point of line as 2D tuple. + pt2: End point of line as 2D tuple. + where: Position at which to split the line. + isHorizontal: Direction of the ray splitting the line. If true, + ``where`` is interpreted as a Y coordinate; if false, then + ``where`` is interpreted as an X coordinate. + + Returns: + A list of two line segments (each line segment being two 2D tuples) + if the line was successfully split, or a list containing the original + line. + + Example:: + + >>> printSegments(splitLine((0, 0), (100, 100), 50, True)) + ((0, 0), (50, 50)) + ((50, 50), (100, 100)) + >>> printSegments(splitLine((0, 0), (100, 100), 100, True)) + ((0, 0), (100, 100)) + >>> printSegments(splitLine((0, 0), (100, 100), 0, True)) + ((0, 0), (0, 0)) + ((0, 0), (100, 100)) + >>> printSegments(splitLine((0, 0), (100, 100), 0, False)) + ((0, 0), (0, 0)) + ((0, 0), (100, 100)) + >>> printSegments(splitLine((100, 0), (0, 0), 50, False)) + ((100, 0), (50, 0)) + ((50, 0), (0, 0)) + >>> printSegments(splitLine((0, 100), (0, 0), 50, True)) + ((0, 100), (0, 50)) + ((0, 50), (0, 0)) + """ + pt1x, pt1y = pt1 + pt2x, pt2y = pt2 + + ax = pt2x - pt1x + ay = pt2y - pt1y + + bx = pt1x + by = pt1y + + a = (ax, ay)[isHorizontal] + + if a == 0: + return [(pt1, pt2)] + t = (where - (bx, by)[isHorizontal]) / a + if 0 <= t < 1: + midPt = ax * t + bx, ay * t + by + return [(pt1, midPt), (midPt, pt2)] + else: + return [(pt1, pt2)] + + +def splitQuadratic(pt1, pt2, pt3, where, isHorizontal): + """Split a quadratic Bezier curve at a given coordinate. + + Args: + pt1,pt2,pt3: Control points of the Bezier as 2D tuples. + where: Position at which to split the curve. + isHorizontal: Direction of the ray splitting the curve. If true, + ``where`` is interpreted as a Y coordinate; if false, then + ``where`` is interpreted as an X coordinate. + + Returns: + A list of two curve segments (each curve segment being three 2D tuples) + if the curve was successfully split, or a list containing the original + curve. + + Example:: + + >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 150, False)) + ((0, 0), (50, 100), (100, 0)) + >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, False)) + ((0, 0), (25, 50), (50, 50)) + ((50, 50), (75, 50), (100, 0)) + >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, False)) + ((0, 0), (12.5, 25), (25, 37.5)) + ((25, 37.5), (62.5, 75), (100, 0)) + >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, True)) + ((0, 0), (7.32233, 14.6447), (14.6447, 25)) + ((14.6447, 25), (50, 75), (85.3553, 25)) + ((85.3553, 25), (92.6777, 14.6447), (100, -7.10543e-15)) + >>> # XXX I'm not at all sure if the following behavior is desirable: + >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, True)) + ((0, 0), (25, 50), (50, 50)) + ((50, 50), (50, 50), (50, 50)) + ((50, 50), (75, 50), (100, 0)) + """ + a, b, c = calcQuadraticParameters(pt1, pt2, pt3) + solutions = solveQuadratic( + a[isHorizontal], b[isHorizontal], c[isHorizontal] - where + ) + solutions = sorted(t for t in solutions if 0 <= t < 1) + if not solutions: + return [(pt1, pt2, pt3)] + return _splitQuadraticAtT(a, b, c, *solutions) + + +def splitCubic(pt1, pt2, pt3, pt4, where, isHorizontal): + """Split a cubic Bezier curve at a given coordinate. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples. + where: Position at which to split the curve. + isHorizontal: Direction of the ray splitting the curve. If true, + ``where`` is interpreted as a Y coordinate; if false, then + ``where`` is interpreted as an X coordinate. + + Returns: + A list of two curve segments (each curve segment being four 2D tuples) + if the curve was successfully split, or a list containing the original + curve. + + Example:: + + >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 150, False)) + ((0, 0), (25, 100), (75, 100), (100, 0)) + >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 50, False)) + ((0, 0), (12.5, 50), (31.25, 75), (50, 75)) + ((50, 75), (68.75, 75), (87.5, 50), (100, 0)) + >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 25, True)) + ((0, 0), (2.29379, 9.17517), (4.79804, 17.5085), (7.47414, 25)) + ((7.47414, 25), (31.2886, 91.6667), (68.7114, 91.6667), (92.5259, 25)) + ((92.5259, 25), (95.202, 17.5085), (97.7062, 9.17517), (100, 1.77636e-15)) + """ + a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) + solutions = solveCubic( + a[isHorizontal], b[isHorizontal], c[isHorizontal], d[isHorizontal] - where + ) + solutions = sorted(t for t in solutions if 0 <= t < 1) + if not solutions: + return [(pt1, pt2, pt3, pt4)] + return _splitCubicAtT(a, b, c, d, *solutions) + + +def splitQuadraticAtT(pt1, pt2, pt3, *ts): + """Split a quadratic Bezier curve at one or more values of t. + + Args: + pt1,pt2,pt3: Control points of the Bezier as 2D tuples. + *ts: Positions at which to split the curve. + + Returns: + A list of curve segments (each curve segment being three 2D tuples). + + Examples:: + + >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5)) + ((0, 0), (25, 50), (50, 50)) + ((50, 50), (75, 50), (100, 0)) + >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5, 0.75)) + ((0, 0), (25, 50), (50, 50)) + ((50, 50), (62.5, 50), (75, 37.5)) + ((75, 37.5), (87.5, 25), (100, 0)) + """ + a, b, c = calcQuadraticParameters(pt1, pt2, pt3) + return _splitQuadraticAtT(a, b, c, *ts) + + +def splitCubicAtT(pt1, pt2, pt3, pt4, *ts): + """Split a cubic Bezier curve at one or more values of t. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples. + *ts: Positions at which to split the curve. + + Returns: + A list of curve segments (each curve segment being four 2D tuples). + + Examples:: + + >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5)) + ((0, 0), (12.5, 50), (31.25, 75), (50, 75)) + ((50, 75), (68.75, 75), (87.5, 50), (100, 0)) + >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5, 0.75)) + ((0, 0), (12.5, 50), (31.25, 75), (50, 75)) + ((50, 75), (59.375, 75), (68.75, 68.75), (77.3438, 56.25)) + ((77.3438, 56.25), (85.9375, 43.75), (93.75, 25), (100, 0)) + """ + a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) + split = _splitCubicAtT(a, b, c, d, *ts) + + # the split impl can introduce floating point errors; we know the first + # segment should always start at pt1 and the last segment should end at pt4, + # so we set those values directly before returning. + split[0] = (pt1, *split[0][1:]) + split[-1] = (*split[-1][:-1], pt4) + return split + + +@cython.locals( + pt1=cython.complex, + pt2=cython.complex, + pt3=cython.complex, + pt4=cython.complex, + a=cython.complex, + b=cython.complex, + c=cython.complex, + d=cython.complex, +) +def splitCubicAtTC(pt1, pt2, pt3, pt4, *ts): + """Split a cubic Bezier curve at one or more values of t. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers.. + *ts: Positions at which to split the curve. + + Yields: + Curve segments (each curve segment being four complex numbers). + """ + a, b, c, d = calcCubicParametersC(pt1, pt2, pt3, pt4) + yield from _splitCubicAtTC(a, b, c, d, *ts) + + +@cython.returns(cython.complex) +@cython.locals( + t=cython.double, + pt1=cython.complex, + pt2=cython.complex, + pt3=cython.complex, + pt4=cython.complex, + pointAtT=cython.complex, + off1=cython.complex, + off2=cython.complex, +) +@cython.locals( + t2=cython.double, _1_t=cython.double, _1_t_2=cython.double, _2_t_1_t=cython.double +) +def splitCubicIntoTwoAtTC(pt1, pt2, pt3, pt4, t): + """Split a cubic Bezier curve at t. + + Args: + pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers. + t: Position at which to split the curve. + + Returns: + A tuple of two curve segments (each curve segment being four complex numbers). + """ + t2 = t * t + _1_t = 1 - t + _1_t_2 = _1_t * _1_t + _2_t_1_t = 2 * t * _1_t + pointAtT = ( + _1_t_2 * _1_t * pt1 + 3 * (_1_t_2 * t * pt2 + _1_t * t2 * pt3) + t2 * t * pt4 + ) + off1 = _1_t_2 * pt1 + _2_t_1_t * pt2 + t2 * pt3 + off2 = _1_t_2 * pt2 + _2_t_1_t * pt3 + t2 * pt4 + + pt2 = pt1 + (pt2 - pt1) * t + pt3 = pt4 + (pt3 - pt4) * _1_t + + return ((pt1, pt2, off1, pointAtT), (pointAtT, off2, pt3, pt4)) + + +def _splitQuadraticAtT(a, b, c, *ts): + ts = list(ts) + segments = [] + ts.insert(0, 0.0) + ts.append(1.0) + ax, ay = a + bx, by = b + cx, cy = c + for i in range(len(ts) - 1): + t1 = ts[i] + t2 = ts[i + 1] + delta = t2 - t1 + # calc new a, b and c + delta_2 = delta * delta + a1x = ax * delta_2 + a1y = ay * delta_2 + b1x = (2 * ax * t1 + bx) * delta + b1y = (2 * ay * t1 + by) * delta + t1_2 = t1 * t1 + c1x = ax * t1_2 + bx * t1 + cx + c1y = ay * t1_2 + by * t1 + cy + + pt1, pt2, pt3 = calcQuadraticPoints((a1x, a1y), (b1x, b1y), (c1x, c1y)) + segments.append((pt1, pt2, pt3)) + return segments + + +def _splitCubicAtT(a, b, c, d, *ts): + ts = list(ts) + ts.insert(0, 0.0) + ts.append(1.0) + segments = [] + ax, ay = a + bx, by = b + cx, cy = c + dx, dy = d + for i in range(len(ts) - 1): + t1 = ts[i] + t2 = ts[i + 1] + delta = t2 - t1 + + delta_2 = delta * delta + delta_3 = delta * delta_2 + t1_2 = t1 * t1 + t1_3 = t1 * t1_2 + + # calc new a, b, c and d + a1x = ax * delta_3 + a1y = ay * delta_3 + b1x = (3 * ax * t1 + bx) * delta_2 + b1y = (3 * ay * t1 + by) * delta_2 + c1x = (2 * bx * t1 + cx + 3 * ax * t1_2) * delta + c1y = (2 * by * t1 + cy + 3 * ay * t1_2) * delta + d1x = ax * t1_3 + bx * t1_2 + cx * t1 + dx + d1y = ay * t1_3 + by * t1_2 + cy * t1 + dy + pt1, pt2, pt3, pt4 = calcCubicPoints( + (a1x, a1y), (b1x, b1y), (c1x, c1y), (d1x, d1y) + ) + segments.append((pt1, pt2, pt3, pt4)) + return segments + + +@cython.locals( + a=cython.complex, + b=cython.complex, + c=cython.complex, + d=cython.complex, + t1=cython.double, + t2=cython.double, + delta=cython.double, + delta_2=cython.double, + delta_3=cython.double, + a1=cython.complex, + b1=cython.complex, + c1=cython.complex, + d1=cython.complex, +) +def _splitCubicAtTC(a, b, c, d, *ts): + ts = list(ts) + ts.insert(0, 0.0) + ts.append(1.0) + for i in range(len(ts) - 1): + t1 = ts[i] + t2 = ts[i + 1] + delta = t2 - t1 + + delta_2 = delta * delta + delta_3 = delta * delta_2 + t1_2 = t1 * t1 + t1_3 = t1 * t1_2 + + # calc new a, b, c and d + a1 = a * delta_3 + b1 = (3 * a * t1 + b) * delta_2 + c1 = (2 * b * t1 + c + 3 * a * t1_2) * delta + d1 = a * t1_3 + b * t1_2 + c * t1 + d + pt1, pt2, pt3, pt4 = calcCubicPointsC(a1, b1, c1, d1) + yield (pt1, pt2, pt3, pt4) + + +# +# Equation solvers. +# + +from math import sqrt, acos, cos, pi + + +def solveQuadratic(a, b, c, sqrt=sqrt): + """Solve a quadratic equation. + + Solves *a*x*x + b*x + c = 0* where a, b and c are real. + + Args: + a: coefficient of *x²* + b: coefficient of *x* + c: constant term + + Returns: + A list of roots. Note that the returned list is neither guaranteed to + be sorted nor to contain unique values! + """ + if abs(a) < epsilon: + if abs(b) < epsilon: + # We have a non-equation; therefore, we have no valid solution + roots = [] + else: + # We have a linear equation with 1 root. + roots = [-c / b] + else: + # We have a true quadratic equation. Apply the quadratic formula to find two roots. + DD = b * b - 4.0 * a * c + if DD >= 0.0: + rDD = sqrt(DD) + roots = [(-b + rDD) / 2.0 / a, (-b - rDD) / 2.0 / a] + else: + # complex roots, ignore + roots = [] + return roots + + +def solveCubic(a, b, c, d): + """Solve a cubic equation. + + Solves *a*x*x*x + b*x*x + c*x + d = 0* where a, b, c and d are real. + + Args: + a: coefficient of *x³* + b: coefficient of *x²* + c: coefficient of *x* + d: constant term + + Returns: + A list of roots. Note that the returned list is neither guaranteed to + be sorted nor to contain unique values! + + Examples:: + + >>> solveCubic(1, 1, -6, 0) + [-3.0, -0.0, 2.0] + >>> solveCubic(-10.0, -9.0, 48.0, -29.0) + [-2.9, 1.0, 1.0] + >>> solveCubic(-9.875, -9.0, 47.625, -28.75) + [-2.911392, 1.0, 1.0] + >>> solveCubic(1.0, -4.5, 6.75, -3.375) + [1.5, 1.5, 1.5] + >>> solveCubic(-12.0, 18.0, -9.0, 1.50023651123) + [0.5, 0.5, 0.5] + >>> solveCubic( + ... 9.0, 0.0, 0.0, -7.62939453125e-05 + ... ) == [-0.0, -0.0, -0.0] + True + """ + # + # adapted from: + # CUBIC.C - Solve a cubic polynomial + # public domain by Ross Cottrell + # found at: http://www.strangecreations.com/library/snippets/Cubic.C + # + if abs(a) < epsilon: + # don't just test for zero; for very small values of 'a' solveCubic() + # returns unreliable results, so we fall back to quad. + return solveQuadratic(b, c, d) + a = float(a) + a1 = b / a + a2 = c / a + a3 = d / a + + Q = (a1 * a1 - 3.0 * a2) / 9.0 + R = (2.0 * a1 * a1 * a1 - 9.0 * a1 * a2 + 27.0 * a3) / 54.0 + + R2 = R * R + Q3 = Q * Q * Q + R2 = 0 if R2 < epsilon else R2 + Q3 = 0 if abs(Q3) < epsilon else Q3 + + R2_Q3 = R2 - Q3 + + if R2 == 0.0 and Q3 == 0.0: + x = round(-a1 / 3.0, epsilonDigits) + return [x, x, x] + elif R2_Q3 <= epsilon * 0.5: + # The epsilon * .5 above ensures that Q3 is not zero. + theta = acos(max(min(R / sqrt(Q3), 1.0), -1.0)) + rQ2 = -2.0 * sqrt(Q) + a1_3 = a1 / 3.0 + x0 = rQ2 * cos(theta / 3.0) - a1_3 + x1 = rQ2 * cos((theta + 2.0 * pi) / 3.0) - a1_3 + x2 = rQ2 * cos((theta + 4.0 * pi) / 3.0) - a1_3 + x0, x1, x2 = sorted([x0, x1, x2]) + # Merge roots that are close-enough + if x1 - x0 < epsilon and x2 - x1 < epsilon: + x0 = x1 = x2 = round((x0 + x1 + x2) / 3.0, epsilonDigits) + elif x1 - x0 < epsilon: + x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits) + x2 = round(x2, epsilonDigits) + elif x2 - x1 < epsilon: + x0 = round(x0, epsilonDigits) + x1 = x2 = round((x1 + x2) / 2.0, epsilonDigits) + else: + x0 = round(x0, epsilonDigits) + x1 = round(x1, epsilonDigits) + x2 = round(x2, epsilonDigits) + return [x0, x1, x2] + else: + x = pow(sqrt(R2_Q3) + abs(R), 1 / 3.0) + x = x + Q / x + if R >= 0.0: + x = -x + x = round(x - a1 / 3.0, epsilonDigits) + return [x] + + +# +# Conversion routines for points to parameters and vice versa +# + + +def calcQuadraticParameters(pt1, pt2, pt3): + x2, y2 = pt2 + x3, y3 = pt3 + cx, cy = pt1 + bx = (x2 - cx) * 2.0 + by = (y2 - cy) * 2.0 + ax = x3 - cx - bx + ay = y3 - cy - by + return (ax, ay), (bx, by), (cx, cy) + + +def calcCubicParameters(pt1, pt2, pt3, pt4): + x2, y2 = pt2 + x3, y3 = pt3 + x4, y4 = pt4 + dx, dy = pt1 + cx = (x2 - dx) * 3.0 + cy = (y2 - dy) * 3.0 + bx = (x3 - x2) * 3.0 - cx + by = (y3 - y2) * 3.0 - cy + ax = x4 - dx - cx - bx + ay = y4 - dy - cy - by + return (ax, ay), (bx, by), (cx, cy), (dx, dy) + + +@cython.cfunc +@cython.inline +@cython.locals( + pt1=cython.complex, + pt2=cython.complex, + pt3=cython.complex, + pt4=cython.complex, + a=cython.complex, + b=cython.complex, + c=cython.complex, +) +def calcCubicParametersC(pt1, pt2, pt3, pt4): + c = (pt2 - pt1) * 3.0 + b = (pt3 - pt2) * 3.0 - c + a = pt4 - pt1 - c - b + return (a, b, c, pt1) + + +def calcQuadraticPoints(a, b, c): + ax, ay = a + bx, by = b + cx, cy = c + x1 = cx + y1 = cy + x2 = (bx * 0.5) + cx + y2 = (by * 0.5) + cy + x3 = ax + bx + cx + y3 = ay + by + cy + return (x1, y1), (x2, y2), (x3, y3) + + +def calcCubicPoints(a, b, c, d): + ax, ay = a + bx, by = b + cx, cy = c + dx, dy = d + x1 = dx + y1 = dy + x2 = (cx / 3.0) + dx + y2 = (cy / 3.0) + dy + x3 = (bx + cx) / 3.0 + x2 + y3 = (by + cy) / 3.0 + y2 + x4 = ax + dx + cx + bx + y4 = ay + dy + cy + by + return (x1, y1), (x2, y2), (x3, y3), (x4, y4) + + +@cython.cfunc +@cython.inline +@cython.locals( + a=cython.complex, + b=cython.complex, + c=cython.complex, + d=cython.complex, + p2=cython.complex, + p3=cython.complex, + p4=cython.complex, +) +def calcCubicPointsC(a, b, c, d): + p2 = c * (1 / 3) + d + p3 = (b + c) * (1 / 3) + p2 + p4 = a + b + c + d + return (d, p2, p3, p4) + + +# +# Point at time +# + + +def linePointAtT(pt1, pt2, t): + """Finds the point at time `t` on a line. + + Args: + pt1, pt2: Coordinates of the line as 2D tuples. + t: The time along the line. + + Returns: + A 2D tuple with the coordinates of the point. + """ + return ((pt1[0] * (1 - t) + pt2[0] * t), (pt1[1] * (1 - t) + pt2[1] * t)) + + +def quadraticPointAtT(pt1, pt2, pt3, t): + """Finds the point at time `t` on a quadratic curve. + + Args: + pt1, pt2, pt3: Coordinates of the curve as 2D tuples. + t: The time along the curve. + + Returns: + A 2D tuple with the coordinates of the point. + """ + x = (1 - t) * (1 - t) * pt1[0] + 2 * (1 - t) * t * pt2[0] + t * t * pt3[0] + y = (1 - t) * (1 - t) * pt1[1] + 2 * (1 - t) * t * pt2[1] + t * t * pt3[1] + return (x, y) + + +def cubicPointAtT(pt1, pt2, pt3, pt4, t): + """Finds the point at time `t` on a cubic curve. + + Args: + pt1, pt2, pt3, pt4: Coordinates of the curve as 2D tuples. + t: The time along the curve. + + Returns: + A 2D tuple with the coordinates of the point. + """ + t2 = t * t + _1_t = 1 - t + _1_t_2 = _1_t * _1_t + x = ( + _1_t_2 * _1_t * pt1[0] + + 3 * (_1_t_2 * t * pt2[0] + _1_t * t2 * pt3[0]) + + t2 * t * pt4[0] + ) + y = ( + _1_t_2 * _1_t * pt1[1] + + 3 * (_1_t_2 * t * pt2[1] + _1_t * t2 * pt3[1]) + + t2 * t * pt4[1] + ) + return (x, y) + + +@cython.returns(cython.complex) +@cython.locals( + t=cython.double, + pt1=cython.complex, + pt2=cython.complex, + pt3=cython.complex, + pt4=cython.complex, +) +@cython.locals(t2=cython.double, _1_t=cython.double, _1_t_2=cython.double) +def cubicPointAtTC(pt1, pt2, pt3, pt4, t): + """Finds the point at time `t` on a cubic curve. + + Args: + pt1, pt2, pt3, pt4: Coordinates of the curve as complex numbers. + t: The time along the curve. + + Returns: + A complex number with the coordinates of the point. + """ + t2 = t * t + _1_t = 1 - t + _1_t_2 = _1_t * _1_t + return _1_t_2 * _1_t * pt1 + 3 * (_1_t_2 * t * pt2 + _1_t * t2 * pt3) + t2 * t * pt4 + + +def segmentPointAtT(seg, t): + if len(seg) == 2: + return linePointAtT(*seg, t) + elif len(seg) == 3: + return quadraticPointAtT(*seg, t) + elif len(seg) == 4: + return cubicPointAtT(*seg, t) + raise ValueError("Unknown curve degree") + + +# +# Intersection finders +# + + +def _line_t_of_pt(s, e, pt): + sx, sy = s + ex, ey = e + px, py = pt + if abs(sx - ex) < epsilon and abs(sy - ey) < epsilon: + # Line is a point! + return -1 + # Use the largest + if abs(sx - ex) > abs(sy - ey): + return (px - sx) / (ex - sx) + else: + return (py - sy) / (ey - sy) + + +def _both_points_are_on_same_side_of_origin(a, b, origin): + xDiff = (a[0] - origin[0]) * (b[0] - origin[0]) + yDiff = (a[1] - origin[1]) * (b[1] - origin[1]) + return not (xDiff <= 0.0 and yDiff <= 0.0) + + +def lineLineIntersections(s1, e1, s2, e2): + """Finds intersections between two line segments. + + Args: + s1, e1: Coordinates of the first line as 2D tuples. + s2, e2: Coordinates of the second line as 2D tuples. + + Returns: + A list of ``Intersection`` objects, each object having ``pt``, ``t1`` + and ``t2`` attributes containing the intersection point, time on first + segment and time on second segment respectively. + + Examples:: + + >>> a = lineLineIntersections( (310,389), (453, 222), (289, 251), (447, 367)) + >>> len(a) + 1 + >>> intersection = a[0] + >>> intersection.pt + (374.44882952482897, 313.73458370177315) + >>> (intersection.t1, intersection.t2) + (0.45069111555824465, 0.5408153767394238) + """ + s1x, s1y = s1 + e1x, e1y = e1 + s2x, s2y = s2 + e2x, e2y = e2 + if ( + math.isclose(s2x, e2x) and math.isclose(s1x, e1x) and not math.isclose(s1x, s2x) + ): # Parallel vertical + return [] + if ( + math.isclose(s2y, e2y) and math.isclose(s1y, e1y) and not math.isclose(s1y, s2y) + ): # Parallel horizontal + return [] + if math.isclose(s2x, e2x) and math.isclose(s2y, e2y): # Line segment is tiny + return [] + if math.isclose(s1x, e1x) and math.isclose(s1y, e1y): # Line segment is tiny + return [] + if math.isclose(e1x, s1x): + x = s1x + slope34 = (e2y - s2y) / (e2x - s2x) + y = slope34 * (x - s2x) + s2y + pt = (x, y) + return [ + Intersection( + pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + ) + ] + if math.isclose(s2x, e2x): + x = s2x + slope12 = (e1y - s1y) / (e1x - s1x) + y = slope12 * (x - s1x) + s1y + pt = (x, y) + return [ + Intersection( + pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + ) + ] + + slope12 = (e1y - s1y) / (e1x - s1x) + slope34 = (e2y - s2y) / (e2x - s2x) + if math.isclose(slope12, slope34): + return [] + x = (slope12 * s1x - s1y - slope34 * s2x + s2y) / (slope12 - slope34) + y = slope12 * (x - s1x) + s1y + pt = (x, y) + if _both_points_are_on_same_side_of_origin( + pt, e1, s1 + ) and _both_points_are_on_same_side_of_origin(pt, s2, e2): + return [ + Intersection( + pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) + ) + ] + return [] + + +def _alignment_transformation(segment): + # Returns a transformation which aligns a segment horizontally at the + # origin. Apply this transformation to curves and root-find to find + # intersections with the segment. + start = segment[0] + end = segment[-1] + angle = math.atan2(end[1] - start[1], end[0] - start[0]) + return Identity.rotate(-angle).translate(-start[0], -start[1]) + + +def _curve_line_intersections_t(curve, line): + aligned_curve = _alignment_transformation(line).transformPoints(curve) + if len(curve) == 3: + a, b, c = calcQuadraticParameters(*aligned_curve) + intersections = solveQuadratic(a[1], b[1], c[1]) + elif len(curve) == 4: + a, b, c, d = calcCubicParameters(*aligned_curve) + intersections = solveCubic(a[1], b[1], c[1], d[1]) + else: + raise ValueError("Unknown curve degree") + return sorted(i for i in intersections if 0.0 <= i <= 1) + + +def curveLineIntersections(curve, line): + """Finds intersections between a curve and a line. + + Args: + curve: List of coordinates of the curve segment as 2D tuples. + line: List of coordinates of the line segment as 2D tuples. + + Returns: + A list of ``Intersection`` objects, each object having ``pt``, ``t1`` + and ``t2`` attributes containing the intersection point, time on first + segment and time on second segment respectively. + + Examples:: + >>> curve = [ (100, 240), (30, 60), (210, 230), (160, 30) ] + >>> line = [ (25, 260), (230, 20) ] + >>> intersections = curveLineIntersections(curve, line) + >>> len(intersections) + 3 + >>> intersections[0].pt + (84.9000930760723, 189.87306176459828) + """ + if len(curve) == 3: + pointFinder = quadraticPointAtT + elif len(curve) == 4: + pointFinder = cubicPointAtT + else: + raise ValueError("Unknown curve degree") + intersections = [] + for t in _curve_line_intersections_t(curve, line): + pt = pointFinder(*curve, t) + # Back-project the point onto the line, to avoid problems with + # numerical accuracy in the case of vertical and horizontal lines + line_t = _line_t_of_pt(*line, pt) + pt = linePointAtT(*line, line_t) + intersections.append(Intersection(pt=pt, t1=t, t2=line_t)) + return intersections + + +def _curve_bounds(c): + if len(c) == 3: + return calcQuadraticBounds(*c) + elif len(c) == 4: + return calcCubicBounds(*c) + raise ValueError("Unknown curve degree") + + +def _split_segment_at_t(c, t): + if len(c) == 2: + s, e = c + midpoint = linePointAtT(s, e, t) + return [(s, midpoint), (midpoint, e)] + if len(c) == 3: + return splitQuadraticAtT(*c, t) + elif len(c) == 4: + return splitCubicAtT(*c, t) + raise ValueError("Unknown curve degree") + + +def _curve_curve_intersections_t( + curve1, curve2, precision=1e-3, range1=None, range2=None +): + bounds1 = _curve_bounds(curve1) + bounds2 = _curve_bounds(curve2) + + if not range1: + range1 = (0.0, 1.0) + if not range2: + range2 = (0.0, 1.0) + + # If bounds don't intersect, go home + intersects, _ = sectRect(bounds1, bounds2) + if not intersects: + return [] + + def midpoint(r): + return 0.5 * (r[0] + r[1]) + + # If they do overlap but they're tiny, approximate + if rectArea(bounds1) < precision and rectArea(bounds2) < precision: + return [(midpoint(range1), midpoint(range2))] + + c11, c12 = _split_segment_at_t(curve1, 0.5) + c11_range = (range1[0], midpoint(range1)) + c12_range = (midpoint(range1), range1[1]) + + c21, c22 = _split_segment_at_t(curve2, 0.5) + c21_range = (range2[0], midpoint(range2)) + c22_range = (midpoint(range2), range2[1]) + + found = [] + found.extend( + _curve_curve_intersections_t( + c11, c21, precision, range1=c11_range, range2=c21_range + ) + ) + found.extend( + _curve_curve_intersections_t( + c12, c21, precision, range1=c12_range, range2=c21_range + ) + ) + found.extend( + _curve_curve_intersections_t( + c11, c22, precision, range1=c11_range, range2=c22_range + ) + ) + found.extend( + _curve_curve_intersections_t( + c12, c22, precision, range1=c12_range, range2=c22_range + ) + ) + + unique_key = lambda ts: (int(ts[0] / precision), int(ts[1] / precision)) + seen = set() + unique_values = [] + + for ts in found: + key = unique_key(ts) + if key in seen: + continue + seen.add(key) + unique_values.append(ts) + + return unique_values + + +def _is_linelike(segment): + maybeline = _alignment_transformation(segment).transformPoints(segment) + return all(math.isclose(p[1], 0.0) for p in maybeline) + + +def curveCurveIntersections(curve1, curve2): + """Finds intersections between a curve and a curve. + + Args: + curve1: List of coordinates of the first curve segment as 2D tuples. + curve2: List of coordinates of the second curve segment as 2D tuples. + + Returns: + A list of ``Intersection`` objects, each object having ``pt``, ``t1`` + and ``t2`` attributes containing the intersection point, time on first + segment and time on second segment respectively. + + Examples:: + >>> curve1 = [ (10,100), (90,30), (40,140), (220,220) ] + >>> curve2 = [ (5,150), (180,20), (80,250), (210,190) ] + >>> intersections = curveCurveIntersections(curve1, curve2) + >>> len(intersections) + 3 + >>> intersections[0].pt + (81.7831487395506, 109.88904552375288) + """ + if _is_linelike(curve1): + line1 = curve1[0], curve1[-1] + if _is_linelike(curve2): + line2 = curve2[0], curve2[-1] + return lineLineIntersections(*line1, *line2) + else: + hits = curveLineIntersections(curve2, line1) + # curve is passed first to this fn but is the second segment, so + # we need to swap t1/t2 in the result + return [Intersection(pt=x.pt, t1=x.t2, t2=x.t1) for x in hits] + elif _is_linelike(curve2): + line2 = curve2[0], curve2[-1] + return curveLineIntersections(curve1, line2) + + intersection_ts = _curve_curve_intersections_t(curve1, curve2) + return [ + Intersection(pt=segmentPointAtT(curve1, ts[0]), t1=ts[0], t2=ts[1]) + for ts in intersection_ts + ] + + +def segmentSegmentIntersections(seg1, seg2): + """Finds intersections between two segments. + + Args: + seg1: List of coordinates of the first segment as 2D tuples. + seg2: List of coordinates of the second segment as 2D tuples. + + Returns: + A list of ``Intersection`` objects, each object having ``pt``, ``t1`` + and ``t2`` attributes containing the intersection point, time on first + segment and time on second segment respectively. + + Examples:: + >>> curve1 = [ (10,100), (90,30), (40,140), (220,220) ] + >>> curve2 = [ (5,150), (180,20), (80,250), (210,190) ] + >>> intersections = segmentSegmentIntersections(curve1, curve2) + >>> len(intersections) + 3 + >>> intersections[0].pt + (81.7831487395506, 109.88904552375288) + >>> curve3 = [ (100, 240), (30, 60), (210, 230), (160, 30) ] + >>> line = [ (25, 260), (230, 20) ] + >>> intersections = segmentSegmentIntersections(curve3, line) + >>> len(intersections) + 3 + >>> intersections[0].pt + (84.9000930760723, 189.87306176459828) + + """ + # Arrange by degree + swapped = False + if len(seg2) > len(seg1): + seg2, seg1 = seg1, seg2 + swapped = True + if len(seg1) > 2: + if len(seg2) > 2: + intersections = curveCurveIntersections(seg1, seg2) + else: + intersections = curveLineIntersections(seg1, seg2) + elif len(seg1) == 2 and len(seg2) == 2: + intersections = lineLineIntersections(*seg1, *seg2) + else: + raise ValueError("Couldn't work out which intersection function to use") + if not swapped: + return intersections + return [Intersection(pt=i.pt, t1=i.t2, t2=i.t1) for i in intersections] + + +def _segmentrepr(obj): + """ + >>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]]) + '(1, (2, 3), (), ((2, (3, 4), (0.1, 2.2))))' + """ + try: + it = iter(obj) + except TypeError: + return "%g" % obj + else: + return "(%s)" % ", ".join(_segmentrepr(x) for x in it) + + +def printSegments(segments): + """Helper for the doctests, displaying each segment in a list of + segments on a single line as a tuple. + """ + for segment in segments: + print(_segmentrepr(segment)) + + +if __name__ == "__main__": + import sys + import doctest + + sys.exit(doctest.testmod().failed) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/classifyTools.py b/.venv/lib/python3.13/site-packages/fontTools/misc/classifyTools.py new file mode 100644 index 0000000000000000000000000000000000000000..aed7ca68c4e75fb9c120a9bc479093039e823b30 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/classifyTools.py @@ -0,0 +1,170 @@ +""" fontTools.misc.classifyTools.py -- tools for classifying things. +""" + + +class Classifier(object): + """ + Main Classifier object, used to classify things into similar sets. + """ + + def __init__(self, sort=True): + self._things = set() # set of all things known so far + self._sets = [] # list of class sets produced so far + self._mapping = {} # map from things to their class set + self._dirty = False + self._sort = sort + + def add(self, set_of_things): + """ + Add a set to the classifier. Any iterable is accepted. + """ + if not set_of_things: + return + + self._dirty = True + + things, sets, mapping = self._things, self._sets, self._mapping + + s = set(set_of_things) + intersection = s.intersection(things) # existing things + s.difference_update(intersection) # new things + difference = s + del s + + # Add new class for new things + if difference: + things.update(difference) + sets.append(difference) + for thing in difference: + mapping[thing] = difference + del difference + + while intersection: + # Take one item and process the old class it belongs to + old_class = mapping[next(iter(intersection))] + old_class_intersection = old_class.intersection(intersection) + + # Update old class to remove items from new set + old_class.difference_update(old_class_intersection) + + # Remove processed items from todo list + intersection.difference_update(old_class_intersection) + + # Add new class for the intersection with old class + sets.append(old_class_intersection) + for thing in old_class_intersection: + mapping[thing] = old_class_intersection + del old_class_intersection + + def update(self, list_of_sets): + """ + Add a a list of sets to the classifier. Any iterable of iterables is accepted. + """ + for s in list_of_sets: + self.add(s) + + def _process(self): + if not self._dirty: + return + + # Do any deferred processing + sets = self._sets + self._sets = [s for s in sets if s] + + if self._sort: + self._sets = sorted(self._sets, key=lambda s: (-len(s), sorted(s))) + + self._dirty = False + + # Output methods + + def getThings(self): + """Returns the set of all things known so far. + + The return value belongs to the Classifier object and should NOT + be modified while the classifier is still in use. + """ + self._process() + return self._things + + def getMapping(self): + """Returns the mapping from things to their class set. + + The return value belongs to the Classifier object and should NOT + be modified while the classifier is still in use. + """ + self._process() + return self._mapping + + def getClasses(self): + """Returns the list of class sets. + + The return value belongs to the Classifier object and should NOT + be modified while the classifier is still in use. + """ + self._process() + return self._sets + + +def classify(list_of_sets, sort=True): + """ + Takes a iterable of iterables (list of sets from here on; but any + iterable works.), and returns the smallest list of sets such that + each set, is either a subset, or is disjoint from, each of the input + sets. + + In other words, this function classifies all the things present in + any of the input sets, into similar classes, based on which sets + things are a member of. + + If sort=True, return class sets are sorted by decreasing size and + their natural sort order within each class size. Otherwise, class + sets are returned in the order that they were identified, which is + generally not significant. + + >>> classify([]) == ([], {}) + True + >>> classify([[]]) == ([], {}) + True + >>> classify([[], []]) == ([], {}) + True + >>> classify([[1]]) == ([{1}], {1: {1}}) + True + >>> classify([[1,2]]) == ([{1, 2}], {1: {1, 2}, 2: {1, 2}}) + True + >>> classify([[1],[2]]) == ([{1}, {2}], {1: {1}, 2: {2}}) + True + >>> classify([[1,2],[2]]) == ([{1}, {2}], {1: {1}, 2: {2}}) + True + >>> classify([[1,2],[2,4]]) == ([{1}, {2}, {4}], {1: {1}, 2: {2}, 4: {4}}) + True + >>> classify([[1,2],[2,4,5]]) == ( + ... [{4, 5}, {1}, {2}], {1: {1}, 2: {2}, 4: {4, 5}, 5: {4, 5}}) + True + >>> classify([[1,2],[2,4,5]], sort=False) == ( + ... [{1}, {4, 5}, {2}], {1: {1}, 2: {2}, 4: {4, 5}, 5: {4, 5}}) + True + >>> classify([[1,2,9],[2,4,5]], sort=False) == ( + ... [{1, 9}, {4, 5}, {2}], {1: {1, 9}, 2: {2}, 4: {4, 5}, 5: {4, 5}, + ... 9: {1, 9}}) + True + >>> classify([[1,2,9,15],[2,4,5]], sort=False) == ( + ... [{1, 9, 15}, {4, 5}, {2}], {1: {1, 9, 15}, 2: {2}, 4: {4, 5}, + ... 5: {4, 5}, 9: {1, 9, 15}, 15: {1, 9, 15}}) + True + >>> classes, mapping = classify([[1,2,9,15],[2,4,5],[15,5]], sort=False) + >>> set([frozenset(c) for c in classes]) == set( + ... [frozenset(s) for s in ({1, 9}, {4}, {2}, {5}, {15})]) + True + >>> mapping == {1: {1, 9}, 2: {2}, 4: {4}, 5: {5}, 9: {1, 9}, 15: {15}} + True + """ + classifier = Classifier(sort=sort) + classifier.update(list_of_sets) + return classifier.getClasses(), classifier.getMapping() + + +if __name__ == "__main__": + import sys, doctest + + sys.exit(doctest.testmod(optionflags=doctest.ELLIPSIS).failed) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/configTools.py b/.venv/lib/python3.13/site-packages/fontTools/misc/configTools.py new file mode 100644 index 0000000000000000000000000000000000000000..c928840a5154a21024ab6ff6e766ea346d43e741 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/configTools.py @@ -0,0 +1,351 @@ +""" +Code of the config system; not related to fontTools or fonts in particular. + +The options that are specific to fontTools are in :mod:`fontTools.config`. + +To create your own config system, you need to create an instance of +:class:`Options`, and a subclass of :class:`AbstractConfig` with its +``options`` class variable set to your instance of Options. + +""" + +from __future__ import annotations + +import logging +from dataclasses import dataclass +from typing import ( + Any, + Callable, + ClassVar, + Dict, + Iterable, + Mapping, + MutableMapping, + Optional, + Set, + Union, +) + + +log = logging.getLogger(__name__) + +__all__ = [ + "AbstractConfig", + "ConfigAlreadyRegisteredError", + "ConfigError", + "ConfigUnknownOptionError", + "ConfigValueParsingError", + "ConfigValueValidationError", + "Option", + "Options", +] + + +class ConfigError(Exception): + """Base exception for the config module.""" + + +class ConfigAlreadyRegisteredError(ConfigError): + """Raised when a module tries to register a configuration option that + already exists. + + Should not be raised too much really, only when developing new fontTools + modules. + """ + + def __init__(self, name): + super().__init__(f"Config option {name} is already registered.") + + +class ConfigValueParsingError(ConfigError): + """Raised when a configuration value cannot be parsed.""" + + def __init__(self, name, value): + super().__init__( + f"Config option {name}: value cannot be parsed (given {repr(value)})" + ) + + +class ConfigValueValidationError(ConfigError): + """Raised when a configuration value cannot be validated.""" + + def __init__(self, name, value): + super().__init__( + f"Config option {name}: value is invalid (given {repr(value)})" + ) + + +class ConfigUnknownOptionError(ConfigError): + """Raised when a configuration option is unknown.""" + + def __init__(self, option_or_name): + name = ( + f"'{option_or_name.name}' (id={id(option_or_name)})>" + if isinstance(option_or_name, Option) + else f"'{option_or_name}'" + ) + super().__init__(f"Config option {name} is unknown") + + +# eq=False because Options are unique, not fungible objects +@dataclass(frozen=True, eq=False) +class Option: + name: str + """Unique name identifying the option (e.g. package.module:MY_OPTION).""" + help: str + """Help text for this option.""" + default: Any + """Default value for this option.""" + parse: Callable[[str], Any] + """Turn input (e.g. string) into proper type. Only when reading from file.""" + validate: Optional[Callable[[Any], bool]] = None + """Return true if the given value is an acceptable value.""" + + @staticmethod + def parse_optional_bool(v: str) -> Optional[bool]: + s = str(v).lower() + if s in {"0", "no", "false"}: + return False + if s in {"1", "yes", "true"}: + return True + if s in {"auto", "none"}: + return None + raise ValueError("invalid optional bool: {v!r}") + + @staticmethod + def validate_optional_bool(v: Any) -> bool: + return v is None or isinstance(v, bool) + + +class Options(Mapping): + """Registry of available options for a given config system. + + Define new options using the :meth:`register()` method. + + Access existing options using the Mapping interface. + """ + + __options: Dict[str, Option] + + def __init__(self, other: "Options" = None) -> None: + self.__options = {} + if other is not None: + for option in other.values(): + self.register_option(option) + + def register( + self, + name: str, + help: str, + default: Any, + parse: Callable[[str], Any], + validate: Optional[Callable[[Any], bool]] = None, + ) -> Option: + """Create and register a new option.""" + return self.register_option(Option(name, help, default, parse, validate)) + + def register_option(self, option: Option) -> Option: + """Register a new option.""" + name = option.name + if name in self.__options: + raise ConfigAlreadyRegisteredError(name) + self.__options[name] = option + return option + + def is_registered(self, option: Option) -> bool: + """Return True if the same option object is already registered.""" + return self.__options.get(option.name) is option + + def __getitem__(self, key: str) -> Option: + return self.__options.__getitem__(key) + + def __iter__(self) -> Iterator[str]: + return self.__options.__iter__() + + def __len__(self) -> int: + return self.__options.__len__() + + def __repr__(self) -> str: + return ( + f"{self.__class__.__name__}({{\n" + + "".join( + f" {k!r}: Option(default={v.default!r}, ...),\n" + for k, v in self.__options.items() + ) + + "})" + ) + + +_USE_GLOBAL_DEFAULT = object() + + +class AbstractConfig(MutableMapping): + """ + Create a set of config values, optionally pre-filled with values from + the given dictionary or pre-existing config object. + + The class implements the MutableMapping protocol keyed by option name (`str`). + For convenience its methods accept either Option or str as the key parameter. + + .. seealso:: :meth:`set()` + + This config class is abstract because it needs its ``options`` class + var to be set to an instance of :class:`Options` before it can be + instanciated and used. + + .. code:: python + + class MyConfig(AbstractConfig): + options = Options() + + MyConfig.register_option( "test:option_name", "This is an option", 0, int, lambda v: isinstance(v, int)) + + cfg = MyConfig({"test:option_name": 10}) + + """ + + options: ClassVar[Options] + + @classmethod + def register_option( + cls, + name: str, + help: str, + default: Any, + parse: Callable[[str], Any], + validate: Optional[Callable[[Any], bool]] = None, + ) -> Option: + """Register an available option in this config system.""" + return cls.options.register( + name, help=help, default=default, parse=parse, validate=validate + ) + + _values: Dict[str, Any] + + def __init__( + self, + values: Union[ + AbstractConfig, Dict[Union[Option, str], Any], Mapping[str, Any] + ] = {}, + parse_values: bool = False, + skip_unknown: bool = False, + ): + self._values = {} + values_dict = values._values if isinstance(values, AbstractConfig) else values + for name, value in values_dict.items(): + self.set(name, value, parse_values, skip_unknown) + + def _resolve_option(self, option_or_name: Union[Option, str]) -> Option: + if isinstance(option_or_name, Option): + option = option_or_name + if not self.options.is_registered(option): + raise ConfigUnknownOptionError(option) + return option + elif isinstance(option_or_name, str): + name = option_or_name + try: + return self.options[name] + except KeyError: + raise ConfigUnknownOptionError(name) + else: + raise TypeError( + "expected Option or str, found " + f"{type(option_or_name).__name__}: {option_or_name!r}" + ) + + def set( + self, + option_or_name: Union[Option, str], + value: Any, + parse_values: bool = False, + skip_unknown: bool = False, + ): + """Set the value of an option. + + Args: + * `option_or_name`: an `Option` object or its name (`str`). + * `value`: the value to be assigned to given option. + * `parse_values`: parse the configuration value from a string into + its proper type, as per its `Option` object. The default + behavior is to raise `ConfigValueValidationError` when the value + is not of the right type. Useful when reading options from a + file type that doesn't support as many types as Python. + * `skip_unknown`: skip unknown configuration options. The default + behaviour is to raise `ConfigUnknownOptionError`. Useful when + reading options from a configuration file that has extra entries + (e.g. for a later version of fontTools) + """ + try: + option = self._resolve_option(option_or_name) + except ConfigUnknownOptionError as e: + if skip_unknown: + log.debug(str(e)) + return + raise + + # Can be useful if the values come from a source that doesn't have + # strict typing (.ini file? Terminal input?) + if parse_values: + try: + value = option.parse(value) + except Exception as e: + raise ConfigValueParsingError(option.name, value) from e + + if option.validate is not None and not option.validate(value): + raise ConfigValueValidationError(option.name, value) + + self._values[option.name] = value + + def get( + self, option_or_name: Union[Option, str], default: Any = _USE_GLOBAL_DEFAULT + ) -> Any: + """ + Get the value of an option. The value which is returned is the first + provided among: + + 1. a user-provided value in the options's ``self._values`` dict + 2. a caller-provided default value to this method call + 3. the global default for the option provided in ``fontTools.config`` + + This is to provide the ability to migrate progressively from config + options passed as arguments to fontTools APIs to config options read + from the current TTFont, e.g. + + .. code:: python + + def fontToolsAPI(font, some_option): + value = font.cfg.get("someLib.module:SOME_OPTION", some_option) + # use value + + That way, the function will work the same for users of the API that + still pass the option to the function call, but will favour the new + config mechanism if the given font specifies a value for that option. + """ + option = self._resolve_option(option_or_name) + if option.name in self._values: + return self._values[option.name] + if default is not _USE_GLOBAL_DEFAULT: + return default + return option.default + + def copy(self): + return self.__class__(self._values) + + def __getitem__(self, option_or_name: Union[Option, str]) -> Any: + return self.get(option_or_name) + + def __setitem__(self, option_or_name: Union[Option, str], value: Any) -> None: + return self.set(option_or_name, value) + + def __delitem__(self, option_or_name: Union[Option, str]) -> None: + option = self._resolve_option(option_or_name) + del self._values[option.name] + + def __iter__(self) -> Iterable[str]: + return self._values.__iter__() + + def __len__(self) -> int: + return len(self._values) + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({repr(self._values)})" diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/cython.py b/.venv/lib/python3.13/site-packages/fontTools/misc/cython.py new file mode 100644 index 0000000000000000000000000000000000000000..2a42d94a3591e0e8e47f184b303e4aec0a6337ef --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/cython.py @@ -0,0 +1,27 @@ +""" Exports a no-op 'cython' namespace similar to +https://github.com/cython/cython/blob/master/Cython/Shadow.py + +This allows to optionally compile @cython decorated functions +(when cython is available at built time), or run the same code +as pure-python, without runtime dependency on cython module. + +We only define the symbols that we use. E.g. see fontTools.cu2qu +""" + +from types import SimpleNamespace + + +def _empty_decorator(x): + return x + + +compiled = False + +for name in ("double", "complex", "int"): + globals()[name] = None + +for name in ("cfunc", "inline"): + globals()[name] = _empty_decorator + +locals = lambda **_: _empty_decorator +returns = lambda _: _empty_decorator diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/dictTools.py b/.venv/lib/python3.13/site-packages/fontTools/misc/dictTools.py new file mode 100644 index 0000000000000000000000000000000000000000..cd3d394c25bc0f5ab49b502fdb614d01a9fef281 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/dictTools.py @@ -0,0 +1,83 @@ +"""Misc dict tools.""" + +__all__ = ["hashdict"] + + +# https://stackoverflow.com/questions/1151658/python-hashable-dicts +class hashdict(dict): + """ + hashable dict implementation, suitable for use as a key into + other dicts. + + >>> h1 = hashdict({"apples": 1, "bananas":2}) + >>> h2 = hashdict({"bananas": 3, "mangoes": 5}) + >>> h1+h2 + hashdict(apples=1, bananas=3, mangoes=5) + >>> d1 = {} + >>> d1[h1] = "salad" + >>> d1[h1] + 'salad' + >>> d1[h2] + Traceback (most recent call last): + ... + KeyError: hashdict(bananas=3, mangoes=5) + + based on answers from + http://stackoverflow.com/questions/1151658/python-hashable-dicts + + """ + + def __key(self): + return tuple(sorted(self.items())) + + def __repr__(self): + return "{0}({1})".format( + self.__class__.__name__, + ", ".join("{0}={1}".format(str(i[0]), repr(i[1])) for i in self.__key()), + ) + + def __hash__(self): + return hash(self.__key()) + + def __setitem__(self, key, value): + raise TypeError( + "{0} does not support item assignment".format(self.__class__.__name__) + ) + + def __delitem__(self, key): + raise TypeError( + "{0} does not support item assignment".format(self.__class__.__name__) + ) + + def clear(self): + raise TypeError( + "{0} does not support item assignment".format(self.__class__.__name__) + ) + + def pop(self, *args, **kwargs): + raise TypeError( + "{0} does not support item assignment".format(self.__class__.__name__) + ) + + def popitem(self, *args, **kwargs): + raise TypeError( + "{0} does not support item assignment".format(self.__class__.__name__) + ) + + def setdefault(self, *args, **kwargs): + raise TypeError( + "{0} does not support item assignment".format(self.__class__.__name__) + ) + + def update(self, *args, **kwargs): + raise TypeError( + "{0} does not support item assignment".format(self.__class__.__name__) + ) + + # update is not ok because it mutates the object + # __add__ is ok because it creates a new object + # while the new object is under construction, it's ok to mutate it + def __add__(self, right): + result = hashdict(self) + dict.update(result, right) + return result diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/eexec.py b/.venv/lib/python3.13/site-packages/fontTools/misc/eexec.py new file mode 100644 index 0000000000000000000000000000000000000000..cafa312cdaa4696b0624438e06418ade95438441 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/eexec.py @@ -0,0 +1,119 @@ +""" +PostScript Type 1 fonts make use of two types of encryption: charstring +encryption and ``eexec`` encryption. Charstring encryption is used for +the charstrings themselves, while ``eexec`` is used to encrypt larger +sections of the font program, such as the ``Private`` and ``CharStrings`` +dictionaries. Despite the different names, the algorithm is the same, +although ``eexec`` encryption uses a fixed initial key R=55665. + +The algorithm uses cipher feedback, meaning that the ciphertext is used +to modify the key. Because of this, the routines in this module return +the new key at the end of the operation. + +""" + +from fontTools.misc.textTools import bytechr, bytesjoin, byteord + + +def _decryptChar(cipher, R): + cipher = byteord(cipher) + plain = ((cipher ^ (R >> 8))) & 0xFF + R = ((cipher + R) * 52845 + 22719) & 0xFFFF + return bytechr(plain), R + + +def _encryptChar(plain, R): + plain = byteord(plain) + cipher = ((plain ^ (R >> 8))) & 0xFF + R = ((cipher + R) * 52845 + 22719) & 0xFFFF + return bytechr(cipher), R + + +def decrypt(cipherstring, R): + r""" + Decrypts a string using the Type 1 encryption algorithm. + + Args: + cipherstring: String of ciphertext. + R: Initial key. + + Returns: + decryptedStr: Plaintext string. + R: Output key for subsequent decryptions. + + Examples:: + + >>> testStr = b"\0\0asdadads asds\265" + >>> decryptedStr, R = decrypt(testStr, 12321) + >>> decryptedStr == b'0d\nh\x15\xe8\xc4\xb2\x15\x1d\x108\x1a<6\xa1' + True + >>> R == 36142 + True + """ + plainList = [] + for cipher in cipherstring: + plain, R = _decryptChar(cipher, R) + plainList.append(plain) + plainstring = bytesjoin(plainList) + return plainstring, int(R) + + +def encrypt(plainstring, R): + r""" + Encrypts a string using the Type 1 encryption algorithm. + + Note that the algorithm as described in the Type 1 specification requires the + plaintext to be prefixed with a number of random bytes. (For ``eexec`` the + number of random bytes is set to 4.) This routine does *not* add the random + prefix to its input. + + Args: + plainstring: String of plaintext. + R: Initial key. + + Returns: + cipherstring: Ciphertext string. + R: Output key for subsequent encryptions. + + Examples:: + + >>> testStr = b"\0\0asdadads asds\265" + >>> decryptedStr, R = decrypt(testStr, 12321) + >>> decryptedStr == b'0d\nh\x15\xe8\xc4\xb2\x15\x1d\x108\x1a<6\xa1' + True + >>> R == 36142 + True + + >>> testStr = b'0d\nh\x15\xe8\xc4\xb2\x15\x1d\x108\x1a<6\xa1' + >>> encryptedStr, R = encrypt(testStr, 12321) + >>> encryptedStr == b"\0\0asdadads asds\265" + True + >>> R == 36142 + True + """ + cipherList = [] + for plain in plainstring: + cipher, R = _encryptChar(plain, R) + cipherList.append(cipher) + cipherstring = bytesjoin(cipherList) + return cipherstring, int(R) + + +def hexString(s): + import binascii + + return binascii.hexlify(s) + + +def deHexString(h): + import binascii + + h = bytesjoin(h.split()) + return binascii.unhexlify(h) + + +if __name__ == "__main__": + import sys + import doctest + + sys.exit(doctest.testmod().failed) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/encodingTools.py b/.venv/lib/python3.13/site-packages/fontTools/misc/encodingTools.py new file mode 100644 index 0000000000000000000000000000000000000000..3b2651d3b1ce222060fa67abaeac4da8030618fa --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/encodingTools.py @@ -0,0 +1,72 @@ +"""fontTools.misc.encodingTools.py -- tools for working with OpenType encodings. +""" + +import fontTools.encodings.codecs + +# Map keyed by platformID, then platEncID, then possibly langID +_encodingMap = { + 0: { # Unicode + 0: "utf_16_be", + 1: "utf_16_be", + 2: "utf_16_be", + 3: "utf_16_be", + 4: "utf_16_be", + 5: "utf_16_be", + 6: "utf_16_be", + }, + 1: { # Macintosh + # See + # https://github.com/fonttools/fonttools/issues/236 + 0: { # Macintosh, platEncID==0, keyed by langID + 15: "mac_iceland", + 17: "mac_turkish", + 18: "mac_croatian", + 24: "mac_latin2", + 25: "mac_latin2", + 26: "mac_latin2", + 27: "mac_latin2", + 28: "mac_latin2", + 36: "mac_latin2", + 37: "mac_romanian", + 38: "mac_latin2", + 39: "mac_latin2", + 40: "mac_latin2", + Ellipsis: "mac_roman", # Other + }, + 1: "x_mac_japanese_ttx", + 2: "x_mac_trad_chinese_ttx", + 3: "x_mac_korean_ttx", + 6: "mac_greek", + 7: "mac_cyrillic", + 25: "x_mac_simp_chinese_ttx", + 29: "mac_latin2", + 35: "mac_turkish", + 37: "mac_iceland", + }, + 2: { # ISO + 0: "ascii", + 1: "utf_16_be", + 2: "latin1", + }, + 3: { # Microsoft + 0: "utf_16_be", + 1: "utf_16_be", + 2: "shift_jis", + 3: "gb2312", + 4: "big5", + 5: "euc_kr", + 6: "johab", + 10: "utf_16_be", + }, +} + + +def getEncoding(platformID, platEncID, langID, default=None): + """Returns the Python encoding name for OpenType platformID/encodingID/langID + triplet. If encoding for these values is not known, by default None is + returned. That can be overriden by passing a value to the default argument. + """ + encoding = _encodingMap.get(platformID, {}).get(platEncID, default) + if isinstance(encoding, dict): + encoding = encoding.get(langID, encoding[Ellipsis]) + return encoding diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/enumTools.py b/.venv/lib/python3.13/site-packages/fontTools/misc/enumTools.py new file mode 100644 index 0000000000000000000000000000000000000000..e947342f200c7c935724256eaee38c44c492ab78 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/enumTools.py @@ -0,0 +1,23 @@ +"""Enum-related utilities, including backports for older Python versions.""" + +from __future__ import annotations + +from enum import Enum + + +__all__ = ["StrEnum"] + +# StrEnum is only available in Python 3.11+ +try: + from enum import StrEnum +except ImportError: + + class StrEnum(str, Enum): + """ + Minimal backport of Python 3.11's StrEnum for older versions. + + An Enum where all members are also strings. + """ + + def __str__(self) -> str: + return self.value diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/etree.py b/.venv/lib/python3.13/site-packages/fontTools/misc/etree.py new file mode 100644 index 0000000000000000000000000000000000000000..743546061c45724d09c0ca2990383df821026ea7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/etree.py @@ -0,0 +1,456 @@ +"""Shim module exporting the same ElementTree API for lxml and +xml.etree backends. + +When lxml is installed, it is automatically preferred over the built-in +xml.etree module. +On Python 2.7, the cElementTree module is preferred over the pure-python +ElementTree module. + +Besides exporting a unified interface, this also defines extra functions +or subclasses built-in ElementTree classes to add features that are +only availble in lxml, like OrderedDict for attributes, pretty_print and +iterwalk. +""" + +from fontTools.misc.textTools import tostr + + +XML_DECLARATION = """""" + +__all__ = [ + # public symbols + "Comment", + "dump", + "Element", + "ElementTree", + "fromstring", + "fromstringlist", + "iselement", + "iterparse", + "parse", + "ParseError", + "PI", + "ProcessingInstruction", + "QName", + "SubElement", + "tostring", + "tostringlist", + "TreeBuilder", + "XML", + "XMLParser", + "register_namespace", +] + +try: + from lxml.etree import * + + _have_lxml = True +except ImportError: + try: + from xml.etree.cElementTree import * + + # the cElementTree version of XML function doesn't support + # the optional 'parser' keyword argument + from xml.etree.ElementTree import XML + except ImportError: # pragma: no cover + from xml.etree.ElementTree import * + _have_lxml = False + + _Attrib = dict + + if isinstance(Element, type): + _Element = Element + else: + # in py27, cElementTree.Element cannot be subclassed, so + # we need to import the pure-python class + from xml.etree.ElementTree import Element as _Element + + class Element(_Element): + """Element subclass that keeps the order of attributes.""" + + def __init__(self, tag, attrib=_Attrib(), **extra): + super(Element, self).__init__(tag) + self.attrib = _Attrib() + if attrib: + self.attrib.update(attrib) + if extra: + self.attrib.update(extra) + + def SubElement(parent, tag, attrib=_Attrib(), **extra): + """Must override SubElement as well otherwise _elementtree.SubElement + fails if 'parent' is a subclass of Element object. + """ + element = parent.__class__(tag, attrib, **extra) + parent.append(element) + return element + + def _iterwalk(element, events, tag): + include = tag is None or element.tag == tag + if include and "start" in events: + yield ("start", element) + for e in element: + for item in _iterwalk(e, events, tag): + yield item + if include: + yield ("end", element) + + def iterwalk(element_or_tree, events=("end",), tag=None): + """A tree walker that generates events from an existing tree as + if it was parsing XML data with iterparse(). + Drop-in replacement for lxml.etree.iterwalk. + """ + if iselement(element_or_tree): + element = element_or_tree + else: + element = element_or_tree.getroot() + if tag == "*": + tag = None + for item in _iterwalk(element, events, tag): + yield item + + _ElementTree = ElementTree + + class ElementTree(_ElementTree): + """ElementTree subclass that adds 'pretty_print' and 'doctype' + arguments to the 'write' method. + Currently these are only supported for the default XML serialization + 'method', and not also for "html" or "text", for these are delegated + to the base class. + """ + + def write( + self, + file_or_filename, + encoding=None, + xml_declaration=False, + method=None, + doctype=None, + pretty_print=False, + ): + if method and method != "xml": + # delegate to super-class + super(ElementTree, self).write( + file_or_filename, + encoding=encoding, + xml_declaration=xml_declaration, + method=method, + ) + return + + if encoding is not None and encoding.lower() == "unicode": + if xml_declaration: + raise ValueError( + "Serialisation to unicode must not request an XML declaration" + ) + write_declaration = False + encoding = "unicode" + elif xml_declaration is None: + # by default, write an XML declaration only for non-standard encodings + write_declaration = encoding is not None and encoding.upper() not in ( + "ASCII", + "UTF-8", + "UTF8", + "US-ASCII", + ) + else: + write_declaration = xml_declaration + + if encoding is None: + encoding = "ASCII" + + if pretty_print: + # NOTE this will modify the tree in-place + _indent(self._root) + + with _get_writer(file_or_filename, encoding) as write: + if write_declaration: + write(XML_DECLARATION % encoding.upper()) + if pretty_print: + write("\n") + if doctype: + write(_tounicode(doctype)) + if pretty_print: + write("\n") + + qnames, namespaces = _namespaces(self._root) + _serialize_xml(write, self._root, qnames, namespaces) + + import io + + def tostring( + element, + encoding=None, + xml_declaration=None, + method=None, + doctype=None, + pretty_print=False, + ): + """Custom 'tostring' function that uses our ElementTree subclass, with + pretty_print support. + """ + stream = io.StringIO() if encoding == "unicode" else io.BytesIO() + ElementTree(element).write( + stream, + encoding=encoding, + xml_declaration=xml_declaration, + method=method, + doctype=doctype, + pretty_print=pretty_print, + ) + return stream.getvalue() + + # serialization support + + import re + + # Valid XML strings can include any Unicode character, excluding control + # characters, the surrogate blocks, FFFE, and FFFF: + # Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] + # Here we reversed the pattern to match only the invalid characters. + _invalid_xml_string = re.compile( + "[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uD800-\uDFFF\uFFFE-\uFFFF]" + ) + + def _tounicode(s): + """Test if a string is valid user input and decode it to unicode string + using ASCII encoding if it's a bytes string. + Reject all bytes/unicode input that contains non-XML characters. + Reject all bytes input that contains non-ASCII characters. + """ + try: + s = tostr(s, encoding="ascii", errors="strict") + except UnicodeDecodeError: + raise ValueError( + "Bytes strings can only contain ASCII characters. " + "Use unicode strings for non-ASCII characters." + ) + except AttributeError: + _raise_serialization_error(s) + if s and _invalid_xml_string.search(s): + raise ValueError( + "All strings must be XML compatible: Unicode or ASCII, " + "no NULL bytes or control characters" + ) + return s + + import contextlib + + @contextlib.contextmanager + def _get_writer(file_or_filename, encoding): + # returns text write method and release all resources after using + try: + write = file_or_filename.write + except AttributeError: + # file_or_filename is a file name + f = open( + file_or_filename, + "w", + encoding="utf-8" if encoding == "unicode" else encoding, + errors="xmlcharrefreplace", + ) + with f: + yield f.write + else: + # file_or_filename is a file-like object + # encoding determines if it is a text or binary writer + if encoding == "unicode": + # use a text writer as is + yield write + else: + # wrap a binary writer with TextIOWrapper + detach_buffer = False + if isinstance(file_or_filename, io.BufferedIOBase): + buf = file_or_filename + elif isinstance(file_or_filename, io.RawIOBase): + buf = io.BufferedWriter(file_or_filename) + detach_buffer = True + else: + # This is to handle passed objects that aren't in the + # IOBase hierarchy, but just have a write method + buf = io.BufferedIOBase() + buf.writable = lambda: True + buf.write = write + try: + # TextIOWrapper uses this methods to determine + # if BOM (for UTF-16, etc) should be added + buf.seekable = file_or_filename.seekable + buf.tell = file_or_filename.tell + except AttributeError: + pass + wrapper = io.TextIOWrapper( + buf, + encoding=encoding, + errors="xmlcharrefreplace", + newline="\n", + ) + try: + yield wrapper.write + finally: + # Keep the original file open when the TextIOWrapper and + # the BufferedWriter are destroyed + wrapper.detach() + if detach_buffer: + buf.detach() + + from xml.etree.ElementTree import _namespace_map + + def _namespaces(elem): + # identify namespaces used in this tree + + # maps qnames to *encoded* prefix:local names + qnames = {None: None} + + # maps uri:s to prefixes + namespaces = {} + + def add_qname(qname): + # calculate serialized qname representation + try: + qname = _tounicode(qname) + if qname[:1] == "{": + uri, tag = qname[1:].rsplit("}", 1) + prefix = namespaces.get(uri) + if prefix is None: + prefix = _namespace_map.get(uri) + if prefix is None: + prefix = "ns%d" % len(namespaces) + else: + prefix = _tounicode(prefix) + if prefix != "xml": + namespaces[uri] = prefix + if prefix: + qnames[qname] = "%s:%s" % (prefix, tag) + else: + qnames[qname] = tag # default element + else: + qnames[qname] = qname + except TypeError: + _raise_serialization_error(qname) + + # populate qname and namespaces table + for elem in elem.iter(): + tag = elem.tag + if isinstance(tag, QName): + if tag.text not in qnames: + add_qname(tag.text) + elif isinstance(tag, str): + if tag not in qnames: + add_qname(tag) + elif tag is not None and tag is not Comment and tag is not PI: + _raise_serialization_error(tag) + for key, value in elem.items(): + if isinstance(key, QName): + key = key.text + if key not in qnames: + add_qname(key) + if isinstance(value, QName) and value.text not in qnames: + add_qname(value.text) + text = elem.text + if isinstance(text, QName) and text.text not in qnames: + add_qname(text.text) + return qnames, namespaces + + def _serialize_xml(write, elem, qnames, namespaces, **kwargs): + tag = elem.tag + text = elem.text + if tag is Comment: + write("" % _tounicode(text)) + elif tag is ProcessingInstruction: + write("" % _tounicode(text)) + else: + tag = qnames[_tounicode(tag) if tag is not None else None] + if tag is None: + if text: + write(_escape_cdata(text)) + for e in elem: + _serialize_xml(write, e, qnames, None) + else: + write("<" + tag) + if namespaces: + for uri, prefix in sorted( + namespaces.items(), key=lambda x: x[1] + ): # sort on prefix + if prefix: + prefix = ":" + prefix + write(' xmlns%s="%s"' % (prefix, _escape_attrib(uri))) + attrs = elem.attrib + if attrs: + # try to keep existing attrib order + if len(attrs) <= 1 or type(attrs) is _Attrib: + items = attrs.items() + else: + # if plain dict, use lexical order + items = sorted(attrs.items()) + for k, v in items: + if isinstance(k, QName): + k = _tounicode(k.text) + else: + k = _tounicode(k) + if isinstance(v, QName): + v = qnames[_tounicode(v.text)] + else: + v = _escape_attrib(v) + write(' %s="%s"' % (qnames[k], v)) + if text is not None or len(elem): + write(">") + if text: + write(_escape_cdata(text)) + for e in elem: + _serialize_xml(write, e, qnames, None) + write("") + else: + write("/>") + if elem.tail: + write(_escape_cdata(elem.tail)) + + def _raise_serialization_error(text): + raise TypeError("cannot serialize %r (type %s)" % (text, type(text).__name__)) + + def _escape_cdata(text): + # escape character data + try: + text = _tounicode(text) + # it's worth avoiding do-nothing calls for short strings + if "&" in text: + text = text.replace("&", "&") + if "<" in text: + text = text.replace("<", "<") + if ">" in text: + text = text.replace(">", ">") + return text + except (TypeError, AttributeError): + _raise_serialization_error(text) + + def _escape_attrib(text): + # escape attribute value + try: + text = _tounicode(text) + if "&" in text: + text = text.replace("&", "&") + if "<" in text: + text = text.replace("<", "<") + if ">" in text: + text = text.replace(">", ">") + if '"' in text: + text = text.replace('"', """) + if "\n" in text: + text = text.replace("\n", " ") + return text + except (TypeError, AttributeError): + _raise_serialization_error(text) + + def _indent(elem, level=0): + # From http://effbot.org/zone/element-lib.htm#prettyprint + i = "\n" + level * " " + if len(elem): + if not elem.text or not elem.text.strip(): + elem.text = i + " " + if not elem.tail or not elem.tail.strip(): + elem.tail = i + for elem in elem: + _indent(elem, level + 1) + if not elem.tail or not elem.tail.strip(): + elem.tail = i + else: + if level and (not elem.tail or not elem.tail.strip()): + elem.tail = i diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/filenames.py b/.venv/lib/python3.13/site-packages/fontTools/misc/filenames.py new file mode 100644 index 0000000000000000000000000000000000000000..ddedc5210fb3f81e7b26a8950b6155173ad0069b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/filenames.py @@ -0,0 +1,245 @@ +""" +This module implements the algorithm for converting between a "user name" - +something that a user can choose arbitrarily inside a font editor - and a file +name suitable for use in a wide range of operating systems and filesystems. + +The `UFO 3 specification `_ +provides an example of an algorithm for such conversion, which avoids illegal +characters, reserved file names, ambiguity between upper- and lower-case +characters, and clashes with existing files. + +This code was originally copied from +`ufoLib `_ +by Tal Leming and is copyright (c) 2005-2016, The RoboFab Developers: + +- Erik van Blokland +- Tal Leming +- Just van Rossum +""" + +illegalCharacters = r"\" * + / : < > ? [ \ ] | \0".split(" ") +illegalCharacters += [chr(i) for i in range(1, 32)] +illegalCharacters += [chr(0x7F)] +reservedFileNames = "CON PRN AUX CLOCK$ NUL A:-Z: COM1".lower().split(" ") +reservedFileNames += "LPT1 LPT2 LPT3 COM2 COM3 COM4".lower().split(" ") +maxFileNameLength = 255 + + +class NameTranslationError(Exception): + pass + + +def userNameToFileName(userName, existing=[], prefix="", suffix=""): + """Converts from a user name to a file name. + + Takes care to avoid illegal characters, reserved file names, ambiguity between + upper- and lower-case characters, and clashes with existing files. + + Args: + userName (str): The input file name. + existing: A case-insensitive list of all existing file names. + prefix: Prefix to be prepended to the file name. + suffix: Suffix to be appended to the file name. + + Returns: + A suitable filename. + + Raises: + NameTranslationError: If no suitable name could be generated. + + Examples:: + + >>> userNameToFileName("a") == "a" + True + >>> userNameToFileName("A") == "A_" + True + >>> userNameToFileName("AE") == "A_E_" + True + >>> userNameToFileName("Ae") == "A_e" + True + >>> userNameToFileName("ae") == "ae" + True + >>> userNameToFileName("aE") == "aE_" + True + >>> userNameToFileName("a.alt") == "a.alt" + True + >>> userNameToFileName("A.alt") == "A_.alt" + True + >>> userNameToFileName("A.Alt") == "A_.A_lt" + True + >>> userNameToFileName("A.aLt") == "A_.aL_t" + True + >>> userNameToFileName(u"A.alT") == "A_.alT_" + True + >>> userNameToFileName("T_H") == "T__H_" + True + >>> userNameToFileName("T_h") == "T__h" + True + >>> userNameToFileName("t_h") == "t_h" + True + >>> userNameToFileName("F_F_I") == "F__F__I_" + True + >>> userNameToFileName("f_f_i") == "f_f_i" + True + >>> userNameToFileName("Aacute_V.swash") == "A_acute_V_.swash" + True + >>> userNameToFileName(".notdef") == "_notdef" + True + >>> userNameToFileName("con") == "_con" + True + >>> userNameToFileName("CON") == "C_O_N_" + True + >>> userNameToFileName("con.alt") == "_con.alt" + True + >>> userNameToFileName("alt.con") == "alt._con" + True + """ + # the incoming name must be a str + if not isinstance(userName, str): + raise ValueError("The value for userName must be a string.") + # establish the prefix and suffix lengths + prefixLength = len(prefix) + suffixLength = len(suffix) + # replace an initial period with an _ + # if no prefix is to be added + if not prefix and userName[0] == ".": + userName = "_" + userName[1:] + # filter the user name + filteredUserName = [] + for character in userName: + # replace illegal characters with _ + if character in illegalCharacters: + character = "_" + # add _ to all non-lower characters + elif character != character.lower(): + character += "_" + filteredUserName.append(character) + userName = "".join(filteredUserName) + # clip to 255 + sliceLength = maxFileNameLength - prefixLength - suffixLength + userName = userName[:sliceLength] + # test for illegal files names + parts = [] + for part in userName.split("."): + if part.lower() in reservedFileNames: + part = "_" + part + parts.append(part) + userName = ".".join(parts) + # test for clash + fullName = prefix + userName + suffix + if fullName.lower() in existing: + fullName = handleClash1(userName, existing, prefix, suffix) + # finished + return fullName + + +def handleClash1(userName, existing=[], prefix="", suffix=""): + """ + existing should be a case-insensitive list + of all existing file names. + + >>> prefix = ("0" * 5) + "." + >>> suffix = "." + ("0" * 10) + >>> existing = ["a" * 5] + + >>> e = list(existing) + >>> handleClash1(userName="A" * 5, existing=e, + ... prefix=prefix, suffix=suffix) == ( + ... '00000.AAAAA000000000000001.0000000000') + True + + >>> e = list(existing) + >>> e.append(prefix + "aaaaa" + "1".zfill(15) + suffix) + >>> handleClash1(userName="A" * 5, existing=e, + ... prefix=prefix, suffix=suffix) == ( + ... '00000.AAAAA000000000000002.0000000000') + True + + >>> e = list(existing) + >>> e.append(prefix + "AAAAA" + "2".zfill(15) + suffix) + >>> handleClash1(userName="A" * 5, existing=e, + ... prefix=prefix, suffix=suffix) == ( + ... '00000.AAAAA000000000000001.0000000000') + True + """ + # if the prefix length + user name length + suffix length + 15 is at + # or past the maximum length, silce 15 characters off of the user name + prefixLength = len(prefix) + suffixLength = len(suffix) + if prefixLength + len(userName) + suffixLength + 15 > maxFileNameLength: + l = prefixLength + len(userName) + suffixLength + 15 + sliceLength = maxFileNameLength - l + userName = userName[:sliceLength] + finalName = None + # try to add numbers to create a unique name + counter = 1 + while finalName is None: + name = userName + str(counter).zfill(15) + fullName = prefix + name + suffix + if fullName.lower() not in existing: + finalName = fullName + break + else: + counter += 1 + if counter >= 999999999999999: + break + # if there is a clash, go to the next fallback + if finalName is None: + finalName = handleClash2(existing, prefix, suffix) + # finished + return finalName + + +def handleClash2(existing=[], prefix="", suffix=""): + """ + existing should be a case-insensitive list + of all existing file names. + + >>> prefix = ("0" * 5) + "." + >>> suffix = "." + ("0" * 10) + >>> existing = [prefix + str(i) + suffix for i in range(100)] + + >>> e = list(existing) + >>> handleClash2(existing=e, prefix=prefix, suffix=suffix) == ( + ... '00000.100.0000000000') + True + + >>> e = list(existing) + >>> e.remove(prefix + "1" + suffix) + >>> handleClash2(existing=e, prefix=prefix, suffix=suffix) == ( + ... '00000.1.0000000000') + True + + >>> e = list(existing) + >>> e.remove(prefix + "2" + suffix) + >>> handleClash2(existing=e, prefix=prefix, suffix=suffix) == ( + ... '00000.2.0000000000') + True + """ + # calculate the longest possible string + maxLength = maxFileNameLength - len(prefix) - len(suffix) + maxValue = int("9" * maxLength) + # try to find a number + finalName = None + counter = 1 + while finalName is None: + fullName = prefix + str(counter) + suffix + if fullName.lower() not in existing: + finalName = fullName + break + else: + counter += 1 + if counter >= maxValue: + break + # raise an error if nothing has been found + if finalName is None: + raise NameTranslationError("No unique name could be found.") + # finished + return finalName + + +if __name__ == "__main__": + import doctest + import sys + + sys.exit(doctest.testmod().failed) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/__init__.py b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9f9ae249b32db77a678e72deb5bde31cd5c50d91 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/__init__.py @@ -0,0 +1,68 @@ +"""Minimal, stdlib-only replacement for [`pyfilesystem2`][1] API for use by `fontTools.ufoLib`. + +This package is a partial reimplementation of the `fs` package by Will McGugan, used under the +MIT license. See LICENSE.external for details. + +Note this only exports a **subset** of the `pyfilesystem2` API, in particular the modules, +classes and functions that are currently used directly by `fontTools.ufoLib`. + +It opportunistically tries to import the relevant modules from the upstream `fs` package +when this is available. Otherwise it falls back to the replacement modules within this package. + +As of version 4.59.0, the `fonttools[ufo]` extra no longer requires the `fs` package, thus +this `fontTools.misc.filesystem` package is used by default. + +Client code can either replace `import fs` with `from fontTools.misc import filesystem as fs` +if that happens to work (no guarantee), or they can continue to use `fs` but they will have +to specify it as an explicit dependency of their project. + +[1]: https://github.com/PyFilesystem/pyfilesystem2 +""" + +from __future__ import annotations + +try: + __import__("fs") +except ImportError: + from . import _base as base + from . import _copy as copy + from . import _errors as errors + from . import _info as info + from . import _osfs as osfs + from . import _path as path + from . import _subfs as subfs + from . import _tempfs as tempfs + from . import _tools as tools + from . import _walk as walk + from . import _zipfs as zipfs + + _haveFS = False +else: + import fs.base as base + import fs.copy as copy + import fs.errors as errors + import fs.info as info + import fs.osfs as osfs + import fs.path as path + import fs.subfs as subfs + import fs.tempfs as tempfs + import fs.tools as tools + import fs.walk as walk + import fs.zipfs as zipfs + + _haveFS = True + + +__all__ = [ + "base", + "copy", + "errors", + "info", + "osfs", + "path", + "subfs", + "tempfs", + "tools", + "walk", + "zipfs", +] diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_base.py b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_base.py new file mode 100644 index 0000000000000000000000000000000000000000..14603d5b2656dcc4428db64c026206888a73e3b8 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_base.py @@ -0,0 +1,134 @@ +from __future__ import annotations + +import typing +from abc import ABC, abstractmethod + +from ._copy import copy_dir, copy_file +from ._errors import ( + DestinationExists, + DirectoryExpected, + FileExpected, + FilesystemClosed, + NoSysPath, + ResourceNotFound, +) +from ._path import dirname +from ._walk import BoundWalker + +if typing.TYPE_CHECKING: + from typing import IO, Any, Collection, Iterator, Self, Type + + from ._info import Info + from ._subfs import SubFS + + +class FS(ABC): + """Abstract base class for custom filesystems.""" + + _closed: bool = False + + @abstractmethod + def open(self, path: str, mode: str = "rb", **kwargs) -> IO[Any]: ... + + @abstractmethod + def exists(self, path: str) -> bool: ... + + @abstractmethod + def isdir(self, path: str) -> bool: ... + + @abstractmethod + def isfile(self, path: str) -> bool: ... + + @abstractmethod + def listdir(self, path: str) -> list[str]: ... + + @abstractmethod + def makedir(self, path: str, recreate: bool = False) -> SubFS: ... + + @abstractmethod + def makedirs(self, path: str, recreate: bool = False) -> SubFS: ... + + @abstractmethod + def getinfo(self, path: str, namespaces: Collection[str] | None = None) -> Info: ... + + @abstractmethod + def remove(self, path: str) -> None: ... + + @abstractmethod + def removedir(self, path: str) -> None: ... + + @abstractmethod + def removetree(self, path: str) -> None: ... + + @abstractmethod + def movedir(self, src: str, dst: str, create: bool = False) -> None: ... + + def getsyspath(self, path: str) -> str: + raise NoSysPath(f"the filesystem {self!r} has no system path") + + def close(self): + self._closed = True + + def isclosed(self) -> bool: + return self._closed + + def __enter__(self) -> Self: + return self + + def __exit__(self, exc_type, exc, tb): + self.close() + return False # never swallow exceptions + + def check(self): + if self._closed: + raise FilesystemClosed(f"the filesystem {self!r} is closed") + + def opendir(self, path: str, *, factory: Type[SubFS] | None = None) -> SubFS: + """Return a sub‑filesystem rooted at `path`.""" + if factory is None: + from ._subfs import SubFS + + factory = SubFS + return factory(self, path) + + def scandir( + self, path: str, namespaces: Collection[str] | None = None + ) -> Iterator[Info]: + return (self.getinfo(f"{path}/{p}", namespaces) for p in self.listdir(path)) + + @property + def walk(self) -> BoundWalker: + return BoundWalker(self) + + def readbytes(self, path: str) -> bytes: + with self.open(path, "rb") as f: + return f.read() + + def writebytes(self, path: str, data: bytes): + with self.open(path, "wb") as f: + f.write(data) + + def create(self, path: str, wipe: bool = False): + if not wipe and self.exists(path): + return False + with self.open(path, "wb"): + pass # 'touch' empty file + return True + + def copy(self, src_path: str, dst_path: str, overwrite=False): + if not self.exists(src_path): + raise ResourceNotFound(f"{src_path!r} does not exist") + elif not self.isfile(src_path): + raise FileExpected(f"path {src_path!r} should be a file") + if not overwrite and self.exists(dst_path): + raise DestinationExists(f"destination {dst_path!r} already exists") + if not self.isdir(dirname(dst_path)): + raise DirectoryExpected(f"path {dirname(dst_path)!r} should be a directory") + copy_file(self, src_path, self, dst_path) + + def copydir(self, src_path: str, dst_path: str, create=False): + if not create and not self.exists(dst_path): + raise ResourceNotFound(f"{dst_path!r} does not exist") + if not self.isdir(src_path): + raise DirectoryExpected(f"path {src_path!r} should be a directory") + copy_dir(self, src_path, self, dst_path) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_copy.py b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_copy.py new file mode 100644 index 0000000000000000000000000000000000000000..194f9ffbb456dfc8c915ea82b4179f89a2e7a21e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_copy.py @@ -0,0 +1,45 @@ +from __future__ import annotations + +import typing + +from ._errors import IllegalDestination +from ._path import combine, frombase, isbase +from ._tools import copy_file_data + +if typing.TYPE_CHECKING: + from ._base import FS + + +def copy_file(src_fs: FS, src_path: str, dst_fs: FS, dst_path: str): + if src_fs is dst_fs and src_path == dst_path: + raise IllegalDestination(f"cannot copy {src_path!r} to itself") + + with src_fs.open(src_path, "rb") as src_file: + with dst_fs.open(dst_path, "wb") as dst_file: + copy_file_data(src_file, dst_file) + + +def copy_structure( + src_fs: FS, + dst_fs: FS, + src_root: str = "/", + dst_root: str = "/", +): + if src_fs is dst_fs and isbase(src_root, dst_root): + raise IllegalDestination(f"cannot copy {src_fs!r} to itself") + + dst_fs.makedirs(dst_root, recreate=True) + for dir_path in src_fs.walk.dirs(src_root): + dst_fs.makedir(combine(dst_root, frombase(src_root, dir_path)), recreate=True) + + +def copy_dir(src_fs: FS, src_path: str, dst_fs: FS, dst_path: str): + copy_structure(src_fs, dst_fs, src_path, dst_path) + + for file_path in src_fs.walk.files(src_path): + copy_path = combine(dst_path, frombase(src_path, file_path)) + copy_file(src_fs, file_path, dst_fs, copy_path) + + +def copy_fs(src_fs: FS, dst_fs: FS): + copy_dir(src_fs, "/", dst_fs, "/") diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_errors.py b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_errors.py new file mode 100644 index 0000000000000000000000000000000000000000..5017d563377146915824c718cdcf0fb5d5b9b570 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_errors.py @@ -0,0 +1,54 @@ +class FSError(Exception): + pass + + +class CreateFailed(FSError): + pass + + +class FilesystemClosed(FSError): + pass + + +class MissingInfoNamespace(FSError): + pass + + +class NoSysPath(FSError): + pass + + +class OperationFailed(FSError): + pass + + +class IllegalDestination(OperationFailed): + pass + + +class ResourceError(FSError): + pass + + +class ResourceNotFound(ResourceError): + pass + + +class DirectoryExpected(ResourceError): + pass + + +class DirectoryNotEmpty(ResourceError): + pass + + +class FileExpected(ResourceError): + pass + + +class DestinationExists(ResourceError): + pass + + +class ResourceReadOnly(ResourceError): + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_info.py b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_info.py new file mode 100644 index 0000000000000000000000000000000000000000..7c204c83c47e221d64fb829fbbdd25bfdfe3edaa --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_info.py @@ -0,0 +1,75 @@ +from __future__ import annotations + +import typing +from datetime import datetime, timezone + +from ._errors import MissingInfoNamespace + +if typing.TYPE_CHECKING: + from collections.abc import Mapping + from typing import Any + + +def epoch_to_datetime(t: int | None) -> datetime | None: + """Convert epoch time to a UTC datetime.""" + if t is None: + return None + return datetime.fromtimestamp(t, tz=timezone.utc) + + +class Info: + __slots__ = ["raw", "namespaces"] + + def __init__(self, raw_info: Mapping[str, Any]): + self.raw = raw_info + self.namespaces = frozenset(raw_info.keys()) + + def get(self, namespace: str, key: str, default: Any | None = None) -> Any | None: + try: + return self.raw[namespace].get(key, default) + except KeyError: + raise MissingInfoNamespace(f"Namespace {namespace!r} does not exist") + + @property + def name(self) -> str: + return self.get("basic", "name") + + @property + def is_dir(self) -> bool: + return self.get("basic", "is_dir") + + @property + def is_file(self) -> bool: + return not self.is_dir + + @property + def accessed(self) -> datetime | None: + return epoch_to_datetime(self.get("details", "accessed")) + + @property + def modified(self) -> datetime | None: + return epoch_to_datetime(self.get("details", "modified")) + + @property + def size(self) -> int | None: + return self.get("details", "size") + + @property + def type(self) -> int | None: + return self.get("details", "type") + + @property + def created(self) -> datetime | None: + return epoch_to_datetime(self.get("details", "created")) + + @property + def metadata_changed(self) -> datetime | None: + return epoch_to_datetime(self.get("details", "metadata_changed")) + + def __str__(self) -> str: + if self.is_dir: + return "".format(self.name) + else: + return "".format(self.name) + + __repr__ = __str__ diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_osfs.py b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_osfs.py new file mode 100644 index 0000000000000000000000000000000000000000..3f533bb8da4fce4f76a6a0abf6a154f74635d96c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_osfs.py @@ -0,0 +1,164 @@ +from __future__ import annotations + +import errno +import platform +import shutil +import stat +import typing +from os import PathLike +from pathlib import Path + +from ._base import FS +from ._errors import ( + CreateFailed, + DirectoryExpected, + DirectoryNotEmpty, + FileExpected, + IllegalDestination, + ResourceError, + ResourceNotFound, +) +from ._info import Info +from ._path import isbase + +if typing.TYPE_CHECKING: + from collections.abc import Collection + from typing import IO, Any + + from ._subfs import SubFS + + +_WINDOWS_PLATFORM = platform.system() == "Windows" + + +class OSFS(FS): + """Filesystem for a directory on the local disk. + + A thin layer on top of `pathlib.Path`. + """ + + def __init__(self, root: str | PathLike, create: bool = False): + super().__init__() + self._root = Path(root).resolve() + if create: + self._root.mkdir(parents=True, exist_ok=True) + else: + if not self._root.is_dir(): + raise CreateFailed( + f"unable to create OSFS: {root!r} does not exist or is not a directory" + ) + + def _abs(self, rel_path: str) -> Path: + self.check() + return (self._root / rel_path.strip("/")).resolve() + + def open(self, path: str, mode: str = "rb", **kwargs) -> IO[Any]: + try: + return self._abs(path).open(mode, **kwargs) + except FileNotFoundError: + raise ResourceNotFound(f"No such file or directory: {path!r}") + + def exists(self, path: str) -> bool: + return self._abs(path).exists() + + def isdir(self, path: str) -> bool: + return self._abs(path).is_dir() + + def isfile(self, path: str) -> bool: + return self._abs(path).is_file() + + def listdir(self, path: str) -> list[str]: + return [p.name for p in self._abs(path).iterdir()] + + def _mkdir(self, path: str, parents: bool = False, exist_ok: bool = False) -> SubFS: + self._abs(path).mkdir(parents=parents, exist_ok=exist_ok) + return self.opendir(path) + + def makedir(self, path: str, recreate: bool = False) -> SubFS: + return self._mkdir(path, parents=False, exist_ok=recreate) + + def makedirs(self, path: str, recreate: bool = False) -> SubFS: + return self._mkdir(path, parents=True, exist_ok=recreate) + + def getinfo(self, path: str, namespaces: Collection[str] | None = None) -> Info: + path = self._abs(path) + if not path.exists(): + raise ResourceNotFound(f"No such file or directory: {str(path)!r}") + info = { + "basic": { + "name": path.name, + "is_dir": path.is_dir(), + } + } + namespaces = namespaces or () + if "details" in namespaces: + stat_result = path.stat() + details = info["details"] = { + "accessed": stat_result.st_atime, + "modified": stat_result.st_mtime, + "size": stat_result.st_size, + "type": stat.S_IFMT(stat_result.st_mode), + "created": getattr(stat_result, "st_birthtime", None), + } + ctime_key = "created" if _WINDOWS_PLATFORM else "metadata_changed" + details[ctime_key] = stat_result.st_ctime + return Info(info) + + def remove(self, path: str): + path = self._abs(path) + try: + path.unlink() + except FileNotFoundError: + raise ResourceNotFound(f"No such file or directory: {str(path)!r}") + except OSError as e: + if path.is_dir(): + raise FileExpected(f"path {str(path)!r} should be a file") + else: + raise ResourceError(f"unable to remove {str(path)!r}: {e}") + + def removedir(self, path: str): + try: + self._abs(path).rmdir() + except NotADirectoryError: + raise DirectoryExpected(f"path {path!r} should be a directory") + except OSError as e: + if e.errno == errno.ENOTEMPTY: + raise DirectoryNotEmpty(f"Directory not empty: {path!r}") + else: + raise ResourceError(f"unable to remove {path!r}: {e}") + + def removetree(self, path: str): + shutil.rmtree(self._abs(path)) + + def movedir(self, src_dir: str, dst_dir: str, create: bool = False): + if isbase(src_dir, dst_dir): + raise IllegalDestination(f"cannot move {src_dir!r} to {dst_dir!r}") + src_path = self._abs(src_dir) + if not src_path.exists(): + raise ResourceNotFound(f"Source {src_dir!r} does not exist") + elif not src_path.is_dir(): + raise DirectoryExpected(f"Source {src_dir!r} should be a directory") + dst_path = self._abs(dst_dir) + if not create and not dst_path.exists(): + raise ResourceNotFound(f"Destination {dst_dir!r} does not exist") + if dst_path.is_file(): + raise DirectoryExpected(f"Destination {dst_dir!r} should be a directory") + if create: + dst_path.parent.mkdir(parents=True, exist_ok=True) + if dst_path.exists(): + if list(dst_path.iterdir()): + raise DirectoryNotEmpty(f"Destination {dst_dir!r} is not empty") + elif _WINDOWS_PLATFORM: + # on Unix os.rename silently replaces an empty dst_dir whereas on + # Windows it always raises FileExistsError, empty or not. + dst_path.rmdir() + src_path.rename(dst_path) + + def getsyspath(self, path: str) -> str: + return str(self._abs(path)) + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({str(self._root)!r})" + + def __str__(self) -> str: + return f"<{self.__class__.__name__.lower()} '{self._root}'>" diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_path.py b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_path.py new file mode 100644 index 0000000000000000000000000000000000000000..e89c00b3d97c88339187c3cda03445a7822807e0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_path.py @@ -0,0 +1,67 @@ +import os +import platform + +_WINDOWS_PLATFORM = platform.system() == "Windows" + + +def combine(path1: str, path2) -> str: + if not path1: + return path2 + return "{}/{}".format(path1.rstrip("/"), path2.lstrip("/")) + + +def split(path: str) -> tuple[str, str]: + if "/" not in path: + return ("", path) + split = path.rsplit("/", 1) + return (split[0] or "/", split[1]) + + +def dirname(path: str) -> str: + return split(path)[0] + + +def basename(path: str) -> str: + return split(path)[1] + + +def forcedir(path: str) -> str: + # Ensure the path ends with a trailing forward slash. + if not path.endswith("/"): + return path + "/" + return path + + +def abspath(path: str) -> str: + # FS objects have no concept of a *current directory*. This simply + # ensures the path starts with a forward slash. + if not path.startswith("/"): + return "/" + path + return path + + +def isbase(path1: str, path2: str) -> bool: + # Check if `path1` is a base or prefix of `path2`. + _path1 = forcedir(abspath(path1)) + _path2 = forcedir(abspath(path2)) + return _path2.startswith(_path1) + + +def frombase(path1: str, path2: str) -> str: + # Get the final path of `path2` that isn't in `path1`. + if not isbase(path1, path2): + raise ValueError(f"path1 must be a prefix of path2: {path1!r} vs {path2!r}") + return path2[len(path1) :] + + +def relpath(path: str) -> str: + return path.lstrip("/") + + +def normpath(path: str) -> str: + normalized = os.path.normpath(path) + if _WINDOWS_PLATFORM: + # os.path.normpath converts backslashes to forward slashes on Windows + # but we want forward slashes, so we convert them back + normalized = normalized.replace("\\", "/") + return normalized diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_subfs.py b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_subfs.py new file mode 100644 index 0000000000000000000000000000000000000000..bc7d8825af100384d5b4f0522eaafc6dd1a626ac --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_subfs.py @@ -0,0 +1,92 @@ +from __future__ import annotations + +import typing +from pathlib import PurePosixPath + +from ._base import FS +from ._errors import DirectoryExpected, ResourceNotFound + +if typing.TYPE_CHECKING: + from collections.abc import Collection + from typing import IO, Any + + from ._info import Info + + +class SubFS(FS): + """Maps a sub-directory of another filesystem.""" + + def __init__(self, parent: FS, sub_path: str): + super().__init__() + self._parent = parent + self._prefix = PurePosixPath(sub_path).as_posix().rstrip("/") + if not parent.exists(self._prefix): + raise ResourceNotFound(f"No such file or directory: {sub_path!r}") + elif not parent.isdir(self._prefix): + raise DirectoryExpected(f"{sub_path!r} is not a directory") + + def delegate_fs(self): + return self._parent + + def _full(self, rel: str) -> str: + self.check() + return f"{self._prefix}/{PurePosixPath(rel).as_posix()}".lstrip("/") + + def open(self, path: str, mode: str = "rb", **kwargs) -> IO[Any]: + return self._parent.open(self._full(path), mode, **kwargs) + + def exists(self, path: str) -> bool: + return self._parent.exists(self._full(path)) + + def isdir(self, path: str) -> bool: + return self._parent.isdir(self._full(path)) + + def isfile(self, path: str) -> bool: + return self._parent.isfile(self._full(path)) + + def listdir(self, path: str) -> list[str]: + return self._parent.listdir(self._full(path)) + + def makedir(self, path: str, recreate: bool = False): + return self._parent.makedir(self._full(path), recreate=recreate) + + def makedirs(self, path: str, recreate: bool = False): + return self._parent.makedirs(self._full(path), recreate=recreate) + + def getinfo(self, path: str, namespaces: Collection[str] | None = None) -> Info: + return self._parent.getinfo(self._full(path), namespaces=namespaces) + + def remove(self, path: str): + return self._parent.remove(self._full(path)) + + def removedir(self, path: str): + return self._parent.removedir(self._full(path)) + + def removetree(self, path: str): + return self._parent.removetree(self._full(path)) + + def movedir(self, src: str, dst: str, create: bool = False): + self._parent.movedir(self._full(src), self._full(dst), create=create) + + def getsyspath(self, path: str) -> str: + return self._parent.getsyspath(self._full(path)) + + def readbytes(self, path: str) -> bytes: + return self._parent.readbytes(self._full(path)) + + def writebytes(self, path: str, data: bytes): + self._parent.writebytes(self._full(path), data) + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({self._parent!r}, {self._prefix!r})" + + def __str__(self) -> str: + return f"{self._parent}/{self._prefix}" + + +class ClosingSubFS(SubFS): + """Like SubFS, but auto-closes the parent filesystem when closed.""" + + def close(self): + super().close() + self._parent.close() diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_tempfs.py b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_tempfs.py new file mode 100644 index 0000000000000000000000000000000000000000..9f968c45f0211f004491f6207545f9343a47378d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_tempfs.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +import shutil +import tempfile + +from ._errors import OperationFailed +from ._osfs import OSFS + + +class TempFS(OSFS): + def __init__(self, auto_clean: bool = True, ignore_clean_errors: bool = True): + self.auto_clean = auto_clean + self.ignore_clean_errors = ignore_clean_errors + self._temp_dir = tempfile.mkdtemp("__temp_fs__") + self._cleaned = False + super().__init__(self._temp_dir) + + def close(self): + if self.auto_clean: + self.clean() + super().close() + + def clean(self): + if self._cleaned: + return + + try: + shutil.rmtree(self._temp_dir) + except Exception as e: + if not self.ignore_clean_errors: + raise OperationFailed( + f"failed to remove temporary directory: {self._temp_dir!r}" + ) from e + self._cleaned = True diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_tools.py b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_tools.py new file mode 100644 index 0000000000000000000000000000000000000000..4b02ac0d2533064246312e1127a1a56d2f6d6a39 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_tools.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +import typing +from pathlib import PurePosixPath + +from ._errors import DirectoryNotEmpty + +if typing.TYPE_CHECKING: + from typing import IO + + from ._base import FS + + +def remove_empty(fs: FS, path: str): + """Remove all empty parents.""" + path = PurePosixPath(path) + root = PurePosixPath("/") + try: + while path != root: + fs.removedir(path.as_posix()) + path = path.parent + except DirectoryNotEmpty: + pass + + +def copy_file_data(src_file: IO, dst_file: IO, chunk_size: int | None = None): + """Copy data from one file object to another.""" + _chunk_size = 1024 * 1024 if chunk_size is None else chunk_size + read = src_file.read + write = dst_file.write + # in iter(callable, sentilel), callable is called until it returns the sentinel; + # this allows to copy `chunk_size` bytes at a time. + for chunk in iter(lambda: read(_chunk_size) or None, None): + write(chunk) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_walk.py b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_walk.py new file mode 100644 index 0000000000000000000000000000000000000000..e372e618a4bfa9b0087e82e875e2909475cb40ea --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_walk.py @@ -0,0 +1,55 @@ +from __future__ import annotations + +import typing +from collections import deque +from collections.abc import Collection, Iterator + +from ._path import combine + +if typing.TYPE_CHECKING: + from typing import Callable + + from ._base import FS + from ._info import Info + + +class BoundWalker: + def __init__(self, fs: FS): + self._fs = fs + + def _iter_walk( + self, path: str, namespaces: Collection[str] | None = None + ) -> Iterator[tuple[str, Info | None]]: + """Walk files using a *breadth first* search.""" + queue = deque([path]) + push = queue.appendleft + pop = queue.pop + _scan = self._fs.scandir + _combine = combine + + while queue: + dir_path = pop() + for info in _scan(dir_path, namespaces=namespaces): + if info.is_dir: + yield dir_path, info + push(_combine(dir_path, info.name)) + else: + yield dir_path, info + yield path, None + + def _filter( + self, + include: Callable[[str, Info], bool] = lambda path, info: True, + path: str = "/", + namespaces: Collection[str] | None = None, + ) -> Iterator[str]: + _combine = combine + for path, info in self._iter_walk(path, namespaces): + if info is not None and include(path, info): + yield _combine(path, info.name) + + def files(self, path: str = "/") -> Iterator[str]: + yield from self._filter(lambda _, info: info.is_file, path) + + def dirs(self, path: str = "/") -> Iterator[str]: + yield from self._filter(lambda _, info: info.is_dir, path) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_zipfs.py b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_zipfs.py new file mode 100644 index 0000000000000000000000000000000000000000..1635a6d0abd33798c6d2b5acedc0a1406486889f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/filesystem/_zipfs.py @@ -0,0 +1,204 @@ +from __future__ import annotations + +import io +import os +import shutil +import stat +import typing +import zipfile +from datetime import datetime + +from ._base import FS +from ._errors import FileExpected, ResourceNotFound, ResourceReadOnly +from ._info import Info +from ._path import dirname, forcedir, normpath, relpath +from ._tempfs import TempFS + +if typing.TYPE_CHECKING: + from collections.abc import Collection + from typing import IO, Any + + from ._subfs import SubFS + + +class ZipFS(FS): + """Read and write zip files.""" + + def __new__( + cls, file: str | os.PathLike, write: bool = False, encoding: str = "utf-8" + ): + if write: + return WriteZipFS(file, encoding) + else: + return ReadZipFS(file, encoding) + + if typing.TYPE_CHECKING: + + def __init__( + self, file: str | os.PathLike, write: bool = False, encoding: str = "utf-8" + ): + pass + + +class ReadZipFS(FS): + """A readable zip file.""" + + def __init__(self, file: str | os.PathLike, encoding: str = "utf-8"): + super().__init__() + self._file = os.fspath(file) + self.encoding = encoding # unused + self._zip = zipfile.ZipFile(file, "r") + self._directory_fs = None + + def __repr__(self) -> str: + return f"ReadZipFS({self._file!r})" + + def __str__(self) -> str: + return f"" + + def _path_to_zip_name(self, path: str) -> str: + """Convert a path to a zip file name.""" + path = relpath(normpath(path)) + if self._directory.isdir(path): + path = forcedir(path) + return path + + @property + def _directory(self) -> TempFS: + if self._directory_fs is None: + self._directory_fs = _fs = TempFS() + for zip_name in self._zip.namelist(): + resource_name = zip_name + if resource_name.endswith("/"): + _fs.makedirs(resource_name, recreate=True) + else: + _fs.makedirs(dirname(resource_name), recreate=True) + _fs.create(resource_name) + return self._directory_fs + + def close(self): + super(ReadZipFS, self).close() + self._zip.close() + if self._directory_fs is not None: + self._directory_fs.close() + + def getinfo(self, path: str, namespaces: Collection[str] | None = None) -> Info: + namespaces = namespaces or () + raw_info = {} + + if path == "/": + raw_info["basic"] = {"name": "", "is_dir": True} + if "details" in namespaces: + raw_info["details"] = {"type": stat.S_IFDIR} + else: + basic_info = self._directory.getinfo(path) + raw_info["basic"] = {"name": basic_info.name, "is_dir": basic_info.is_dir} + + if "details" in namespaces: + zip_name = self._path_to_zip_name(path) + try: + zip_info = self._zip.getinfo(zip_name) + except KeyError: + pass + else: + if "details" in namespaces: + raw_info["details"] = { + "size": zip_info.file_size, + "type": int( + stat.S_IFDIR if basic_info.is_dir else stat.S_IFREG + ), + "modified": datetime(*zip_info.date_time).timestamp(), + } + + return Info(raw_info) + + def exists(self, path: str) -> bool: + self.check() + return self._directory.exists(path) + + def isdir(self, path: str) -> bool: + self.check() + return self._directory.isdir(path) + + def isfile(self, path: str) -> bool: + self.check() + return self._directory.isfile(path) + + def listdir(self, path: str) -> str: + self.check() + return self._directory.listdir(path) + + def makedir(self, path: str, recreate: bool = False) -> SubFS: + self.check() + raise ResourceReadOnly(path) + + def makedirs(self, path: str, recreate: bool = False) -> SubFS: + self.check() + raise ResourceReadOnly(path) + + def remove(self, path: str): + self.check() + raise ResourceReadOnly(path) + + def removedir(self, path: str): + self.check() + raise ResourceReadOnly(path) + + def removetree(self, path: str): + self.check() + raise ResourceReadOnly(path) + + def movedir(self, src: str, dst: str, create: bool = False): + self.check() + raise ResourceReadOnly(src) + + def readbytes(self, path: str) -> bytes: + self.check() + if not self._directory.isfile(path): + raise ResourceNotFound(path) + zip_name = self._path_to_zip_name(path) + zip_bytes = self._zip.read(zip_name) + return zip_bytes + + def open(self, path: str, mode: str = "rb", **kwargs) -> IO[Any]: + self.check() + if self._directory.isdir(path): + raise FileExpected(f"{path!r} is a directory") + + zip_mode = mode[0] + if zip_mode == "r" and not self._directory.exists(path): + raise ResourceNotFound(f"No such file or directory: {path!r}") + + if any(m in mode for m in "wax+"): + raise ResourceReadOnly(path) + + zip_name = self._path_to_zip_name(path) + stream = self._zip.open(zip_name, zip_mode) + if "b" in mode: + if kwargs: + raise ValueError("encoding args invalid for binary operation") + return stream + # Text mode + return io.TextIOWrapper(stream, **kwargs) + + +class WriteZipFS(TempFS): + """A writable zip file.""" + + def __init__(self, file: str | os.PathLike, encoding: str = "utf-8"): + super().__init__() + self._file = os.fspath(file) + self.encoding = encoding # unused + + def __repr__(self) -> str: + return f"WriteZipFS({self._file!r})" + + def __str__(self) -> str: + return f"" + + def close(self): + base_name = os.path.splitext(self._file)[0] + shutil.make_archive(base_name, format="zip", root_dir=self._temp_dir) + if self._file != base_name + ".zip": + shutil.move(base_name + ".zip", self._file) + super().close() diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/fixedTools.py b/.venv/lib/python3.13/site-packages/fontTools/misc/fixedTools.py new file mode 100644 index 0000000000000000000000000000000000000000..b7086c8ac1e0409b6223b32946727db0cbf534f3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/fixedTools.py @@ -0,0 +1,253 @@ +""" +The `OpenType specification `_ +defines two fixed-point data types: + +``Fixed`` + A 32-bit signed fixed-point number with a 16 bit twos-complement + magnitude component and 16 fractional bits. +``F2DOT14`` + A 16-bit signed fixed-point number with a 2 bit twos-complement + magnitude component and 14 fractional bits. + +To support reading and writing data with these data types, this module provides +functions for converting between fixed-point, float and string representations. + +.. data:: MAX_F2DOT14 + + The maximum value that can still fit in an F2Dot14. (1.99993896484375) +""" + +from .roundTools import otRound, nearestMultipleShortestRepr +import logging + +log = logging.getLogger(__name__) + +__all__ = [ + "MAX_F2DOT14", + "fixedToFloat", + "floatToFixed", + "floatToFixedToFloat", + "floatToFixedToStr", + "fixedToStr", + "strToFixed", + "strToFixedToFloat", + "ensureVersionIsLong", + "versionToFixed", +] + + +MAX_F2DOT14 = 0x7FFF / (1 << 14) + + +def fixedToFloat(value: float, precisionBits: int) -> float: + """Converts a fixed-point number to a float given the number of + precision bits. + + Args: + value (int): Number in fixed-point format. + precisionBits (int): Number of precision bits. + + Returns: + Floating point value. + + Examples:: + + >>> import math + >>> f = fixedToFloat(-10139, precisionBits=14) + >>> math.isclose(f, -0.61883544921875) + True + """ + return value / (1 << precisionBits) + + +def floatToFixed(value, precisionBits): + """Converts a float to a fixed-point number given the number of + precision bits. + + Args: + value (float): Floating point value. + precisionBits (int): Number of precision bits. + + Returns: + int: Fixed-point representation. + + Examples:: + + >>> floatToFixed(-0.61883544921875, precisionBits=14) + -10139 + >>> floatToFixed(-0.61884, precisionBits=14) + -10139 + """ + return otRound(value * (1 << precisionBits)) + + +def floatToFixedToFloat(value, precisionBits): + """Converts a float to a fixed-point number and back again. + + By converting the float to fixed, rounding it, and converting it back + to float again, this returns a floating point values which is exactly + representable in fixed-point format. + + Note: this **is** equivalent to ``fixedToFloat(floatToFixed(value))``. + + Args: + value (float): The input floating point value. + precisionBits (int): Number of precision bits. + + Returns: + float: The transformed and rounded value. + + Examples:: + >>> import math + >>> f1 = -0.61884 + >>> f2 = floatToFixedToFloat(-0.61884, precisionBits=14) + >>> f1 != f2 + True + >>> math.isclose(f2, -0.61883544921875) + True + """ + scale = 1 << precisionBits + return otRound(value * scale) / scale + + +def fixedToStr(value, precisionBits): + """Converts a fixed-point number to a string representing a decimal float. + + This chooses the float that has the shortest decimal representation (the least + number of fractional decimal digits). + + For example, to convert a fixed-point number in a 2.14 format, use + ``precisionBits=14``:: + + >>> fixedToStr(-10139, precisionBits=14) + '-0.61884' + + This is pretty slow compared to the simple division used in ``fixedToFloat``. + Use sporadically when you need to serialize or print the fixed-point number in + a human-readable form. + It uses nearestMultipleShortestRepr under the hood. + + Args: + value (int): The fixed-point value to convert. + precisionBits (int): Number of precision bits, *up to a maximum of 16*. + + Returns: + str: A string representation of the value. + """ + scale = 1 << precisionBits + return nearestMultipleShortestRepr(value / scale, factor=1.0 / scale) + + +def strToFixed(string, precisionBits): + """Converts a string representing a decimal float to a fixed-point number. + + Args: + string (str): A string representing a decimal float. + precisionBits (int): Number of precision bits, *up to a maximum of 16*. + + Returns: + int: Fixed-point representation. + + Examples:: + + >>> ## to convert a float string to a 2.14 fixed-point number: + >>> strToFixed('-0.61884', precisionBits=14) + -10139 + """ + value = float(string) + return otRound(value * (1 << precisionBits)) + + +def strToFixedToFloat(string, precisionBits): + """Convert a string to a decimal float with fixed-point rounding. + + This first converts string to a float, then turns it into a fixed-point + number with ``precisionBits`` fractional binary digits, then back to a + float again. + + This is simply a shorthand for fixedToFloat(floatToFixed(float(s))). + + Args: + string (str): A string representing a decimal float. + precisionBits (int): Number of precision bits. + + Returns: + float: The transformed and rounded value. + + Examples:: + + >>> import math + >>> s = '-0.61884' + >>> bits = 14 + >>> f = strToFixedToFloat(s, precisionBits=bits) + >>> math.isclose(f, -0.61883544921875) + True + >>> f == fixedToFloat(floatToFixed(float(s), precisionBits=bits), precisionBits=bits) + True + """ + value = float(string) + scale = 1 << precisionBits + return otRound(value * scale) / scale + + +def floatToFixedToStr(value, precisionBits): + """Convert float to string with fixed-point rounding. + + This uses the shortest decimal representation (ie. the least + number of fractional decimal digits) to represent the equivalent + fixed-point number with ``precisionBits`` fractional binary digits. + It uses nearestMultipleShortestRepr under the hood. + + >>> floatToFixedToStr(-0.61883544921875, precisionBits=14) + '-0.61884' + + Args: + value (float): The float value to convert. + precisionBits (int): Number of precision bits, *up to a maximum of 16*. + + Returns: + str: A string representation of the value. + + """ + scale = 1 << precisionBits + return nearestMultipleShortestRepr(value, factor=1.0 / scale) + + +def ensureVersionIsLong(value): + """Ensure a table version is an unsigned long. + + OpenType table version numbers are expressed as a single unsigned long + comprising of an unsigned short major version and unsigned short minor + version. This function detects if the value to be used as a version number + looks too small (i.e. is less than ``0x10000``), and converts it to + fixed-point using :func:`floatToFixed` if so. + + Args: + value (Number): a candidate table version number. + + Returns: + int: A table version number, possibly corrected to fixed-point. + """ + if value < 0x10000: + newValue = floatToFixed(value, 16) + log.warning( + "Table version value is a float: %.4f; " "fix to use hex instead: 0x%08x", + value, + newValue, + ) + value = newValue + return value + + +def versionToFixed(value): + """Ensure a table version number is fixed-point. + + Args: + value (str): a candidate table version number. + + Returns: + int: A table version number, possibly corrected to fixed-point. + """ + value = int(value, 0) if value.startswith("0") else float(value) + value = ensureVersionIsLong(value) + return value diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/intTools.py b/.venv/lib/python3.13/site-packages/fontTools/misc/intTools.py new file mode 100644 index 0000000000000000000000000000000000000000..0ca29854aae85750bdd7d25efc25ffd59392dc8e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/intTools.py @@ -0,0 +1,25 @@ +__all__ = ["popCount", "bit_count", "bit_indices"] + + +try: + bit_count = int.bit_count +except AttributeError: + + def bit_count(v): + return bin(v).count("1") + + +"""Return number of 1 bits (population count) of the absolute value of an integer. + +See https://docs.python.org/3.10/library/stdtypes.html#int.bit_count +""" +popCount = bit_count # alias + + +def bit_indices(v): + """Return list of indices where bits are set, 0 being the index of the least significant bit. + + >>> bit_indices(0b101) + [0, 2] + """ + return [i for i, b in enumerate(bin(v)[::-1]) if b == "1"] diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/lazyTools.py b/.venv/lib/python3.13/site-packages/fontTools/misc/lazyTools.py new file mode 100644 index 0000000000000000000000000000000000000000..91cb80c99262d7d3b6a998847df8de295470d9b9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/lazyTools.py @@ -0,0 +1,42 @@ +from collections import UserDict, UserList + +__all__ = ["LazyDict", "LazyList"] + + +class LazyDict(UserDict): + def __init__(self, data): + super().__init__() + self.data = data + + def __getitem__(self, k): + v = self.data[k] + if callable(v): + v = v(k) + self.data[k] = v + return v + + +class LazyList(UserList): + def __getitem__(self, k): + if isinstance(k, slice): + indices = range(*k.indices(len(self))) + return [self[i] for i in indices] + v = self.data[k] + if callable(v): + v = v(k) + self.data[k] = v + return v + + def __add__(self, other): + if isinstance(other, LazyList): + other = list(other) + elif isinstance(other, list): + pass + else: + return NotImplemented + return list(self) + other + + def __radd__(self, other): + if not isinstance(other, list): + return NotImplemented + return other + list(self) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/loggingTools.py b/.venv/lib/python3.13/site-packages/fontTools/misc/loggingTools.py new file mode 100644 index 0000000000000000000000000000000000000000..be6c2d369b62b23e82397515ad9416ed38868f1e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/loggingTools.py @@ -0,0 +1,543 @@ +import sys +import logging +import timeit +from functools import wraps +from collections.abc import Mapping, Callable +import warnings +from logging import PercentStyle + + +# default logging level used by Timer class +TIME_LEVEL = logging.DEBUG + +# per-level format strings used by the default formatter +# (the level name is not printed for INFO and DEBUG messages) +DEFAULT_FORMATS = { + "*": "%(levelname)s: %(message)s", + "INFO": "%(message)s", + "DEBUG": "%(message)s", +} + + +class LevelFormatter(logging.Formatter): + """Log formatter with level-specific formatting. + + Formatter class which optionally takes a dict of logging levels to + format strings, allowing to customise the log records appearance for + specific levels. + + + Attributes: + fmt: A dictionary mapping logging levels to format strings. + The ``*`` key identifies the default format string. + datefmt: As per py:class:`logging.Formatter` + style: As per py:class:`logging.Formatter` + + >>> import sys + >>> handler = logging.StreamHandler(sys.stdout) + >>> formatter = LevelFormatter( + ... fmt={ + ... '*': '[%(levelname)s] %(message)s', + ... 'DEBUG': '%(name)s [%(levelname)s] %(message)s', + ... 'INFO': '%(message)s', + ... }) + >>> handler.setFormatter(formatter) + >>> log = logging.getLogger('test') + >>> log.setLevel(logging.DEBUG) + >>> log.addHandler(handler) + >>> log.debug('this uses a custom format string') + test [DEBUG] this uses a custom format string + >>> log.info('this also uses a custom format string') + this also uses a custom format string + >>> log.warning("this one uses the default format string") + [WARNING] this one uses the default format string + """ + + def __init__(self, fmt=None, datefmt=None, style="%"): + if style != "%": + raise ValueError( + "only '%' percent style is supported in both python 2 and 3" + ) + if fmt is None: + fmt = DEFAULT_FORMATS + if isinstance(fmt, str): + default_format = fmt + custom_formats = {} + elif isinstance(fmt, Mapping): + custom_formats = dict(fmt) + default_format = custom_formats.pop("*", None) + else: + raise TypeError("fmt must be a str or a dict of str: %r" % fmt) + super(LevelFormatter, self).__init__(default_format, datefmt) + self.default_format = self._fmt + self.custom_formats = {} + for level, fmt in custom_formats.items(): + level = logging._checkLevel(level) + self.custom_formats[level] = fmt + + def format(self, record): + if self.custom_formats: + fmt = self.custom_formats.get(record.levelno, self.default_format) + if self._fmt != fmt: + self._fmt = fmt + # for python >= 3.2, _style needs to be set if _fmt changes + if PercentStyle: + self._style = PercentStyle(fmt) + return super(LevelFormatter, self).format(record) + + +def configLogger(**kwargs): + """A more sophisticated logging system configuation manager. + + This is more or less the same as :py:func:`logging.basicConfig`, + with some additional options and defaults. + + The default behaviour is to create a ``StreamHandler`` which writes to + sys.stderr, set a formatter using the ``DEFAULT_FORMATS`` strings, and add + the handler to the top-level library logger ("fontTools"). + + A number of optional keyword arguments may be specified, which can alter + the default behaviour. + + Args: + + logger: Specifies the logger name or a Logger instance to be + configured. (Defaults to "fontTools" logger). Unlike ``basicConfig``, + this function can be called multiple times to reconfigure a logger. + If the logger or any of its children already exists before the call is + made, they will be reset before the new configuration is applied. + filename: Specifies that a ``FileHandler`` be created, using the + specified filename, rather than a ``StreamHandler``. + filemode: Specifies the mode to open the file, if filename is + specified. (If filemode is unspecified, it defaults to ``a``). + format: Use the specified format string for the handler. This + argument also accepts a dictionary of format strings keyed by + level name, to allow customising the records appearance for + specific levels. The special ``'*'`` key is for 'any other' level. + datefmt: Use the specified date/time format. + level: Set the logger level to the specified level. + stream: Use the specified stream to initialize the StreamHandler. Note + that this argument is incompatible with ``filename`` - if both + are present, ``stream`` is ignored. + handlers: If specified, this should be an iterable of already created + handlers, which will be added to the logger. Any handler in the + list which does not have a formatter assigned will be assigned the + formatter created in this function. + filters: If specified, this should be an iterable of already created + filters. If the ``handlers`` do not already have filters assigned, + these filters will be added to them. + propagate: All loggers have a ``propagate`` attribute which determines + whether to continue searching for handlers up the logging hierarchy. + If not provided, the "propagate" attribute will be set to ``False``. + """ + # using kwargs to enforce keyword-only arguments in py2. + handlers = kwargs.pop("handlers", None) + if handlers is None: + if "stream" in kwargs and "filename" in kwargs: + raise ValueError( + "'stream' and 'filename' should not be " "specified together" + ) + else: + if "stream" in kwargs or "filename" in kwargs: + raise ValueError( + "'stream' or 'filename' should not be " + "specified together with 'handlers'" + ) + if handlers is None: + filename = kwargs.pop("filename", None) + mode = kwargs.pop("filemode", "a") + if filename: + h = logging.FileHandler(filename, mode) + else: + stream = kwargs.pop("stream", None) + h = logging.StreamHandler(stream) + handlers = [h] + # By default, the top-level library logger is configured. + logger = kwargs.pop("logger", "fontTools") + if not logger or isinstance(logger, str): + # empty "" or None means the 'root' logger + logger = logging.getLogger(logger) + # before (re)configuring, reset named logger and its children (if exist) + _resetExistingLoggers(parent=logger.name) + # use DEFAULT_FORMATS if 'format' is None + fs = kwargs.pop("format", None) + dfs = kwargs.pop("datefmt", None) + # XXX: '%' is the only format style supported on both py2 and 3 + style = kwargs.pop("style", "%") + fmt = LevelFormatter(fs, dfs, style) + filters = kwargs.pop("filters", []) + for h in handlers: + if h.formatter is None: + h.setFormatter(fmt) + if not h.filters: + for f in filters: + h.addFilter(f) + logger.addHandler(h) + if logger.name != "root": + # stop searching up the hierarchy for handlers + logger.propagate = kwargs.pop("propagate", False) + # set a custom severity level + level = kwargs.pop("level", None) + if level is not None: + logger.setLevel(level) + if kwargs: + keys = ", ".join(kwargs.keys()) + raise ValueError("Unrecognised argument(s): %s" % keys) + + +def _resetExistingLoggers(parent="root"): + """Reset the logger named 'parent' and all its children to their initial + state, if they already exist in the current configuration. + """ + root = logging.root + # get sorted list of all existing loggers + existing = sorted(root.manager.loggerDict.keys()) + if parent == "root": + # all the existing loggers are children of 'root' + loggers_to_reset = [parent] + existing + elif parent not in existing: + # nothing to do + return + elif parent in existing: + loggers_to_reset = [parent] + # collect children, starting with the entry after parent name + i = existing.index(parent) + 1 + prefixed = parent + "." + pflen = len(prefixed) + num_existing = len(existing) + while i < num_existing: + if existing[i][:pflen] == prefixed: + loggers_to_reset.append(existing[i]) + i += 1 + for name in loggers_to_reset: + if name == "root": + root.setLevel(logging.WARNING) + for h in root.handlers[:]: + root.removeHandler(h) + for f in root.filters[:]: + root.removeFilters(f) + root.disabled = False + else: + logger = root.manager.loggerDict[name] + logger.level = logging.NOTSET + logger.handlers = [] + logger.filters = [] + logger.propagate = True + logger.disabled = False + + +class Timer(object): + """Keeps track of overall time and split/lap times. + + >>> import time + >>> timer = Timer() + >>> time.sleep(0.01) + >>> print("First lap:", timer.split()) + First lap: ... + >>> time.sleep(0.02) + >>> print("Second lap:", timer.split()) + Second lap: ... + >>> print("Overall time:", timer.time()) + Overall time: ... + + Can be used as a context manager inside with-statements. + + >>> with Timer() as t: + ... time.sleep(0.01) + >>> print("%0.3f seconds" % t.elapsed) + 0... seconds + + If initialised with a logger, it can log the elapsed time automatically + upon exiting the with-statement. + + >>> import logging + >>> log = logging.getLogger("my-fancy-timer-logger") + >>> configLogger(logger=log, level="DEBUG", format="%(message)s", stream=sys.stdout) + >>> with Timer(log, 'do something'): + ... time.sleep(0.01) + Took ... to do something + + The same Timer instance, holding a reference to a logger, can be reused + in multiple with-statements, optionally with different messages or levels. + + >>> timer = Timer(log) + >>> with timer(): + ... time.sleep(0.01) + elapsed time: ...s + >>> with timer('redo it', level=logging.INFO): + ... time.sleep(0.02) + Took ... to redo it + + It can also be used as a function decorator to log the time elapsed to run + the decorated function. + + >>> @timer() + ... def test1(): + ... time.sleep(0.01) + >>> @timer('run test 2', level=logging.INFO) + ... def test2(): + ... time.sleep(0.02) + >>> test1() + Took ... to run 'test1' + >>> test2() + Took ... to run test 2 + """ + + # timeit.default_timer choses the most accurate clock for each platform + _time: Callable[[], float] = staticmethod(timeit.default_timer) + default_msg = "elapsed time: %(time).3fs" + default_format = "Took %(time).3fs to %(msg)s" + + def __init__(self, logger=None, msg=None, level=None, start=None): + self.reset(start) + if logger is None: + for arg in ("msg", "level"): + if locals().get(arg) is not None: + raise ValueError("'%s' can't be specified without a 'logger'" % arg) + self.logger = logger + self.level = level if level is not None else TIME_LEVEL + self.msg = msg + + def reset(self, start=None): + """Reset timer to 'start_time' or the current time.""" + if start is None: + self.start = self._time() + else: + self.start = start + self.last = self.start + self.elapsed = 0.0 + + def time(self): + """Return the overall time (in seconds) since the timer started.""" + return self._time() - self.start + + def split(self): + """Split and return the lap time (in seconds) in between splits.""" + current = self._time() + self.elapsed = current - self.last + self.last = current + return self.elapsed + + def formatTime(self, msg, time): + """Format 'time' value in 'msg' and return formatted string. + If 'msg' contains a '%(time)' format string, try to use that. + Otherwise, use the predefined 'default_format'. + If 'msg' is empty or None, fall back to 'default_msg'. + """ + if not msg: + msg = self.default_msg + if msg.find("%(time)") < 0: + msg = self.default_format % {"msg": msg, "time": time} + else: + try: + msg = msg % {"time": time} + except (KeyError, ValueError): + pass # skip if the format string is malformed + return msg + + def __enter__(self): + """Start a new lap""" + self.last = self._time() + self.elapsed = 0.0 + return self + + def __exit__(self, exc_type, exc_value, traceback): + """End the current lap. If timer has a logger, log the time elapsed, + using the format string in self.msg (or the default one). + """ + time = self.split() + if self.logger is None or exc_type: + # if there's no logger attached, or if any exception occurred in + # the with-statement, exit without logging the time + return + message = self.formatTime(self.msg, time) + # Allow log handlers to see the individual parts to facilitate things + # like a server accumulating aggregate stats. + msg_parts = {"msg": self.msg, "time": time} + self.logger.log(self.level, message, msg_parts) + + def __call__(self, func_or_msg=None, **kwargs): + """If the first argument is a function, return a decorator which runs + the wrapped function inside Timer's context manager. + Otherwise, treat the first argument as a 'msg' string and return an updated + Timer instance, referencing the same logger. + A 'level' keyword can also be passed to override self.level. + """ + if isinstance(func_or_msg, Callable): + func = func_or_msg + # use the function name when no explicit 'msg' is provided + if not self.msg: + self.msg = "run '%s'" % func.__name__ + + @wraps(func) + def wrapper(*args, **kwds): + with self: + return func(*args, **kwds) + + return wrapper + else: + msg = func_or_msg or kwargs.get("msg") + level = kwargs.get("level", self.level) + return self.__class__(self.logger, msg, level) + + def __float__(self): + return self.elapsed + + def __int__(self): + return int(self.elapsed) + + def __str__(self): + return "%.3f" % self.elapsed + + +class ChannelsFilter(logging.Filter): + """Provides a hierarchical filter for log entries based on channel names. + + Filters out records emitted from a list of enabled channel names, + including their children. It works the same as the ``logging.Filter`` + class, but allows the user to specify multiple channel names. + + >>> import sys + >>> handler = logging.StreamHandler(sys.stdout) + >>> handler.setFormatter(logging.Formatter("%(message)s")) + >>> filter = ChannelsFilter("A.B", "C.D") + >>> handler.addFilter(filter) + >>> root = logging.getLogger() + >>> root.addHandler(handler) + >>> root.setLevel(level=logging.DEBUG) + >>> logging.getLogger('A.B').debug('this record passes through') + this record passes through + >>> logging.getLogger('A.B.C').debug('records from children also pass') + records from children also pass + >>> logging.getLogger('C.D').debug('this one as well') + this one as well + >>> logging.getLogger('A.B.').debug('also this one') + also this one + >>> logging.getLogger('A.F').debug('but this one does not!') + >>> logging.getLogger('C.DE').debug('neither this one!') + """ + + def __init__(self, *names): + self.names = names + self.num = len(names) + self.lengths = {n: len(n) for n in names} + + def filter(self, record): + if self.num == 0: + return True + for name in self.names: + nlen = self.lengths[name] + if name == record.name: + return True + elif record.name.find(name, 0, nlen) == 0 and record.name[nlen] == ".": + return True + return False + + +class CapturingLogHandler(logging.Handler): + def __init__(self, logger, level): + super(CapturingLogHandler, self).__init__(level=level) + self.records = [] + if isinstance(logger, str): + self.logger = logging.getLogger(logger) + else: + self.logger = logger + + def __enter__(self): + self.original_disabled = self.logger.disabled + self.original_level = self.logger.level + self.original_propagate = self.logger.propagate + + self.logger.addHandler(self) + self.logger.setLevel(self.level) + self.logger.disabled = False + self.logger.propagate = False + + return self + + def __exit__(self, type, value, traceback): + self.logger.removeHandler(self) + self.logger.setLevel(self.original_level) + self.logger.disabled = self.original_disabled + self.logger.propagate = self.original_propagate + + return self + + def emit(self, record): + self.records.append(record) + + def assertRegex(self, regexp, msg=None): + import re + + pattern = re.compile(regexp) + for r in self.records: + if pattern.search(r.getMessage()): + return True + if msg is None: + msg = "Pattern '%s' not found in logger records" % regexp + assert 0, msg + + +class LogMixin(object): + """Mixin class that adds logging functionality to another class. + + You can define a new class that subclasses from ``LogMixin`` as well as + other base classes through multiple inheritance. + All instances of that class will have a ``log`` property that returns + a ``logging.Logger`` named after their respective ``.``. + + For example: + + >>> class BaseClass(object): + ... pass + >>> class MyClass(LogMixin, BaseClass): + ... pass + >>> a = MyClass() + >>> isinstance(a.log, logging.Logger) + True + >>> print(a.log.name) + fontTools.misc.loggingTools.MyClass + >>> class AnotherClass(MyClass): + ... pass + >>> b = AnotherClass() + >>> isinstance(b.log, logging.Logger) + True + >>> print(b.log.name) + fontTools.misc.loggingTools.AnotherClass + """ + + @property + def log(self): + if not hasattr(self, "_log"): + name = ".".join((self.__class__.__module__, self.__class__.__name__)) + self._log = logging.getLogger(name) + return self._log + + +def deprecateArgument(name, msg, category=UserWarning): + """Raise a warning about deprecated function argument 'name'.""" + warnings.warn("%r is deprecated; %s" % (name, msg), category=category, stacklevel=3) + + +def deprecateFunction(msg, category=UserWarning): + """Decorator to raise a warning when a deprecated function is called.""" + + def decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + warnings.warn( + "%r is deprecated; %s" % (func.__name__, msg), + category=category, + stacklevel=2, + ) + return func(*args, **kwargs) + + return wrapper + + return decorator + + +if __name__ == "__main__": + import doctest + + sys.exit(doctest.testmod(optionflags=doctest.ELLIPSIS).failed) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/macCreatorType.py b/.venv/lib/python3.13/site-packages/fontTools/misc/macCreatorType.py new file mode 100644 index 0000000000000000000000000000000000000000..36b15aca51c564c7a9c05ebfcff8f17925ec1630 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/macCreatorType.py @@ -0,0 +1,56 @@ +from fontTools.misc.textTools import Tag, bytesjoin, strjoin + +try: + import xattr +except ImportError: + xattr = None + + +def _reverseString(s): + s = list(s) + s.reverse() + return strjoin(s) + + +def getMacCreatorAndType(path): + """Returns file creator and file type codes for a path. + + Args: + path (str): A file path. + + Returns: + A tuple of two :py:class:`fontTools.textTools.Tag` objects, the first + representing the file creator and the second representing the + file type. + """ + if xattr is not None: + try: + finderInfo = xattr.getxattr(path, "com.apple.FinderInfo") + except (KeyError, IOError): + pass + else: + fileType = Tag(finderInfo[:4]) + fileCreator = Tag(finderInfo[4:8]) + return fileCreator, fileType + return None, None + + +def setMacCreatorAndType(path, fileCreator, fileType): + """Set file creator and file type codes for a path. + + Note that if the ``xattr`` module is not installed, no action is + taken but no error is raised. + + Args: + path (str): A file path. + fileCreator: A four-character file creator tag. + fileType: A four-character file type tag. + + """ + if xattr is not None: + from fontTools.misc.textTools import pad + + if not all(len(s) == 4 for s in (fileCreator, fileType)): + raise TypeError("arg must be string of 4 chars") + finderInfo = pad(bytesjoin([fileType, fileCreator]), 32) + xattr.setxattr(path, "com.apple.FinderInfo", finderInfo) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/macRes.py b/.venv/lib/python3.13/site-packages/fontTools/misc/macRes.py new file mode 100644 index 0000000000000000000000000000000000000000..f5a6cfe4789a351204d0ce6fa2abb5651487c5c0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/macRes.py @@ -0,0 +1,261 @@ +from io import BytesIO +import struct +from fontTools.misc import sstruct +from fontTools.misc.textTools import bytesjoin, tostr +from collections import OrderedDict +from collections.abc import MutableMapping + + +class ResourceError(Exception): + pass + + +class ResourceReader(MutableMapping): + """Reader for Mac OS resource forks. + + Parses a resource fork and returns resources according to their type. + If run on OS X, this will open the resource fork in the filesystem. + Otherwise, it will open the file itself and attempt to read it as + though it were a resource fork. + + The returned object can be indexed by type and iterated over, + returning in each case a list of py:class:`Resource` objects + representing all the resources of a certain type. + + """ + + def __init__(self, fileOrPath): + """Open a file + + Args: + fileOrPath: Either an object supporting a ``read`` method, an + ``os.PathLike`` object, or a string. + """ + self._resources = OrderedDict() + if hasattr(fileOrPath, "read"): + self.file = fileOrPath + else: + try: + # try reading from the resource fork (only works on OS X) + self.file = self.openResourceFork(fileOrPath) + self._readFile() + return + except (ResourceError, IOError): + # if it fails, use the data fork + self.file = self.openDataFork(fileOrPath) + self._readFile() + + @staticmethod + def openResourceFork(path): + if hasattr(path, "__fspath__"): # support os.PathLike objects + path = path.__fspath__() + with open(path + "/..namedfork/rsrc", "rb") as resfork: + data = resfork.read() + infile = BytesIO(data) + infile.name = path + return infile + + @staticmethod + def openDataFork(path): + with open(path, "rb") as datafork: + data = datafork.read() + infile = BytesIO(data) + infile.name = path + return infile + + def _readFile(self): + self._readHeaderAndMap() + self._readTypeList() + + def _read(self, numBytes, offset=None): + if offset is not None: + try: + self.file.seek(offset) + except OverflowError: + raise ResourceError("Failed to seek offset ('offset' is too large)") + if self.file.tell() != offset: + raise ResourceError("Failed to seek offset (reached EOF)") + try: + data = self.file.read(numBytes) + except OverflowError: + raise ResourceError("Cannot read resource ('numBytes' is too large)") + if len(data) != numBytes: + raise ResourceError("Cannot read resource (not enough data)") + return data + + def _readHeaderAndMap(self): + self.file.seek(0) + headerData = self._read(ResourceForkHeaderSize) + sstruct.unpack(ResourceForkHeader, headerData, self) + # seek to resource map, skip reserved + mapOffset = self.mapOffset + 22 + resourceMapData = self._read(ResourceMapHeaderSize, mapOffset) + sstruct.unpack(ResourceMapHeader, resourceMapData, self) + self.absTypeListOffset = self.mapOffset + self.typeListOffset + self.absNameListOffset = self.mapOffset + self.nameListOffset + + def _readTypeList(self): + absTypeListOffset = self.absTypeListOffset + numTypesData = self._read(2, absTypeListOffset) + (self.numTypes,) = struct.unpack(">H", numTypesData) + absTypeListOffset2 = absTypeListOffset + 2 + for i in range(self.numTypes + 1): + resTypeItemOffset = absTypeListOffset2 + ResourceTypeItemSize * i + resTypeItemData = self._read(ResourceTypeItemSize, resTypeItemOffset) + item = sstruct.unpack(ResourceTypeItem, resTypeItemData) + resType = tostr(item["type"], encoding="mac-roman") + refListOffset = absTypeListOffset + item["refListOffset"] + numRes = item["numRes"] + 1 + resources = self._readReferenceList(resType, refListOffset, numRes) + self._resources[resType] = resources + + def _readReferenceList(self, resType, refListOffset, numRes): + resources = [] + for i in range(numRes): + refOffset = refListOffset + ResourceRefItemSize * i + refData = self._read(ResourceRefItemSize, refOffset) + res = Resource(resType) + res.decompile(refData, self) + resources.append(res) + return resources + + def __getitem__(self, resType): + return self._resources[resType] + + def __delitem__(self, resType): + del self._resources[resType] + + def __setitem__(self, resType, resources): + self._resources[resType] = resources + + def __len__(self): + return len(self._resources) + + def __iter__(self): + return iter(self._resources) + + def keys(self): + return self._resources.keys() + + @property + def types(self): + """A list of the types of resources in the resource fork.""" + return list(self._resources.keys()) + + def countResources(self, resType): + """Return the number of resources of a given type.""" + try: + return len(self[resType]) + except KeyError: + return 0 + + def getIndices(self, resType): + """Returns a list of indices of resources of a given type.""" + numRes = self.countResources(resType) + if numRes: + return list(range(1, numRes + 1)) + else: + return [] + + def getNames(self, resType): + """Return list of names of all resources of a given type.""" + return [res.name for res in self.get(resType, []) if res.name is not None] + + def getIndResource(self, resType, index): + """Return resource of given type located at an index ranging from 1 + to the number of resources for that type, or None if not found. + """ + if index < 1: + return None + try: + res = self[resType][index - 1] + except (KeyError, IndexError): + return None + return res + + def getNamedResource(self, resType, name): + """Return the named resource of given type, else return None.""" + name = tostr(name, encoding="mac-roman") + for res in self.get(resType, []): + if res.name == name: + return res + return None + + def close(self): + if not self.file.closed: + self.file.close() + + +class Resource(object): + """Represents a resource stored within a resource fork. + + Attributes: + type: resource type. + data: resource data. + id: ID. + name: resource name. + attr: attributes. + """ + + def __init__( + self, resType=None, resData=None, resID=None, resName=None, resAttr=None + ): + self.type = resType + self.data = resData + self.id = resID + self.name = resName + self.attr = resAttr + + def decompile(self, refData, reader): + sstruct.unpack(ResourceRefItem, refData, self) + # interpret 3-byte dataOffset as (padded) ULONG to unpack it with struct + (self.dataOffset,) = struct.unpack(">L", bytesjoin([b"\0", self.dataOffset])) + absDataOffset = reader.dataOffset + self.dataOffset + (dataLength,) = struct.unpack(">L", reader._read(4, absDataOffset)) + self.data = reader._read(dataLength) + if self.nameOffset == -1: + return + absNameOffset = reader.absNameListOffset + self.nameOffset + (nameLength,) = struct.unpack("B", reader._read(1, absNameOffset)) + (name,) = struct.unpack(">%ss" % nameLength, reader._read(nameLength)) + self.name = tostr(name, encoding="mac-roman") + + +ResourceForkHeader = """ + > # big endian + dataOffset: L + mapOffset: L + dataLen: L + mapLen: L +""" + +ResourceForkHeaderSize = sstruct.calcsize(ResourceForkHeader) + +ResourceMapHeader = """ + > # big endian + attr: H + typeListOffset: H + nameListOffset: H +""" + +ResourceMapHeaderSize = sstruct.calcsize(ResourceMapHeader) + +ResourceTypeItem = """ + > # big endian + type: 4s + numRes: H + refListOffset: H +""" + +ResourceTypeItemSize = sstruct.calcsize(ResourceTypeItem) + +ResourceRefItem = """ + > # big endian + id: h + nameOffset: h + attr: B + dataOffset: 3s + reserved: L +""" + +ResourceRefItemSize = sstruct.calcsize(ResourceRefItem) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/plistlib/__init__.py b/.venv/lib/python3.13/site-packages/fontTools/misc/plistlib/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..066eef38fc720265366afee9a8cd415fc560459e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/plistlib/__init__.py @@ -0,0 +1,681 @@ +import collections.abc +import re +from typing import ( + Any, + Callable, + Dict, + List, + Mapping, + MutableMapping, + Optional, + Sequence, + Type, + Union, + IO, +) +import warnings +from io import BytesIO +from datetime import datetime +from base64 import b64encode, b64decode +from numbers import Integral +from types import SimpleNamespace +from functools import singledispatch + +from fontTools.misc import etree + +from fontTools.misc.textTools import tostr + + +# By default, we +# - deserialize elements as bytes and +# - serialize bytes as elements. +# Before, on Python 2, we +# - deserialized elements as plistlib.Data objects, in order to +# distinguish them from the built-in str type (which is bytes on python2) +# - serialized bytes as elements (they must have only contained +# ASCII characters in this case) +# You can pass use_builtin_types=[True|False] to the load/dump etc. functions +# to enforce a specific treatment. +# NOTE that unicode type always maps to element, and plistlib.Data +# always maps to element, regardless of use_builtin_types. +USE_BUILTIN_TYPES = True + +XML_DECLARATION = b"""""" + +PLIST_DOCTYPE = ( + b'' +) + + +# Date should conform to a subset of ISO 8601: +# YYYY '-' MM '-' DD 'T' HH ':' MM ':' SS 'Z' +_date_parser = re.compile( + r"(?P\d\d\d\d)" + r"(?:-(?P\d\d)" + r"(?:-(?P\d\d)" + r"(?:T(?P\d\d)" + r"(?::(?P\d\d)" + r"(?::(?P\d\d))" + r"?)?)?)?)?Z", + re.ASCII, +) + + +def _date_from_string(s: str) -> datetime: + order = ("year", "month", "day", "hour", "minute", "second") + m = _date_parser.match(s) + if m is None: + raise ValueError(f"Expected ISO 8601 date string, but got '{s:r}'.") + gd = m.groupdict() + lst = [] + for key in order: + val = gd[key] + if val is None: + break + lst.append(int(val)) + # NOTE: mypy doesn't know that lst is 6 elements long. + return datetime(*lst) # type:ignore + + +def _date_to_string(d: datetime) -> str: + return "%04d-%02d-%02dT%02d:%02d:%02dZ" % ( + d.year, + d.month, + d.day, + d.hour, + d.minute, + d.second, + ) + + +class Data: + """Represents binary data when ``use_builtin_types=False.`` + + This class wraps binary data loaded from a plist file when the + ``use_builtin_types`` argument to the loading function (:py:func:`fromtree`, + :py:func:`load`, :py:func:`loads`) is false. + + The actual binary data is retrieved using the ``data`` attribute. + """ + + def __init__(self, data: bytes) -> None: + if not isinstance(data, bytes): + raise TypeError("Expected bytes, found %s" % type(data).__name__) + self.data = data + + @classmethod + def fromBase64(cls, data: Union[bytes, str]) -> "Data": + return cls(b64decode(data)) + + def asBase64(self, maxlinelength: int = 76, indent_level: int = 1) -> bytes: + return _encode_base64( + self.data, maxlinelength=maxlinelength, indent_level=indent_level + ) + + def __eq__(self, other: Any) -> bool: + if isinstance(other, self.__class__): + return self.data == other.data + elif isinstance(other, bytes): + return self.data == other + else: + return NotImplemented + + def __repr__(self) -> str: + return "%s(%s)" % (self.__class__.__name__, repr(self.data)) + + +def _encode_base64( + data: bytes, maxlinelength: Optional[int] = 76, indent_level: int = 1 +) -> bytes: + data = b64encode(data) + if data and maxlinelength: + # split into multiple lines right-justified to 'maxlinelength' chars + indent = b"\n" + b" " * indent_level + max_length = max(16, maxlinelength - len(indent)) + chunks = [] + for i in range(0, len(data), max_length): + chunks.append(indent) + chunks.append(data[i : i + max_length]) + chunks.append(indent) + data = b"".join(chunks) + return data + + +# Mypy does not support recursive type aliases as of 0.782, Pylance does. +# https://github.com/python/mypy/issues/731 +# https://devblogs.microsoft.com/python/pylance-introduces-five-new-features-that-enable-type-magic-for-python-developers/#1-support-for-recursive-type-aliases +PlistEncodable = Union[ + bool, + bytes, + Data, + datetime, + float, + Integral, + Mapping[str, Any], + Sequence[Any], + str, +] + + +class PlistTarget: + """Event handler using the ElementTree Target API that can be + passed to a XMLParser to produce property list objects from XML. + It is based on the CPython plistlib module's _PlistParser class, + but does not use the expat parser. + + >>> from fontTools.misc import etree + >>> parser = etree.XMLParser(target=PlistTarget()) + >>> result = etree.XML( + ... "" + ... " something" + ... " blah" + ... "", + ... parser=parser) + >>> result == {"something": "blah"} + True + + Links: + https://github.com/python/cpython/blob/main/Lib/plistlib.py + http://lxml.de/parsing.html#the-target-parser-interface + """ + + def __init__( + self, + use_builtin_types: Optional[bool] = None, + dict_type: Type[MutableMapping[str, Any]] = dict, + ) -> None: + self.stack: List[PlistEncodable] = [] + self.current_key: Optional[str] = None + self.root: Optional[PlistEncodable] = None + if use_builtin_types is None: + self._use_builtin_types = USE_BUILTIN_TYPES + else: + if use_builtin_types is False: + warnings.warn( + "Setting use_builtin_types to False is deprecated and will be " + "removed soon.", + DeprecationWarning, + ) + self._use_builtin_types = use_builtin_types + self._dict_type = dict_type + + def start(self, tag: str, attrib: Mapping[str, str]) -> None: + self._data: List[str] = [] + handler = _TARGET_START_HANDLERS.get(tag) + if handler is not None: + handler(self) + + def end(self, tag: str) -> None: + handler = _TARGET_END_HANDLERS.get(tag) + if handler is not None: + handler(self) + + def data(self, data: str) -> None: + self._data.append(data) + + def close(self) -> PlistEncodable: + if self.root is None: + raise ValueError("No root set.") + return self.root + + # helpers + + def add_object(self, value: PlistEncodable) -> None: + if self.current_key is not None: + stack_top = self.stack[-1] + if not isinstance(stack_top, collections.abc.MutableMapping): + raise ValueError("unexpected element: %r" % stack_top) + stack_top[self.current_key] = value + self.current_key = None + elif not self.stack: + # this is the root object + self.root = value + else: + stack_top = self.stack[-1] + if not isinstance(stack_top, list): + raise ValueError("unexpected element: %r" % stack_top) + stack_top.append(value) + + def get_data(self) -> str: + data = "".join(self._data) + self._data = [] + return data + + +# event handlers + + +def start_dict(self: PlistTarget) -> None: + d = self._dict_type() + self.add_object(d) + self.stack.append(d) + + +def end_dict(self: PlistTarget) -> None: + if self.current_key: + raise ValueError("missing value for key '%s'" % self.current_key) + self.stack.pop() + + +def end_key(self: PlistTarget) -> None: + if self.current_key or not isinstance(self.stack[-1], collections.abc.Mapping): + raise ValueError("unexpected key") + self.current_key = self.get_data() + + +def start_array(self: PlistTarget) -> None: + a: List[PlistEncodable] = [] + self.add_object(a) + self.stack.append(a) + + +def end_array(self: PlistTarget) -> None: + self.stack.pop() + + +def end_true(self: PlistTarget) -> None: + self.add_object(True) + + +def end_false(self: PlistTarget) -> None: + self.add_object(False) + + +def end_integer(self: PlistTarget) -> None: + self.add_object(int(self.get_data())) + + +def end_real(self: PlistTarget) -> None: + self.add_object(float(self.get_data())) + + +def end_string(self: PlistTarget) -> None: + self.add_object(self.get_data()) + + +def end_data(self: PlistTarget) -> None: + if self._use_builtin_types: + self.add_object(b64decode(self.get_data())) + else: + self.add_object(Data.fromBase64(self.get_data())) + + +def end_date(self: PlistTarget) -> None: + self.add_object(_date_from_string(self.get_data())) + + +_TARGET_START_HANDLERS: Dict[str, Callable[[PlistTarget], None]] = { + "dict": start_dict, + "array": start_array, +} + +_TARGET_END_HANDLERS: Dict[str, Callable[[PlistTarget], None]] = { + "dict": end_dict, + "array": end_array, + "key": end_key, + "true": end_true, + "false": end_false, + "integer": end_integer, + "real": end_real, + "string": end_string, + "data": end_data, + "date": end_date, +} + + +# functions to build element tree from plist data + + +def _string_element(value: str, ctx: SimpleNamespace) -> etree.Element: + el = etree.Element("string") + el.text = value + return el + + +def _bool_element(value: bool, ctx: SimpleNamespace) -> etree.Element: + if value: + return etree.Element("true") + return etree.Element("false") + + +def _integer_element(value: int, ctx: SimpleNamespace) -> etree.Element: + if -1 << 63 <= value < 1 << 64: + el = etree.Element("integer") + el.text = "%d" % value + return el + raise OverflowError(value) + + +def _real_element(value: float, ctx: SimpleNamespace) -> etree.Element: + el = etree.Element("real") + el.text = repr(value) + return el + + +def _dict_element( + d: Mapping[str, PlistEncodable], ctx: SimpleNamespace +) -> etree.Element: + el = etree.Element("dict") + items = d.items() + if ctx.sort_keys: + items = sorted(items) # type: ignore + ctx.indent_level += 1 + for key, value in items: + if not isinstance(key, str): + if ctx.skipkeys: + continue + raise TypeError("keys must be strings") + k = etree.SubElement(el, "key") + k.text = tostr(key, "utf-8") + el.append(_make_element(value, ctx)) + ctx.indent_level -= 1 + return el + + +def _array_element( + array: Sequence[PlistEncodable], ctx: SimpleNamespace +) -> etree.Element: + el = etree.Element("array") + if len(array) == 0: + return el + ctx.indent_level += 1 + for value in array: + el.append(_make_element(value, ctx)) + ctx.indent_level -= 1 + return el + + +def _date_element(date: datetime, ctx: SimpleNamespace) -> etree.Element: + el = etree.Element("date") + el.text = _date_to_string(date) + return el + + +def _data_element(data: bytes, ctx: SimpleNamespace) -> etree.Element: + el = etree.Element("data") + # NOTE: mypy is confused about whether el.text should be str or bytes. + el.text = _encode_base64( # type: ignore + data, + maxlinelength=(76 if ctx.pretty_print else None), + indent_level=ctx.indent_level, + ) + return el + + +def _string_or_data_element(raw_bytes: bytes, ctx: SimpleNamespace) -> etree.Element: + if ctx.use_builtin_types: + return _data_element(raw_bytes, ctx) + else: + try: + string = raw_bytes.decode(encoding="ascii", errors="strict") + except UnicodeDecodeError: + raise ValueError( + "invalid non-ASCII bytes; use unicode string instead: %r" % raw_bytes + ) + return _string_element(string, ctx) + + +# The following is probably not entirely correct. The signature should take `Any` +# and return `NoReturn`. At the time of this writing, neither mypy nor Pyright +# can deal with singledispatch properly and will apply the signature of the base +# function to all others. Being slightly dishonest makes it type-check and return +# usable typing information for the optimistic case. +@singledispatch +def _make_element(value: PlistEncodable, ctx: SimpleNamespace) -> etree.Element: + raise TypeError("unsupported type: %s" % type(value)) + + +_make_element.register(str)(_string_element) +_make_element.register(bool)(_bool_element) +_make_element.register(Integral)(_integer_element) +_make_element.register(float)(_real_element) +_make_element.register(collections.abc.Mapping)(_dict_element) +_make_element.register(list)(_array_element) +_make_element.register(tuple)(_array_element) +_make_element.register(datetime)(_date_element) +_make_element.register(bytes)(_string_or_data_element) +_make_element.register(bytearray)(_data_element) +_make_element.register(Data)(lambda v, ctx: _data_element(v.data, ctx)) + + +# Public functions to create element tree from plist-compatible python +# data structures and viceversa, for use when (de)serializing GLIF xml. + + +def totree( + value: PlistEncodable, + sort_keys: bool = True, + skipkeys: bool = False, + use_builtin_types: Optional[bool] = None, + pretty_print: bool = True, + indent_level: int = 1, +) -> etree.Element: + """Convert a value derived from a plist into an XML tree. + + Args: + value: Any kind of value to be serialized to XML. + sort_keys: Whether keys of dictionaries should be sorted. + skipkeys (bool): Whether to silently skip non-string dictionary + keys. + use_builtin_types (bool): If true, byte strings will be + encoded in Base-64 and wrapped in a ``data`` tag; if + false, they will be either stored as ASCII strings or an + exception raised if they cannot be decoded as such. Defaults + to ``True`` if not present. Deprecated. + pretty_print (bool): Whether to indent the output. + indent_level (int): Level of indentation when serializing. + + Returns: an ``etree`` ``Element`` object. + + Raises: + ``TypeError`` + if non-string dictionary keys are serialized + and ``skipkeys`` is false. + ``ValueError`` + if non-ASCII binary data is present + and `use_builtin_types` is false. + """ + if use_builtin_types is None: + use_builtin_types = USE_BUILTIN_TYPES + else: + use_builtin_types = use_builtin_types + context = SimpleNamespace( + sort_keys=sort_keys, + skipkeys=skipkeys, + use_builtin_types=use_builtin_types, + pretty_print=pretty_print, + indent_level=indent_level, + ) + return _make_element(value, context) + + +def fromtree( + tree: etree.Element, + use_builtin_types: Optional[bool] = None, + dict_type: Type[MutableMapping[str, Any]] = dict, +) -> Any: + """Convert an XML tree to a plist structure. + + Args: + tree: An ``etree`` ``Element``. + use_builtin_types: If True, binary data is deserialized to + bytes strings. If False, it is wrapped in :py:class:`Data` + objects. Defaults to True if not provided. Deprecated. + dict_type: What type to use for dictionaries. + + Returns: An object (usually a dictionary). + """ + target = PlistTarget(use_builtin_types=use_builtin_types, dict_type=dict_type) + for action, element in etree.iterwalk(tree, events=("start", "end")): + if action == "start": + target.start(element.tag, element.attrib) + elif action == "end": + # if there are no children, parse the leaf's data + if not len(element): + # always pass str, not None + target.data(element.text or "") + target.end(element.tag) + return target.close() + + +# python3 plistlib API + + +def load( + fp: IO[bytes], + use_builtin_types: Optional[bool] = None, + dict_type: Type[MutableMapping[str, Any]] = dict, +) -> Any: + """Load a plist file into an object. + + Args: + fp: An opened file. + use_builtin_types: If True, binary data is deserialized to + bytes strings. If False, it is wrapped in :py:class:`Data` + objects. Defaults to True if not provided. Deprecated. + dict_type: What type to use for dictionaries. + + Returns: + An object (usually a dictionary) representing the top level of + the plist file. + """ + + if not hasattr(fp, "read"): + raise AttributeError("'%s' object has no attribute 'read'" % type(fp).__name__) + target = PlistTarget(use_builtin_types=use_builtin_types, dict_type=dict_type) + parser = etree.XMLParser(target=target) + result = etree.parse(fp, parser=parser) + # lxml returns the target object directly, while ElementTree wraps + # it as the root of an ElementTree object + try: + return result.getroot() + except AttributeError: + return result + + +def loads( + value: bytes, + use_builtin_types: Optional[bool] = None, + dict_type: Type[MutableMapping[str, Any]] = dict, +) -> Any: + """Load a plist file from a string into an object. + + Args: + value: A bytes string containing a plist. + use_builtin_types: If True, binary data is deserialized to + bytes strings. If False, it is wrapped in :py:class:`Data` + objects. Defaults to True if not provided. Deprecated. + dict_type: What type to use for dictionaries. + + Returns: + An object (usually a dictionary) representing the top level of + the plist file. + """ + + fp = BytesIO(value) + return load(fp, use_builtin_types=use_builtin_types, dict_type=dict_type) + + +def dump( + value: PlistEncodable, + fp: IO[bytes], + sort_keys: bool = True, + skipkeys: bool = False, + use_builtin_types: Optional[bool] = None, + pretty_print: bool = True, +) -> None: + """Write a Python object to a plist file. + + Args: + value: An object to write. + fp: A file opened for writing. + sort_keys (bool): Whether keys of dictionaries should be sorted. + skipkeys (bool): Whether to silently skip non-string dictionary + keys. + use_builtin_types (bool): If true, byte strings will be + encoded in Base-64 and wrapped in a ``data`` tag; if + false, they will be either stored as ASCII strings or an + exception raised if they cannot be represented. Defaults + pretty_print (bool): Whether to indent the output. + indent_level (int): Level of indentation when serializing. + + Raises: + ``TypeError`` + if non-string dictionary keys are serialized + and ``skipkeys`` is false. + ``ValueError`` + if non-representable binary data is present + and `use_builtin_types` is false. + """ + + if not hasattr(fp, "write"): + raise AttributeError("'%s' object has no attribute 'write'" % type(fp).__name__) + root = etree.Element("plist", version="1.0") + el = totree( + value, + sort_keys=sort_keys, + skipkeys=skipkeys, + use_builtin_types=use_builtin_types, + pretty_print=pretty_print, + ) + root.append(el) + tree = etree.ElementTree(root) + # we write the doctype ourselves instead of using the 'doctype' argument + # of 'write' method, becuse lxml will force adding a '\n' even when + # pretty_print is False. + if pretty_print: + header = b"\n".join((XML_DECLARATION, PLIST_DOCTYPE, b"")) + else: + header = XML_DECLARATION + PLIST_DOCTYPE + fp.write(header) + tree.write( # type: ignore + fp, + encoding="utf-8", + pretty_print=pretty_print, + xml_declaration=False, + ) + + +def dumps( + value: PlistEncodable, + sort_keys: bool = True, + skipkeys: bool = False, + use_builtin_types: Optional[bool] = None, + pretty_print: bool = True, +) -> bytes: + """Write a Python object to a string in plist format. + + Args: + value: An object to write. + sort_keys (bool): Whether keys of dictionaries should be sorted. + skipkeys (bool): Whether to silently skip non-string dictionary + keys. + use_builtin_types (bool): If true, byte strings will be + encoded in Base-64 and wrapped in a ``data`` tag; if + false, they will be either stored as strings or an + exception raised if they cannot be represented. Defaults + pretty_print (bool): Whether to indent the output. + indent_level (int): Level of indentation when serializing. + + Returns: + string: A plist representation of the Python object. + + Raises: + ``TypeError`` + if non-string dictionary keys are serialized + and ``skipkeys`` is false. + ``ValueError`` + if non-representable binary data is present + and `use_builtin_types` is false. + """ + fp = BytesIO() + dump( + value, + fp, + sort_keys=sort_keys, + skipkeys=skipkeys, + use_builtin_types=use_builtin_types, + pretty_print=pretty_print, + ) + return fp.getvalue() diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/plistlib/py.typed b/.venv/lib/python3.13/site-packages/fontTools/misc/plistlib/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/psCharStrings.py b/.venv/lib/python3.13/site-packages/fontTools/misc/psCharStrings.py new file mode 100644 index 0000000000000000000000000000000000000000..db837248dea6525c87beee5c3a860d86e41fe44a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/psCharStrings.py @@ -0,0 +1,1511 @@ +"""psCharStrings.py -- module implementing various kinds of CharStrings: +CFF dictionary data and Type1/Type2 CharStrings. +""" + +from fontTools.misc.fixedTools import ( + fixedToFloat, + floatToFixed, + floatToFixedToStr, + strToFixedToFloat, +) +from fontTools.misc.textTools import bytechr, byteord, bytesjoin, strjoin +from fontTools.pens.boundsPen import BoundsPen +import struct +import logging + + +log = logging.getLogger(__name__) + + +def read_operator(self, b0, data, index): + if b0 == 12: + op = (b0, byteord(data[index])) + index = index + 1 + else: + op = b0 + try: + operator = self.operators[op] + except KeyError: + return None, index + value = self.handle_operator(operator) + return value, index + + +def read_byte(self, b0, data, index): + return b0 - 139, index + + +def read_smallInt1(self, b0, data, index): + b1 = byteord(data[index]) + return (b0 - 247) * 256 + b1 + 108, index + 1 + + +def read_smallInt2(self, b0, data, index): + b1 = byteord(data[index]) + return -(b0 - 251) * 256 - b1 - 108, index + 1 + + +def read_shortInt(self, b0, data, index): + (value,) = struct.unpack(">h", data[index : index + 2]) + return value, index + 2 + + +def read_longInt(self, b0, data, index): + (value,) = struct.unpack(">l", data[index : index + 4]) + return value, index + 4 + + +def read_fixed1616(self, b0, data, index): + (value,) = struct.unpack(">l", data[index : index + 4]) + return fixedToFloat(value, precisionBits=16), index + 4 + + +def read_reserved(self, b0, data, index): + assert NotImplementedError + return NotImplemented, index + + +def read_realNumber(self, b0, data, index): + number = "" + while True: + b = byteord(data[index]) + index = index + 1 + nibble0 = (b & 0xF0) >> 4 + nibble1 = b & 0x0F + if nibble0 == 0xF: + break + number = number + realNibbles[nibble0] + if nibble1 == 0xF: + break + number = number + realNibbles[nibble1] + return float(number), index + + +t1OperandEncoding = [None] * 256 +t1OperandEncoding[0:32] = (32) * [read_operator] +t1OperandEncoding[32:247] = (247 - 32) * [read_byte] +t1OperandEncoding[247:251] = (251 - 247) * [read_smallInt1] +t1OperandEncoding[251:255] = (255 - 251) * [read_smallInt2] +t1OperandEncoding[255] = read_longInt +assert len(t1OperandEncoding) == 256 + +t2OperandEncoding = t1OperandEncoding[:] +t2OperandEncoding[28] = read_shortInt +t2OperandEncoding[255] = read_fixed1616 + +cffDictOperandEncoding = t2OperandEncoding[:] +cffDictOperandEncoding[29] = read_longInt +cffDictOperandEncoding[30] = read_realNumber +cffDictOperandEncoding[255] = read_reserved + + +realNibbles = [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + ".", + "E", + "E-", + None, + "-", +] +realNibblesDict = {v: i for i, v in enumerate(realNibbles)} + +maxOpStack = 193 + + +def buildOperatorDict(operatorList): + oper = {} + opc = {} + for item in operatorList: + if len(item) == 2: + oper[item[0]] = item[1] + else: + oper[item[0]] = item[1:] + if isinstance(item[0], tuple): + opc[item[1]] = item[0] + else: + opc[item[1]] = (item[0],) + return oper, opc + + +t2Operators = [ + # opcode name + (1, "hstem"), + (3, "vstem"), + (4, "vmoveto"), + (5, "rlineto"), + (6, "hlineto"), + (7, "vlineto"), + (8, "rrcurveto"), + (10, "callsubr"), + (11, "return"), + (14, "endchar"), + (15, "vsindex"), + (16, "blend"), + (18, "hstemhm"), + (19, "hintmask"), + (20, "cntrmask"), + (21, "rmoveto"), + (22, "hmoveto"), + (23, "vstemhm"), + (24, "rcurveline"), + (25, "rlinecurve"), + (26, "vvcurveto"), + (27, "hhcurveto"), + # (28, 'shortint'), # not really an operator + (29, "callgsubr"), + (30, "vhcurveto"), + (31, "hvcurveto"), + ((12, 0), "ignore"), # dotsection. Yes, there a few very early OTF/CFF + # fonts with this deprecated operator. Just ignore it. + ((12, 3), "and"), + ((12, 4), "or"), + ((12, 5), "not"), + ((12, 8), "store"), + ((12, 9), "abs"), + ((12, 10), "add"), + ((12, 11), "sub"), + ((12, 12), "div"), + ((12, 13), "load"), + ((12, 14), "neg"), + ((12, 15), "eq"), + ((12, 18), "drop"), + ((12, 20), "put"), + ((12, 21), "get"), + ((12, 22), "ifelse"), + ((12, 23), "random"), + ((12, 24), "mul"), + ((12, 26), "sqrt"), + ((12, 27), "dup"), + ((12, 28), "exch"), + ((12, 29), "index"), + ((12, 30), "roll"), + ((12, 34), "hflex"), + ((12, 35), "flex"), + ((12, 36), "hflex1"), + ((12, 37), "flex1"), +] + + +def getIntEncoder(format): + if format == "cff": + twoByteOp = bytechr(28) + fourByteOp = bytechr(29) + elif format == "t1": + twoByteOp = None + fourByteOp = bytechr(255) + else: + assert format == "t2" + twoByteOp = bytechr(28) + fourByteOp = None + + def encodeInt( + value, + fourByteOp=fourByteOp, + bytechr=bytechr, + pack=struct.pack, + unpack=struct.unpack, + twoByteOp=twoByteOp, + ): + if -107 <= value <= 107: + code = bytechr(value + 139) + elif 108 <= value <= 1131: + value = value - 108 + code = bytechr((value >> 8) + 247) + bytechr(value & 0xFF) + elif -1131 <= value <= -108: + value = -value - 108 + code = bytechr((value >> 8) + 251) + bytechr(value & 0xFF) + elif twoByteOp is not None and -32768 <= value <= 32767: + code = twoByteOp + pack(">h", value) + elif fourByteOp is None: + # Backwards compatible hack: due to a previous bug in FontTools, + # 16.16 fixed numbers were written out as 4-byte ints. When + # these numbers were small, they were wrongly written back as + # small ints instead of 4-byte ints, breaking round-tripping. + # This here workaround doesn't do it any better, since we can't + # distinguish anymore between small ints that were supposed to + # be small fixed numbers and small ints that were just small + # ints. Hence the warning. + log.warning( + "4-byte T2 number got passed to the " + "IntType handler. This should happen only when reading in " + "old XML files.\n" + ) + code = bytechr(255) + pack(">l", value) + else: + code = fourByteOp + pack(">l", value) + return code + + return encodeInt + + +encodeIntCFF = getIntEncoder("cff") +encodeIntT1 = getIntEncoder("t1") +encodeIntT2 = getIntEncoder("t2") + + +def encodeFixed(f, pack=struct.pack): + """For T2 only""" + value = floatToFixed(f, precisionBits=16) + if value & 0xFFFF == 0: # check if the fractional part is zero + return encodeIntT2(value >> 16) # encode only the integer part + else: + return b"\xff" + pack(">l", value) # encode the entire fixed point value + + +realZeroBytes = bytechr(30) + bytechr(0xF) + + +def encodeFloat(f): + # For CFF only, used in cffLib + if f == 0.0: # 0.0 == +0.0 == -0.0 + return realZeroBytes + # Note: 14 decimal digits seems to be the limitation for CFF real numbers + # in macOS. However, we use 8 here to match the implementation of AFDKO. + s = "%.8G" % f + if s[:2] == "0.": + s = s[1:] + elif s[:3] == "-0.": + s = "-" + s[2:] + elif s.endswith("000"): + significantDigits = s.rstrip("0") + s = "%sE%d" % (significantDigits, len(s) - len(significantDigits)) + else: + dotIndex = s.find(".") + eIndex = s.find("E") + if dotIndex != -1 and eIndex != -1: + integerPart = s[:dotIndex] + fractionalPart = s[dotIndex + 1 : eIndex] + exponent = int(s[eIndex + 1 :]) + newExponent = exponent - len(fractionalPart) + if newExponent == 1: + s = "%s%s0" % (integerPart, fractionalPart) + else: + s = "%s%sE%d" % (integerPart, fractionalPart, newExponent) + if s.startswith((".0", "-.0")): + sign, s = s.split(".", 1) + s = "%s%sE-%d" % (sign, s.lstrip("0"), len(s)) + nibbles = [] + while s: + c = s[0] + s = s[1:] + if c == "E": + c2 = s[:1] + if c2 == "-": + s = s[1:] + c = "E-" + elif c2 == "+": + s = s[1:] + if s.startswith("0"): + s = s[1:] + nibbles.append(realNibblesDict[c]) + nibbles.append(0xF) + if len(nibbles) % 2: + nibbles.append(0xF) + d = bytechr(30) + for i in range(0, len(nibbles), 2): + d = d + bytechr(nibbles[i] << 4 | nibbles[i + 1]) + return d + + +class CharStringCompileError(Exception): + pass + + +class SimpleT2Decompiler(object): + def __init__(self, localSubrs, globalSubrs, private=None, blender=None): + self.localSubrs = localSubrs + self.localBias = calcSubrBias(localSubrs) + self.globalSubrs = globalSubrs + self.globalBias = calcSubrBias(globalSubrs) + self.private = private + self.blender = blender + self.reset() + + def reset(self): + self.callingStack = [] + self.operandStack = [] + self.hintCount = 0 + self.hintMaskBytes = 0 + self.numRegions = 0 + self.vsIndex = 0 + + def execute(self, charString, *, pushToStack=None): + self.callingStack.append(charString) + needsDecompilation = charString.needsDecompilation() + if needsDecompilation: + program = [] + pushToProgram = program.append + else: + pushToProgram = lambda x: None + if pushToStack is None: + pushToStack = self.operandStack.append + index = 0 + while True: + token, isOperator, index = charString.getToken(index) + if token is None: + break # we're done! + pushToProgram(token) + if isOperator: + handlerName = "op_" + token + handler = getattr(self, handlerName, None) + if handler is not None: + rv = handler(index) + if rv: + hintMaskBytes, index = rv + pushToProgram(hintMaskBytes) + else: + self.popall() + else: + pushToStack(token) + if needsDecompilation: + charString.setProgram(program) + del self.callingStack[-1] + + def pop(self): + value = self.operandStack[-1] + del self.operandStack[-1] + return value + + def popall(self): + stack = self.operandStack[:] + self.operandStack[:] = [] + return stack + + def push(self, value): + self.operandStack.append(value) + + def op_return(self, index): + if self.operandStack: + pass + + def op_endchar(self, index): + pass + + def op_ignore(self, index): + pass + + def op_callsubr(self, index): + subrIndex = self.pop() + subr = self.localSubrs[subrIndex + self.localBias] + self.execute(subr) + + def op_callgsubr(self, index): + subrIndex = self.pop() + subr = self.globalSubrs[subrIndex + self.globalBias] + self.execute(subr) + + def op_hstem(self, index): + self.countHints() + + def op_vstem(self, index): + self.countHints() + + def op_hstemhm(self, index): + self.countHints() + + def op_vstemhm(self, index): + self.countHints() + + def op_hintmask(self, index): + if not self.hintMaskBytes: + self.countHints() + self.hintMaskBytes = (self.hintCount + 7) // 8 + hintMaskBytes, index = self.callingStack[-1].getBytes(index, self.hintMaskBytes) + return hintMaskBytes, index + + op_cntrmask = op_hintmask + + def countHints(self): + args = self.popall() + self.hintCount = self.hintCount + len(args) // 2 + + # misc + def op_and(self, index): + raise NotImplementedError + + def op_or(self, index): + raise NotImplementedError + + def op_not(self, index): + raise NotImplementedError + + def op_store(self, index): + raise NotImplementedError + + def op_abs(self, index): + raise NotImplementedError + + def op_add(self, index): + raise NotImplementedError + + def op_sub(self, index): + raise NotImplementedError + + def op_div(self, index): + raise NotImplementedError + + def op_load(self, index): + raise NotImplementedError + + def op_neg(self, index): + raise NotImplementedError + + def op_eq(self, index): + raise NotImplementedError + + def op_drop(self, index): + raise NotImplementedError + + def op_put(self, index): + raise NotImplementedError + + def op_get(self, index): + raise NotImplementedError + + def op_ifelse(self, index): + raise NotImplementedError + + def op_random(self, index): + raise NotImplementedError + + def op_mul(self, index): + raise NotImplementedError + + def op_sqrt(self, index): + raise NotImplementedError + + def op_dup(self, index): + raise NotImplementedError + + def op_exch(self, index): + raise NotImplementedError + + def op_index(self, index): + raise NotImplementedError + + def op_roll(self, index): + raise NotImplementedError + + def op_blend(self, index): + if self.numRegions == 0: + self.numRegions = self.private.getNumRegions() + numBlends = self.pop() + numOps = numBlends * (self.numRegions + 1) + if self.blender is None: + del self.operandStack[ + -(numOps - numBlends) : + ] # Leave the default operands on the stack. + else: + argi = len(self.operandStack) - numOps + end_args = tuplei = argi + numBlends + while argi < end_args: + next_ti = tuplei + self.numRegions + deltas = self.operandStack[tuplei:next_ti] + delta = self.blender(self.vsIndex, deltas) + self.operandStack[argi] += delta + tuplei = next_ti + argi += 1 + self.operandStack[end_args:] = [] + + def op_vsindex(self, index): + vi = self.pop() + self.vsIndex = vi + self.numRegions = self.private.getNumRegions(vi) + + +t1Operators = [ + # opcode name + (1, "hstem"), + (3, "vstem"), + (4, "vmoveto"), + (5, "rlineto"), + (6, "hlineto"), + (7, "vlineto"), + (8, "rrcurveto"), + (9, "closepath"), + (10, "callsubr"), + (11, "return"), + (13, "hsbw"), + (14, "endchar"), + (21, "rmoveto"), + (22, "hmoveto"), + (30, "vhcurveto"), + (31, "hvcurveto"), + ((12, 0), "dotsection"), + ((12, 1), "vstem3"), + ((12, 2), "hstem3"), + ((12, 6), "seac"), + ((12, 7), "sbw"), + ((12, 12), "div"), + ((12, 16), "callothersubr"), + ((12, 17), "pop"), + ((12, 33), "setcurrentpoint"), +] + + +class T2StackUseExtractor(SimpleT2Decompiler): + + def execute(self, charString): + maxStackUse = 0 + + def pushToStack(value): + nonlocal maxStackUse + self.operandStack.append(value) + maxStackUse = max(maxStackUse, len(self.operandStack)) + + super().execute(charString, pushToStack=pushToStack) + return maxStackUse + + +class T2WidthExtractor(SimpleT2Decompiler): + def __init__( + self, + localSubrs, + globalSubrs, + nominalWidthX, + defaultWidthX, + private=None, + blender=None, + ): + SimpleT2Decompiler.__init__(self, localSubrs, globalSubrs, private, blender) + self.nominalWidthX = nominalWidthX + self.defaultWidthX = defaultWidthX + + def reset(self): + SimpleT2Decompiler.reset(self) + self.gotWidth = 0 + self.width = 0 + + def popallWidth(self, evenOdd=0): + args = self.popall() + if not self.gotWidth: + if evenOdd ^ (len(args) % 2): + # For CFF2 charstrings, this should never happen + assert ( + self.defaultWidthX is not None + ), "CFF2 CharStrings must not have an initial width value" + self.width = self.nominalWidthX + args[0] + args = args[1:] + else: + self.width = self.defaultWidthX + self.gotWidth = 1 + return args + + def countHints(self): + args = self.popallWidth() + self.hintCount = self.hintCount + len(args) // 2 + + def op_rmoveto(self, index): + self.popallWidth() + + def op_hmoveto(self, index): + self.popallWidth(1) + + def op_vmoveto(self, index): + self.popallWidth(1) + + def op_endchar(self, index): + self.popallWidth() + + +class T2OutlineExtractor(T2WidthExtractor): + def __init__( + self, + pen, + localSubrs, + globalSubrs, + nominalWidthX, + defaultWidthX, + private=None, + blender=None, + ): + T2WidthExtractor.__init__( + self, + localSubrs, + globalSubrs, + nominalWidthX, + defaultWidthX, + private, + blender, + ) + self.pen = pen + self.subrLevel = 0 + + def reset(self): + T2WidthExtractor.reset(self) + self.currentPoint = (0, 0) + self.sawMoveTo = 0 + self.subrLevel = 0 + + def execute(self, charString): + self.subrLevel += 1 + super().execute(charString) + self.subrLevel -= 1 + if self.subrLevel == 0: + self.endPath() + + def _nextPoint(self, point): + x, y = self.currentPoint + point = x + point[0], y + point[1] + self.currentPoint = point + return point + + def rMoveTo(self, point): + self.pen.moveTo(self._nextPoint(point)) + self.sawMoveTo = 1 + + def rLineTo(self, point): + if not self.sawMoveTo: + self.rMoveTo((0, 0)) + self.pen.lineTo(self._nextPoint(point)) + + def rCurveTo(self, pt1, pt2, pt3): + if not self.sawMoveTo: + self.rMoveTo((0, 0)) + nextPoint = self._nextPoint + self.pen.curveTo(nextPoint(pt1), nextPoint(pt2), nextPoint(pt3)) + + def closePath(self): + if self.sawMoveTo: + self.pen.closePath() + self.sawMoveTo = 0 + + def endPath(self): + # In T2 there are no open paths, so always do a closePath when + # finishing a sub path. We avoid spurious calls to closePath() + # because its a real T1 op we're emulating in T2 whereas + # endPath() is just a means to that emulation + if self.sawMoveTo: + self.closePath() + + # + # hint operators + # + # def op_hstem(self, index): + # self.countHints() + # def op_vstem(self, index): + # self.countHints() + # def op_hstemhm(self, index): + # self.countHints() + # def op_vstemhm(self, index): + # self.countHints() + # def op_hintmask(self, index): + # self.countHints() + # def op_cntrmask(self, index): + # self.countHints() + + # + # path constructors, moveto + # + def op_rmoveto(self, index): + self.endPath() + self.rMoveTo(self.popallWidth()) + + def op_hmoveto(self, index): + self.endPath() + self.rMoveTo((self.popallWidth(1)[0], 0)) + + def op_vmoveto(self, index): + self.endPath() + self.rMoveTo((0, self.popallWidth(1)[0])) + + def op_endchar(self, index): + self.endPath() + args = self.popallWidth() + if args: + from fontTools.encodings.StandardEncoding import StandardEncoding + + # endchar can do seac accent bulding; The T2 spec says it's deprecated, + # but recent software that shall remain nameless does output it. + adx, ady, bchar, achar = args + baseGlyph = StandardEncoding[bchar] + self.pen.addComponent(baseGlyph, (1, 0, 0, 1, 0, 0)) + accentGlyph = StandardEncoding[achar] + self.pen.addComponent(accentGlyph, (1, 0, 0, 1, adx, ady)) + + # + # path constructors, lines + # + def op_rlineto(self, index): + args = self.popall() + for i in range(0, len(args), 2): + point = args[i : i + 2] + self.rLineTo(point) + + def op_hlineto(self, index): + self.alternatingLineto(1) + + def op_vlineto(self, index): + self.alternatingLineto(0) + + # + # path constructors, curves + # + def op_rrcurveto(self, index): + """{dxa dya dxb dyb dxc dyc}+ rrcurveto""" + args = self.popall() + for i in range(0, len(args), 6): + ( + dxa, + dya, + dxb, + dyb, + dxc, + dyc, + ) = args[i : i + 6] + self.rCurveTo((dxa, dya), (dxb, dyb), (dxc, dyc)) + + def op_rcurveline(self, index): + """{dxa dya dxb dyb dxc dyc}+ dxd dyd rcurveline""" + args = self.popall() + for i in range(0, len(args) - 2, 6): + dxb, dyb, dxc, dyc, dxd, dyd = args[i : i + 6] + self.rCurveTo((dxb, dyb), (dxc, dyc), (dxd, dyd)) + self.rLineTo(args[-2:]) + + def op_rlinecurve(self, index): + """{dxa dya}+ dxb dyb dxc dyc dxd dyd rlinecurve""" + args = self.popall() + lineArgs = args[:-6] + for i in range(0, len(lineArgs), 2): + self.rLineTo(lineArgs[i : i + 2]) + dxb, dyb, dxc, dyc, dxd, dyd = args[-6:] + self.rCurveTo((dxb, dyb), (dxc, dyc), (dxd, dyd)) + + def op_vvcurveto(self, index): + "dx1? {dya dxb dyb dyc}+ vvcurveto" + args = self.popall() + if len(args) % 2: + dx1 = args[0] + args = args[1:] + else: + dx1 = 0 + for i in range(0, len(args), 4): + dya, dxb, dyb, dyc = args[i : i + 4] + self.rCurveTo((dx1, dya), (dxb, dyb), (0, dyc)) + dx1 = 0 + + def op_hhcurveto(self, index): + """dy1? {dxa dxb dyb dxc}+ hhcurveto""" + args = self.popall() + if len(args) % 2: + dy1 = args[0] + args = args[1:] + else: + dy1 = 0 + for i in range(0, len(args), 4): + dxa, dxb, dyb, dxc = args[i : i + 4] + self.rCurveTo((dxa, dy1), (dxb, dyb), (dxc, 0)) + dy1 = 0 + + def op_vhcurveto(self, index): + """dy1 dx2 dy2 dx3 {dxa dxb dyb dyc dyd dxe dye dxf}* dyf? vhcurveto (30) + {dya dxb dyb dxc dxd dxe dye dyf}+ dxf? vhcurveto + """ + args = self.popall() + while args: + args = self.vcurveto(args) + if args: + args = self.hcurveto(args) + + def op_hvcurveto(self, index): + """dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf? + {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf? + """ + args = self.popall() + while args: + args = self.hcurveto(args) + if args: + args = self.vcurveto(args) + + # + # path constructors, flex + # + def op_hflex(self, index): + dx1, dx2, dy2, dx3, dx4, dx5, dx6 = self.popall() + dy1 = dy3 = dy4 = dy6 = 0 + dy5 = -dy2 + self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) + self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) + + def op_flex(self, index): + dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4, dx5, dy5, dx6, dy6, fd = self.popall() + self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) + self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) + + def op_hflex1(self, index): + dx1, dy1, dx2, dy2, dx3, dx4, dx5, dy5, dx6 = self.popall() + dy3 = dy4 = 0 + dy6 = -(dy1 + dy2 + dy3 + dy4 + dy5) + + self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) + self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) + + def op_flex1(self, index): + dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4, dx5, dy5, d6 = self.popall() + dx = dx1 + dx2 + dx3 + dx4 + dx5 + dy = dy1 + dy2 + dy3 + dy4 + dy5 + if abs(dx) > abs(dy): + dx6 = d6 + dy6 = -dy + else: + dx6 = -dx + dy6 = d6 + self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) + self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) + + # misc + def op_and(self, index): + raise NotImplementedError + + def op_or(self, index): + raise NotImplementedError + + def op_not(self, index): + raise NotImplementedError + + def op_store(self, index): + raise NotImplementedError + + def op_abs(self, index): + raise NotImplementedError + + def op_add(self, index): + raise NotImplementedError + + def op_sub(self, index): + raise NotImplementedError + + def op_div(self, index): + num2 = self.pop() + num1 = self.pop() + d1 = num1 // num2 + d2 = num1 / num2 + if d1 == d2: + self.push(d1) + else: + self.push(d2) + + def op_load(self, index): + raise NotImplementedError + + def op_neg(self, index): + raise NotImplementedError + + def op_eq(self, index): + raise NotImplementedError + + def op_drop(self, index): + raise NotImplementedError + + def op_put(self, index): + raise NotImplementedError + + def op_get(self, index): + raise NotImplementedError + + def op_ifelse(self, index): + raise NotImplementedError + + def op_random(self, index): + raise NotImplementedError + + def op_mul(self, index): + raise NotImplementedError + + def op_sqrt(self, index): + raise NotImplementedError + + def op_dup(self, index): + raise NotImplementedError + + def op_exch(self, index): + raise NotImplementedError + + def op_index(self, index): + raise NotImplementedError + + def op_roll(self, index): + raise NotImplementedError + + # + # miscellaneous helpers + # + def alternatingLineto(self, isHorizontal): + args = self.popall() + for arg in args: + if isHorizontal: + point = (arg, 0) + else: + point = (0, arg) + self.rLineTo(point) + isHorizontal = not isHorizontal + + def vcurveto(self, args): + dya, dxb, dyb, dxc = args[:4] + args = args[4:] + if len(args) == 1: + dyc = args[0] + args = [] + else: + dyc = 0 + self.rCurveTo((0, dya), (dxb, dyb), (dxc, dyc)) + return args + + def hcurveto(self, args): + dxa, dxb, dyb, dyc = args[:4] + args = args[4:] + if len(args) == 1: + dxc = args[0] + args = [] + else: + dxc = 0 + self.rCurveTo((dxa, 0), (dxb, dyb), (dxc, dyc)) + return args + + +class T1OutlineExtractor(T2OutlineExtractor): + def __init__(self, pen, subrs): + self.pen = pen + self.subrs = subrs + self.reset() + + def reset(self): + self.flexing = 0 + self.width = 0 + self.sbx = 0 + T2OutlineExtractor.reset(self) + + def endPath(self): + if self.sawMoveTo: + self.pen.endPath() + self.sawMoveTo = 0 + + def popallWidth(self, evenOdd=0): + return self.popall() + + def exch(self): + stack = self.operandStack + stack[-1], stack[-2] = stack[-2], stack[-1] + + # + # path constructors + # + def op_rmoveto(self, index): + if self.flexing: + return + self.endPath() + self.rMoveTo(self.popall()) + + def op_hmoveto(self, index): + if self.flexing: + # We must add a parameter to the stack if we are flexing + self.push(0) + return + self.endPath() + self.rMoveTo((self.popall()[0], 0)) + + def op_vmoveto(self, index): + if self.flexing: + # We must add a parameter to the stack if we are flexing + self.push(0) + self.exch() + return + self.endPath() + self.rMoveTo((0, self.popall()[0])) + + def op_closepath(self, index): + self.closePath() + + def op_setcurrentpoint(self, index): + args = self.popall() + x, y = args + self.currentPoint = x, y + + def op_endchar(self, index): + self.endPath() + + def op_hsbw(self, index): + sbx, wx = self.popall() + self.width = wx + self.sbx = sbx + self.currentPoint = sbx, self.currentPoint[1] + + def op_sbw(self, index): + self.popall() # XXX + + # + def op_callsubr(self, index): + subrIndex = self.pop() + subr = self.subrs[subrIndex] + self.execute(subr) + + def op_callothersubr(self, index): + subrIndex = self.pop() + nArgs = self.pop() + # print nArgs, subrIndex, "callothersubr" + if subrIndex == 0 and nArgs == 3: + self.doFlex() + self.flexing = 0 + elif subrIndex == 1 and nArgs == 0: + self.flexing = 1 + # ignore... + + def op_pop(self, index): + pass # ignore... + + def doFlex(self): + finaly = self.pop() + finalx = self.pop() + self.pop() # flex height is unused + + p3y = self.pop() + p3x = self.pop() + bcp4y = self.pop() + bcp4x = self.pop() + bcp3y = self.pop() + bcp3x = self.pop() + p2y = self.pop() + p2x = self.pop() + bcp2y = self.pop() + bcp2x = self.pop() + bcp1y = self.pop() + bcp1x = self.pop() + rpy = self.pop() + rpx = self.pop() + + # call rrcurveto + self.push(bcp1x + rpx) + self.push(bcp1y + rpy) + self.push(bcp2x) + self.push(bcp2y) + self.push(p2x) + self.push(p2y) + self.op_rrcurveto(None) + + # call rrcurveto + self.push(bcp3x) + self.push(bcp3y) + self.push(bcp4x) + self.push(bcp4y) + self.push(p3x) + self.push(p3y) + self.op_rrcurveto(None) + + # Push back final coords so subr 0 can find them + self.push(finalx) + self.push(finaly) + + def op_dotsection(self, index): + self.popall() # XXX + + def op_hstem3(self, index): + self.popall() # XXX + + def op_seac(self, index): + "asb adx ady bchar achar seac" + from fontTools.encodings.StandardEncoding import StandardEncoding + + asb, adx, ady, bchar, achar = self.popall() + baseGlyph = StandardEncoding[bchar] + self.pen.addComponent(baseGlyph, (1, 0, 0, 1, 0, 0)) + accentGlyph = StandardEncoding[achar] + adx = adx + self.sbx - asb # seac weirdness + self.pen.addComponent(accentGlyph, (1, 0, 0, 1, adx, ady)) + + def op_vstem3(self, index): + self.popall() # XXX + + +class T2CharString(object): + operandEncoding = t2OperandEncoding + operators, opcodes = buildOperatorDict(t2Operators) + decompilerClass = SimpleT2Decompiler + outlineExtractor = T2OutlineExtractor + + def __init__(self, bytecode=None, program=None, private=None, globalSubrs=None): + if program is None: + program = [] + self.bytecode = bytecode + self.program = program + self.private = private + self.globalSubrs = globalSubrs if globalSubrs is not None else [] + self._cur_vsindex = None + + def getNumRegions(self, vsindex=None): + pd = self.private + assert pd is not None + if vsindex is not None: + self._cur_vsindex = vsindex + elif self._cur_vsindex is None: + self._cur_vsindex = pd.vsindex if hasattr(pd, "vsindex") else 0 + return pd.getNumRegions(self._cur_vsindex) + + def __repr__(self): + if self.bytecode is None: + return "<%s (source) at %x>" % (self.__class__.__name__, id(self)) + else: + return "<%s (bytecode) at %x>" % (self.__class__.__name__, id(self)) + + def getIntEncoder(self): + return encodeIntT2 + + def getFixedEncoder(self): + return encodeFixed + + def decompile(self): + if not self.needsDecompilation(): + return + subrs = getattr(self.private, "Subrs", []) + decompiler = self.decompilerClass(subrs, self.globalSubrs, self.private) + decompiler.execute(self) + + def draw(self, pen, blender=None): + subrs = getattr(self.private, "Subrs", []) + extractor = self.outlineExtractor( + pen, + subrs, + self.globalSubrs, + self.private.nominalWidthX, + self.private.defaultWidthX, + self.private, + blender, + ) + extractor.execute(self) + self.width = extractor.width + + def calcBounds(self, glyphSet): + boundsPen = BoundsPen(glyphSet) + self.draw(boundsPen) + return boundsPen.bounds + + def compile(self, isCFF2=False): + if self.bytecode is not None: + return + opcodes = self.opcodes + program = self.program + + if isCFF2: + # If present, remove return and endchar operators. + if program and program[-1] in ("return", "endchar"): + program = program[:-1] + elif program and not isinstance(program[-1], str): + raise CharStringCompileError( + "T2CharString or Subr has items on the stack after last operator." + ) + + bytecode = [] + encodeInt = self.getIntEncoder() + encodeFixed = self.getFixedEncoder() + i = 0 + end = len(program) + while i < end: + token = program[i] + i = i + 1 + if isinstance(token, str): + try: + bytecode.extend(bytechr(b) for b in opcodes[token]) + except KeyError: + raise CharStringCompileError("illegal operator: %s" % token) + if token in ("hintmask", "cntrmask"): + bytecode.append(program[i]) # hint mask + i = i + 1 + elif isinstance(token, int): + bytecode.append(encodeInt(token)) + elif isinstance(token, float): + bytecode.append(encodeFixed(token)) + else: + assert 0, "unsupported type: %s" % type(token) + try: + bytecode = bytesjoin(bytecode) + except TypeError: + log.error(bytecode) + raise + self.setBytecode(bytecode) + + def needsDecompilation(self): + return self.bytecode is not None + + def setProgram(self, program): + self.program = program + self.bytecode = None + + def setBytecode(self, bytecode): + self.bytecode = bytecode + self.program = None + + def getToken(self, index, len=len, byteord=byteord, isinstance=isinstance): + if self.bytecode is not None: + if index >= len(self.bytecode): + return None, 0, 0 + b0 = byteord(self.bytecode[index]) + index = index + 1 + handler = self.operandEncoding[b0] + token, index = handler(self, b0, self.bytecode, index) + else: + if index >= len(self.program): + return None, 0, 0 + token = self.program[index] + index = index + 1 + isOperator = isinstance(token, str) + return token, isOperator, index + + def getBytes(self, index, nBytes): + if self.bytecode is not None: + newIndex = index + nBytes + bytes = self.bytecode[index:newIndex] + index = newIndex + else: + bytes = self.program[index] + index = index + 1 + assert len(bytes) == nBytes + return bytes, index + + def handle_operator(self, operator): + return operator + + def toXML(self, xmlWriter, ttFont=None): + from fontTools.misc.textTools import num2binary + + if self.bytecode is not None: + xmlWriter.dumphex(self.bytecode) + else: + index = 0 + args = [] + while True: + token, isOperator, index = self.getToken(index) + if token is None: + break + if isOperator: + if token in ("hintmask", "cntrmask"): + hintMask, isOperator, index = self.getToken(index) + bits = [] + for byte in hintMask: + bits.append(num2binary(byteord(byte), 8)) + hintMask = strjoin(bits) + line = " ".join(args + [token, hintMask]) + else: + line = " ".join(args + [token]) + xmlWriter.write(line) + xmlWriter.newline() + args = [] + else: + if isinstance(token, float): + token = floatToFixedToStr(token, precisionBits=16) + else: + token = str(token) + args.append(token) + if args: + # NOTE: only CFF2 charstrings/subrs can have numeric arguments on + # the stack after the last operator. Compiling this would fail if + # this is part of CFF 1.0 table. + line = " ".join(args) + xmlWriter.write(line) + + def fromXML(self, name, attrs, content): + from fontTools.misc.textTools import binary2num, readHex + + if attrs.get("raw"): + self.setBytecode(readHex(content)) + return + content = strjoin(content) + content = content.split() + program = [] + end = len(content) + i = 0 + while i < end: + token = content[i] + i = i + 1 + try: + token = int(token) + except ValueError: + try: + token = strToFixedToFloat(token, precisionBits=16) + except ValueError: + program.append(token) + if token in ("hintmask", "cntrmask"): + mask = content[i] + maskBytes = b"" + for j in range(0, len(mask), 8): + maskBytes = maskBytes + bytechr(binary2num(mask[j : j + 8])) + program.append(maskBytes) + i = i + 1 + else: + program.append(token) + else: + program.append(token) + self.setProgram(program) + + +class T1CharString(T2CharString): + operandEncoding = t1OperandEncoding + operators, opcodes = buildOperatorDict(t1Operators) + + def __init__(self, bytecode=None, program=None, subrs=None): + super().__init__(bytecode, program) + self.subrs = subrs + + def getIntEncoder(self): + return encodeIntT1 + + def getFixedEncoder(self): + def encodeFixed(value): + raise TypeError("Type 1 charstrings don't support floating point operands") + + def decompile(self): + if self.bytecode is None: + return + program = [] + index = 0 + while True: + token, isOperator, index = self.getToken(index) + if token is None: + break + program.append(token) + self.setProgram(program) + + def draw(self, pen): + extractor = T1OutlineExtractor(pen, self.subrs) + extractor.execute(self) + self.width = extractor.width + + +class DictDecompiler(object): + operandEncoding = cffDictOperandEncoding + + def __init__(self, strings, parent=None): + self.stack = [] + self.strings = strings + self.dict = {} + self.parent = parent + + def getDict(self): + assert len(self.stack) == 0, "non-empty stack" + return self.dict + + def decompile(self, data): + index = 0 + lenData = len(data) + push = self.stack.append + while index < lenData: + b0 = byteord(data[index]) + index = index + 1 + handler = self.operandEncoding[b0] + value, index = handler(self, b0, data, index) + if value is not None: + push(value) + + def pop(self): + value = self.stack[-1] + del self.stack[-1] + return value + + def popall(self): + args = self.stack[:] + del self.stack[:] + return args + + def handle_operator(self, operator): + operator, argType = operator + if isinstance(argType, tuple): + value = () + for i in range(len(argType) - 1, -1, -1): + arg = argType[i] + arghandler = getattr(self, "arg_" + arg) + value = (arghandler(operator),) + value + else: + arghandler = getattr(self, "arg_" + argType) + value = arghandler(operator) + if operator == "blend": + self.stack.extend(value) + else: + self.dict[operator] = value + + def arg_number(self, name): + if isinstance(self.stack[0], list): + out = self.arg_blend_number(self.stack) + else: + out = self.pop() + return out + + def arg_blend_number(self, name): + out = [] + blendArgs = self.pop() + numMasters = len(blendArgs) + out.append(blendArgs) + out.append("blend") + dummy = self.popall() + return blendArgs + + def arg_SID(self, name): + return self.strings[self.pop()] + + def arg_array(self, name): + return self.popall() + + def arg_blendList(self, name): + """ + There may be non-blend args at the top of the stack. We first calculate + where the blend args start in the stack. These are the last + numMasters*numBlends) +1 args. + The blend args starts with numMasters relative coordinate values, the BlueValues in the list from the default master font. This is followed by + numBlends list of values. Each of value in one of these lists is the + Variable Font delta for the matching region. + + We re-arrange this to be a list of numMaster entries. Each entry starts with the corresponding default font relative value, and is followed by + the delta values. We then convert the default values, the first item in each entry, to an absolute value. + """ + vsindex = self.dict.get("vsindex", 0) + numMasters = ( + self.parent.getNumRegions(vsindex) + 1 + ) # only a PrivateDict has blended ops. + numBlends = self.pop() + args = self.popall() + numArgs = len(args) + # The spec says that there should be no non-blended Blue Values,. + assert numArgs == numMasters * numBlends + value = [None] * numBlends + numDeltas = numMasters - 1 + i = 0 + prevVal = 0 + while i < numBlends: + newVal = args[i] + prevVal + prevVal = newVal + masterOffset = numBlends + (i * numDeltas) + blendList = [newVal] + args[masterOffset : masterOffset + numDeltas] + value[i] = blendList + i += 1 + return value + + def arg_delta(self, name): + valueList = self.popall() + out = [] + if valueList and isinstance(valueList[0], list): + # arg_blendList() has already converted these to absolute values. + out = valueList + else: + current = 0 + for v in valueList: + current = current + v + out.append(current) + return out + + +def calcSubrBias(subrs): + nSubrs = len(subrs) + if nSubrs < 1240: + bias = 107 + elif nSubrs < 33900: + bias = 1131 + else: + bias = 32768 + return bias diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/psLib.py b/.venv/lib/python3.13/site-packages/fontTools/misc/psLib.py new file mode 100644 index 0000000000000000000000000000000000000000..3bfdb4ae9fcc0c49b77830d2be8c46274e315bd4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/psLib.py @@ -0,0 +1,398 @@ +from fontTools.misc.textTools import bytechr, byteord, bytesjoin, tobytes, tostr +from fontTools.misc import eexec +from .psOperators import ( + PSOperators, + ps_StandardEncoding, + ps_array, + ps_boolean, + ps_dict, + ps_integer, + ps_literal, + ps_mark, + ps_name, + ps_operator, + ps_procedure, + ps_procmark, + ps_real, + ps_string, +) +import re +from collections.abc import Callable +from string import whitespace +import logging + + +log = logging.getLogger(__name__) + +ps_special = b"()<>[]{}%" # / is one too, but we take care of that one differently + +skipwhiteRE = re.compile(bytesjoin([b"[", whitespace, b"]*"])) +endofthingPat = bytesjoin([b"[^][(){}<>/%", whitespace, b"]*"]) +endofthingRE = re.compile(endofthingPat) +commentRE = re.compile(b"%[^\n\r]*") + +# XXX This not entirely correct as it doesn't allow *nested* embedded parens: +stringPat = rb""" + \( + ( + ( + [^()]* \ [()] + ) + | + ( + [^()]* \( [^()]* \) + ) + )* + [^()]* + \) +""" +stringPat = b"".join(stringPat.split()) +stringRE = re.compile(stringPat) + +hexstringRE = re.compile(bytesjoin([b"<[", whitespace, b"0-9A-Fa-f]*>"])) + + +class PSTokenError(Exception): + pass + + +class PSError(Exception): + pass + + +class PSTokenizer(object): + def __init__(self, buf=b"", encoding="ascii"): + # Force self.buf to be a byte string + buf = tobytes(buf) + self.buf = buf + self.len = len(buf) + self.pos = 0 + self.closed = False + self.encoding = encoding + + def read(self, n=-1): + """Read at most 'n' bytes from the buffer, or less if the read + hits EOF before obtaining 'n' bytes. + If 'n' is negative or omitted, read all data until EOF is reached. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + if n is None or n < 0: + newpos = self.len + else: + newpos = min(self.pos + n, self.len) + r = self.buf[self.pos : newpos] + self.pos = newpos + return r + + def close(self): + if not self.closed: + self.closed = True + del self.buf, self.pos + + def getnexttoken( + self, + # localize some stuff, for performance + len=len, + ps_special=ps_special, + stringmatch=stringRE.match, + hexstringmatch=hexstringRE.match, + commentmatch=commentRE.match, + endmatch=endofthingRE.match, + ): + self.skipwhite() + if self.pos >= self.len: + return None, None + pos = self.pos + buf = self.buf + char = bytechr(byteord(buf[pos])) + if char in ps_special: + if char in b"{}[]": + tokentype = "do_special" + token = char + elif char == b"%": + tokentype = "do_comment" + _, nextpos = commentmatch(buf, pos).span() + token = buf[pos:nextpos] + elif char == b"(": + tokentype = "do_string" + m = stringmatch(buf, pos) + if m is None: + raise PSTokenError("bad string at character %d" % pos) + _, nextpos = m.span() + token = buf[pos:nextpos] + elif char == b"<": + tokentype = "do_hexstring" + m = hexstringmatch(buf, pos) + if m is None: + raise PSTokenError("bad hexstring at character %d" % pos) + _, nextpos = m.span() + token = buf[pos:nextpos] + else: + raise PSTokenError("bad token at character %d" % pos) + else: + if char == b"/": + tokentype = "do_literal" + m = endmatch(buf, pos + 1) + else: + tokentype = "" + m = endmatch(buf, pos) + if m is None: + raise PSTokenError("bad token at character %d" % pos) + _, nextpos = m.span() + token = buf[pos:nextpos] + self.pos = pos + len(token) + token = tostr(token, encoding=self.encoding) + return tokentype, token + + def skipwhite(self, whitematch=skipwhiteRE.match): + _, nextpos = whitematch(self.buf, self.pos).span() + self.pos = nextpos + + def starteexec(self): + self.pos = self.pos + 1 + self.dirtybuf = self.buf[self.pos :] + self.buf, R = eexec.decrypt(self.dirtybuf, 55665) + self.len = len(self.buf) + self.pos = 4 + + def stopeexec(self): + if not hasattr(self, "dirtybuf"): + return + self.buf = self.dirtybuf + del self.dirtybuf + + +class PSInterpreter(PSOperators): + def __init__(self, encoding="ascii"): + systemdict = {} + userdict = {} + self.encoding = encoding + self.dictstack = [systemdict, userdict] + self.stack = [] + self.proclevel = 0 + self.procmark = ps_procmark() + self.fillsystemdict() + + def fillsystemdict(self): + systemdict = self.dictstack[0] + systemdict["["] = systemdict["mark"] = self.mark = ps_mark() + systemdict["]"] = ps_operator("]", self.do_makearray) + systemdict["true"] = ps_boolean(1) + systemdict["false"] = ps_boolean(0) + systemdict["StandardEncoding"] = ps_array(ps_StandardEncoding) + systemdict["FontDirectory"] = ps_dict({}) + self.suckoperators(systemdict, self.__class__) + + def suckoperators(self, systemdict, klass): + for name in dir(klass): + attr = getattr(self, name) + if isinstance(attr, Callable) and name[:3] == "ps_": + name = name[3:] + systemdict[name] = ps_operator(name, attr) + for baseclass in klass.__bases__: + self.suckoperators(systemdict, baseclass) + + def interpret(self, data, getattr=getattr): + tokenizer = self.tokenizer = PSTokenizer(data, self.encoding) + getnexttoken = tokenizer.getnexttoken + do_token = self.do_token + handle_object = self.handle_object + try: + while 1: + tokentype, token = getnexttoken() + if not token: + break + if tokentype: + handler = getattr(self, tokentype) + object = handler(token) + else: + object = do_token(token) + if object is not None: + handle_object(object) + tokenizer.close() + self.tokenizer = None + except: + if self.tokenizer is not None: + log.debug( + "ps error:\n" + "- - - - - - -\n" + "%s\n" + ">>>\n" + "%s\n" + "- - - - - - -", + self.tokenizer.buf[self.tokenizer.pos - 50 : self.tokenizer.pos], + self.tokenizer.buf[self.tokenizer.pos : self.tokenizer.pos + 50], + ) + raise + + def handle_object(self, object): + if not (self.proclevel or object.literal or object.type == "proceduretype"): + if object.type != "operatortype": + object = self.resolve_name(object.value) + if object.literal: + self.push(object) + else: + if object.type == "proceduretype": + self.call_procedure(object) + else: + object.function() + else: + self.push(object) + + def call_procedure(self, proc): + handle_object = self.handle_object + for item in proc.value: + handle_object(item) + + def resolve_name(self, name): + dictstack = self.dictstack + for i in range(len(dictstack) - 1, -1, -1): + if name in dictstack[i]: + return dictstack[i][name] + raise PSError("name error: " + str(name)) + + def do_token( + self, + token, + int=int, + float=float, + ps_name=ps_name, + ps_integer=ps_integer, + ps_real=ps_real, + ): + try: + num = int(token) + except (ValueError, OverflowError): + try: + num = float(token) + except (ValueError, OverflowError): + if "#" in token: + hashpos = token.find("#") + try: + base = int(token[:hashpos]) + num = int(token[hashpos + 1 :], base) + except (ValueError, OverflowError): + return ps_name(token) + else: + return ps_integer(num) + else: + return ps_name(token) + else: + return ps_real(num) + else: + return ps_integer(num) + + def do_comment(self, token): + pass + + def do_literal(self, token): + return ps_literal(token[1:]) + + def do_string(self, token): + return ps_string(token[1:-1]) + + def do_hexstring(self, token): + hexStr = "".join(token[1:-1].split()) + if len(hexStr) % 2: + hexStr = hexStr + "0" + cleanstr = [] + for i in range(0, len(hexStr), 2): + cleanstr.append(chr(int(hexStr[i : i + 2], 16))) + cleanstr = "".join(cleanstr) + return ps_string(cleanstr) + + def do_special(self, token): + if token == "{": + self.proclevel = self.proclevel + 1 + return self.procmark + elif token == "}": + proc = [] + while 1: + topobject = self.pop() + if topobject == self.procmark: + break + proc.append(topobject) + self.proclevel = self.proclevel - 1 + proc.reverse() + return ps_procedure(proc) + elif token == "[": + return self.mark + elif token == "]": + return ps_name("]") + else: + raise PSTokenError("huh?") + + def push(self, object): + self.stack.append(object) + + def pop(self, *types): + stack = self.stack + if not stack: + raise PSError("stack underflow") + object = stack[-1] + if types: + if object.type not in types: + raise PSError( + "typecheck, expected %s, found %s" % (repr(types), object.type) + ) + del stack[-1] + return object + + def do_makearray(self): + array = [] + while 1: + topobject = self.pop() + if topobject == self.mark: + break + array.append(topobject) + array.reverse() + self.push(ps_array(array)) + + def close(self): + """Remove circular references.""" + del self.stack + del self.dictstack + + +def unpack_item(item): + tp = type(item.value) + if tp == dict: + newitem = {} + for key, value in item.value.items(): + newitem[key] = unpack_item(value) + elif tp == list: + newitem = [None] * len(item.value) + for i in range(len(item.value)): + newitem[i] = unpack_item(item.value[i]) + if item.type == "proceduretype": + newitem = tuple(newitem) + else: + newitem = item.value + return newitem + + +def suckfont(data, encoding="ascii"): + m = re.search(rb"/FontName\s+/([^ \t\n\r]+)\s+def", data) + if m: + fontName = m.group(1) + fontName = fontName.decode() + else: + fontName = None + interpreter = PSInterpreter(encoding=encoding) + interpreter.interpret( + b"/Helvetica 4 dict dup /Encoding StandardEncoding put definefont pop" + ) + interpreter.interpret(data) + fontdir = interpreter.dictstack[0]["FontDirectory"].value + if fontName in fontdir: + rawfont = fontdir[fontName] + else: + # fall back, in case fontName wasn't found + fontNames = list(fontdir.keys()) + if len(fontNames) > 1: + fontNames.remove("Helvetica") + fontNames.sort() + rawfont = fontdir[fontNames[0]] + interpreter.close() + return unpack_item(rawfont) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/psOperators.py b/.venv/lib/python3.13/site-packages/fontTools/misc/psOperators.py new file mode 100644 index 0000000000000000000000000000000000000000..d0b975eab14486cab9f7f8e60d2c2c9de8cb7c48 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/psOperators.py @@ -0,0 +1,572 @@ +_accessstrings = {0: "", 1: "readonly", 2: "executeonly", 3: "noaccess"} + + +class ps_object(object): + literal = 1 + access = 0 + value = None + + def __init__(self, value): + self.value = value + self.type = self.__class__.__name__[3:] + "type" + + def __repr__(self): + return "<%s %s>" % (self.__class__.__name__[3:], repr(self.value)) + + +class ps_operator(ps_object): + literal = 0 + + def __init__(self, name, function): + self.name = name + self.function = function + self.type = self.__class__.__name__[3:] + "type" + + def __repr__(self): + return "" % self.name + + +class ps_procedure(ps_object): + literal = 0 + + def __repr__(self): + return "" + + def __str__(self): + psstring = "{" + for i in range(len(self.value)): + if i: + psstring = psstring + " " + str(self.value[i]) + else: + psstring = psstring + str(self.value[i]) + return psstring + "}" + + +class ps_name(ps_object): + literal = 0 + + def __str__(self): + if self.literal: + return "/" + self.value + else: + return self.value + + +class ps_literal(ps_object): + def __str__(self): + return "/" + self.value + + +class ps_array(ps_object): + def __str__(self): + psstring = "[" + for i in range(len(self.value)): + item = self.value[i] + access = _accessstrings[item.access] + if access: + access = " " + access + if i: + psstring = psstring + " " + str(item) + access + else: + psstring = psstring + str(item) + access + return psstring + "]" + + def __repr__(self): + return "" + + +_type1_pre_eexec_order = [ + "FontInfo", + "FontName", + "Encoding", + "PaintType", + "FontType", + "FontMatrix", + "FontBBox", + "UniqueID", + "Metrics", + "StrokeWidth", +] + +_type1_fontinfo_order = [ + "version", + "Notice", + "FullName", + "FamilyName", + "Weight", + "ItalicAngle", + "isFixedPitch", + "UnderlinePosition", + "UnderlineThickness", +] + +_type1_post_eexec_order = ["Private", "CharStrings", "FID"] + + +def _type1_item_repr(key, value): + psstring = "" + access = _accessstrings[value.access] + if access: + access = access + " " + if key == "CharStrings": + psstring = psstring + "/%s %s def\n" % ( + key, + _type1_CharString_repr(value.value), + ) + elif key == "Encoding": + psstring = psstring + _type1_Encoding_repr(value, access) + else: + psstring = psstring + "/%s %s %sdef\n" % (str(key), str(value), access) + return psstring + + +def _type1_Encoding_repr(encoding, access): + encoding = encoding.value + psstring = "/Encoding 256 array\n0 1 255 {1 index exch /.notdef put} for\n" + for i in range(256): + name = encoding[i].value + if name != ".notdef": + psstring = psstring + "dup %d /%s put\n" % (i, name) + return psstring + access + "def\n" + + +def _type1_CharString_repr(charstrings): + items = sorted(charstrings.items()) + return "xxx" + + +class ps_font(ps_object): + def __str__(self): + psstring = "%d dict dup begin\n" % len(self.value) + for key in _type1_pre_eexec_order: + try: + value = self.value[key] + except KeyError: + pass + else: + psstring = psstring + _type1_item_repr(key, value) + items = sorted(self.value.items()) + for key, value in items: + if key not in _type1_pre_eexec_order + _type1_post_eexec_order: + psstring = psstring + _type1_item_repr(key, value) + psstring = psstring + "currentdict end\ncurrentfile eexec\ndup " + for key in _type1_post_eexec_order: + try: + value = self.value[key] + except KeyError: + pass + else: + psstring = psstring + _type1_item_repr(key, value) + return ( + psstring + + "dup/FontName get exch definefont pop\nmark currentfile closefile\n" + + 8 * (64 * "0" + "\n") + + "cleartomark" + + "\n" + ) + + def __repr__(self): + return "" + + +class ps_file(ps_object): + pass + + +class ps_dict(ps_object): + def __str__(self): + psstring = "%d dict dup begin\n" % len(self.value) + items = sorted(self.value.items()) + for key, value in items: + access = _accessstrings[value.access] + if access: + access = access + " " + psstring = psstring + "/%s %s %sdef\n" % (str(key), str(value), access) + return psstring + "end " + + def __repr__(self): + return "" + + +class ps_mark(ps_object): + def __init__(self): + self.value = "mark" + self.type = self.__class__.__name__[3:] + "type" + + +class ps_procmark(ps_object): + def __init__(self): + self.value = "procmark" + self.type = self.__class__.__name__[3:] + "type" + + +class ps_null(ps_object): + def __init__(self): + self.type = self.__class__.__name__[3:] + "type" + + +class ps_boolean(ps_object): + def __str__(self): + if self.value: + return "true" + else: + return "false" + + +class ps_string(ps_object): + def __str__(self): + return "(%s)" % repr(self.value)[1:-1] + + +class ps_integer(ps_object): + def __str__(self): + return repr(self.value) + + +class ps_real(ps_object): + def __str__(self): + return repr(self.value) + + +class PSOperators(object): + def ps_def(self): + obj = self.pop() + name = self.pop() + self.dictstack[-1][name.value] = obj + + def ps_bind(self): + proc = self.pop("proceduretype") + self.proc_bind(proc) + self.push(proc) + + def proc_bind(self, proc): + for i in range(len(proc.value)): + item = proc.value[i] + if item.type == "proceduretype": + self.proc_bind(item) + else: + if not item.literal: + try: + obj = self.resolve_name(item.value) + except: + pass + else: + if obj.type == "operatortype": + proc.value[i] = obj + + def ps_exch(self): + if len(self.stack) < 2: + raise RuntimeError("stack underflow") + obj1 = self.pop() + obj2 = self.pop() + self.push(obj1) + self.push(obj2) + + def ps_dup(self): + if not self.stack: + raise RuntimeError("stack underflow") + self.push(self.stack[-1]) + + def ps_exec(self): + obj = self.pop() + if obj.type == "proceduretype": + self.call_procedure(obj) + else: + self.handle_object(obj) + + def ps_count(self): + self.push(ps_integer(len(self.stack))) + + def ps_eq(self): + any1 = self.pop() + any2 = self.pop() + self.push(ps_boolean(any1.value == any2.value)) + + def ps_ne(self): + any1 = self.pop() + any2 = self.pop() + self.push(ps_boolean(any1.value != any2.value)) + + def ps_cvx(self): + obj = self.pop() + obj.literal = 0 + self.push(obj) + + def ps_matrix(self): + matrix = [ + ps_real(1.0), + ps_integer(0), + ps_integer(0), + ps_real(1.0), + ps_integer(0), + ps_integer(0), + ] + self.push(ps_array(matrix)) + + def ps_string(self): + num = self.pop("integertype").value + self.push(ps_string("\0" * num)) + + def ps_type(self): + obj = self.pop() + self.push(ps_string(obj.type)) + + def ps_store(self): + value = self.pop() + key = self.pop() + name = key.value + for i in range(len(self.dictstack) - 1, -1, -1): + if name in self.dictstack[i]: + self.dictstack[i][name] = value + break + self.dictstack[-1][name] = value + + def ps_where(self): + name = self.pop() + # XXX + self.push(ps_boolean(0)) + + def ps_systemdict(self): + self.push(ps_dict(self.dictstack[0])) + + def ps_userdict(self): + self.push(ps_dict(self.dictstack[1])) + + def ps_currentdict(self): + self.push(ps_dict(self.dictstack[-1])) + + def ps_currentfile(self): + self.push(ps_file(self.tokenizer)) + + def ps_eexec(self): + f = self.pop("filetype").value + f.starteexec() + + def ps_closefile(self): + f = self.pop("filetype").value + f.skipwhite() + f.stopeexec() + + def ps_cleartomark(self): + obj = self.pop() + while obj != self.mark: + obj = self.pop() + + def ps_readstring(self, ps_boolean=ps_boolean, len=len): + s = self.pop("stringtype") + oldstr = s.value + f = self.pop("filetype") + # pad = file.value.read(1) + # for StringIO, this is faster + f.value.pos = f.value.pos + 1 + newstr = f.value.read(len(oldstr)) + s.value = newstr + self.push(s) + self.push(ps_boolean(len(oldstr) == len(newstr))) + + def ps_known(self): + key = self.pop() + d = self.pop("dicttype", "fonttype") + self.push(ps_boolean(key.value in d.value)) + + def ps_if(self): + proc = self.pop("proceduretype") + if self.pop("booleantype").value: + self.call_procedure(proc) + + def ps_ifelse(self): + proc2 = self.pop("proceduretype") + proc1 = self.pop("proceduretype") + if self.pop("booleantype").value: + self.call_procedure(proc1) + else: + self.call_procedure(proc2) + + def ps_readonly(self): + obj = self.pop() + if obj.access < 1: + obj.access = 1 + self.push(obj) + + def ps_executeonly(self): + obj = self.pop() + if obj.access < 2: + obj.access = 2 + self.push(obj) + + def ps_noaccess(self): + obj = self.pop() + if obj.access < 3: + obj.access = 3 + self.push(obj) + + def ps_not(self): + obj = self.pop("booleantype", "integertype") + if obj.type == "booleantype": + self.push(ps_boolean(not obj.value)) + else: + self.push(ps_integer(~obj.value)) + + def ps_print(self): + str = self.pop("stringtype") + print("PS output --->", str.value) + + def ps_anchorsearch(self): + seek = self.pop("stringtype") + s = self.pop("stringtype") + seeklen = len(seek.value) + if s.value[:seeklen] == seek.value: + self.push(ps_string(s.value[seeklen:])) + self.push(seek) + self.push(ps_boolean(1)) + else: + self.push(s) + self.push(ps_boolean(0)) + + def ps_array(self): + num = self.pop("integertype") + array = ps_array([None] * num.value) + self.push(array) + + def ps_astore(self): + array = self.pop("arraytype") + for i in range(len(array.value) - 1, -1, -1): + array.value[i] = self.pop() + self.push(array) + + def ps_load(self): + name = self.pop() + self.push(self.resolve_name(name.value)) + + def ps_put(self): + obj1 = self.pop() + obj2 = self.pop() + obj3 = self.pop("arraytype", "dicttype", "stringtype", "proceduretype") + tp = obj3.type + if tp == "arraytype" or tp == "proceduretype": + obj3.value[obj2.value] = obj1 + elif tp == "dicttype": + obj3.value[obj2.value] = obj1 + elif tp == "stringtype": + index = obj2.value + obj3.value = obj3.value[:index] + chr(obj1.value) + obj3.value[index + 1 :] + + def ps_get(self): + obj1 = self.pop() + if obj1.value == "Encoding": + pass + obj2 = self.pop( + "arraytype", "dicttype", "stringtype", "proceduretype", "fonttype" + ) + tp = obj2.type + if tp in ("arraytype", "proceduretype"): + self.push(obj2.value[obj1.value]) + elif tp in ("dicttype", "fonttype"): + self.push(obj2.value[obj1.value]) + elif tp == "stringtype": + self.push(ps_integer(ord(obj2.value[obj1.value]))) + else: + assert False, "shouldn't get here" + + def ps_getinterval(self): + obj1 = self.pop("integertype") + obj2 = self.pop("integertype") + obj3 = self.pop("arraytype", "stringtype") + tp = obj3.type + if tp == "arraytype": + self.push(ps_array(obj3.value[obj2.value : obj2.value + obj1.value])) + elif tp == "stringtype": + self.push(ps_string(obj3.value[obj2.value : obj2.value + obj1.value])) + + def ps_putinterval(self): + obj1 = self.pop("arraytype", "stringtype") + obj2 = self.pop("integertype") + obj3 = self.pop("arraytype", "stringtype") + tp = obj3.type + if tp == "arraytype": + obj3.value[obj2.value : obj2.value + len(obj1.value)] = obj1.value + elif tp == "stringtype": + newstr = obj3.value[: obj2.value] + newstr = newstr + obj1.value + newstr = newstr + obj3.value[obj2.value + len(obj1.value) :] + obj3.value = newstr + + def ps_cvn(self): + self.push(ps_name(self.pop("stringtype").value)) + + def ps_index(self): + n = self.pop("integertype").value + if n < 0: + raise RuntimeError("index may not be negative") + self.push(self.stack[-1 - n]) + + def ps_for(self): + proc = self.pop("proceduretype") + limit = self.pop("integertype", "realtype").value + increment = self.pop("integertype", "realtype").value + i = self.pop("integertype", "realtype").value + while 1: + if increment > 0: + if i > limit: + break + else: + if i < limit: + break + if type(i) == type(0.0): + self.push(ps_real(i)) + else: + self.push(ps_integer(i)) + self.call_procedure(proc) + i = i + increment + + def ps_forall(self): + proc = self.pop("proceduretype") + obj = self.pop("arraytype", "stringtype", "dicttype") + tp = obj.type + if tp == "arraytype": + for item in obj.value: + self.push(item) + self.call_procedure(proc) + elif tp == "stringtype": + for item in obj.value: + self.push(ps_integer(ord(item))) + self.call_procedure(proc) + elif tp == "dicttype": + for key, value in obj.value.items(): + self.push(ps_name(key)) + self.push(value) + self.call_procedure(proc) + + def ps_definefont(self): + font = self.pop("dicttype") + name = self.pop() + font = ps_font(font.value) + self.dictstack[0]["FontDirectory"].value[name.value] = font + self.push(font) + + def ps_findfont(self): + name = self.pop() + font = self.dictstack[0]["FontDirectory"].value[name.value] + self.push(font) + + def ps_pop(self): + self.pop() + + def ps_dict(self): + self.pop("integertype") + self.push(ps_dict({})) + + def ps_begin(self): + self.dictstack.append(self.pop("dicttype").value) + + def ps_end(self): + if len(self.dictstack) > 2: + del self.dictstack[-1] + else: + raise RuntimeError("dictstack underflow") + + +notdef = ".notdef" +from fontTools.encodings.StandardEncoding import StandardEncoding + +ps_StandardEncoding = list(map(ps_name, StandardEncoding)) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/roundTools.py b/.venv/lib/python3.13/site-packages/fontTools/misc/roundTools.py new file mode 100644 index 0000000000000000000000000000000000000000..a4d45c31b2265cc5f705c39f41e952cc69514517 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/roundTools.py @@ -0,0 +1,110 @@ +""" +Various round-to-integer helpers. +""" + +import math +import functools +import logging + +log = logging.getLogger(__name__) + +__all__ = [ + "noRound", + "otRound", + "maybeRound", + "roundFunc", + "nearestMultipleShortestRepr", +] + + +def noRound(value): + return value + + +def otRound(value): + """Round float value to nearest integer towards ``+Infinity``. + + The OpenType spec (in the section on `"normalization" of OpenType Font Variations `_) + defines the required method for converting floating point values to + fixed-point. In particular it specifies the following rounding strategy: + + for fractional values of 0.5 and higher, take the next higher integer; + for other fractional values, truncate. + + This function rounds the floating-point value according to this strategy + in preparation for conversion to fixed-point. + + Args: + value (float): The input floating-point value. + + Returns + float: The rounded value. + """ + # See this thread for how we ended up with this implementation: + # https://github.com/fonttools/fonttools/issues/1248#issuecomment-383198166 + return int(math.floor(value + 0.5)) + + +def maybeRound(v, tolerance, round=otRound): + rounded = round(v) + return rounded if abs(rounded - v) <= tolerance else v + + +def roundFunc(tolerance, round=otRound): + if tolerance < 0: + raise ValueError("Rounding tolerance must be positive") + + if tolerance == 0: + return noRound + + if tolerance >= 0.5: + return round + + return functools.partial(maybeRound, tolerance=tolerance, round=round) + + +def nearestMultipleShortestRepr(value: float, factor: float) -> str: + """Round to nearest multiple of factor and return shortest decimal representation. + + This chooses the float that is closer to a multiple of the given factor while + having the shortest decimal representation (the least number of fractional decimal + digits). + + For example, given the following: + + >>> nearestMultipleShortestRepr(-0.61883544921875, 1.0/(1<<14)) + '-0.61884' + + Useful when you need to serialize or print a fixed-point number (or multiples + thereof, such as F2Dot14 fractions of 180 degrees in COLRv1 PaintRotate) in + a human-readable form. + + Args: + value (value): The value to be rounded and serialized. + factor (float): The value which the result is a close multiple of. + + Returns: + str: A compact string representation of the value. + """ + if not value: + return "0.0" + + value = otRound(value / factor) * factor + eps = 0.5 * factor + lo = value - eps + hi = value + eps + # If the range of valid choices spans an integer, return the integer. + if int(lo) != int(hi): + return str(float(round(value))) + + fmt = "%.8f" + lo = fmt % lo + hi = fmt % hi + assert len(lo) == len(hi) and lo != hi + for i in range(len(lo)): + if lo[i] != hi[i]: + break + period = lo.find(".") + assert period < i + fmt = "%%.%df" % (i - period) + return fmt % value diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/sstruct.py b/.venv/lib/python3.13/site-packages/fontTools/misc/sstruct.py new file mode 100644 index 0000000000000000000000000000000000000000..23227d8a6839cf276045fabae4b6b1c182665a51 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/sstruct.py @@ -0,0 +1,227 @@ +"""sstruct.py -- SuperStruct + +Higher level layer on top of the struct module, enabling to +bind names to struct elements. The interface is similar to +struct, except the objects passed and returned are not tuples +(or argument lists), but dictionaries or instances. + +Just like struct, we use fmt strings to describe a data +structure, except we use one line per element. Lines are +separated by newlines or semi-colons. Each line contains +either one of the special struct characters ('@', '=', '<', +'>' or '!') or a 'name:formatchar' combo (eg. 'myFloat:f'). +Repetitions, like the struct module offers them are not useful +in this context, except for fixed length strings (eg. 'myInt:5h' +is not allowed but 'myString:5s' is). The 'x' fmt character +(pad byte) is treated as 'special', since it is by definition +anonymous. Extra whitespace is allowed everywhere. + +The sstruct module offers one feature that the "normal" struct +module doesn't: support for fixed point numbers. These are spelled +as "n.mF", where n is the number of bits before the point, and m +the number of bits after the point. Fixed point numbers get +converted to floats. + +pack(fmt, object): + 'object' is either a dictionary or an instance (or actually + anything that has a __dict__ attribute). If it is a dictionary, + its keys are used for names. If it is an instance, it's + attributes are used to grab struct elements from. Returns + a string containing the data. + +unpack(fmt, data, object=None) + If 'object' is omitted (or None), a new dictionary will be + returned. If 'object' is a dictionary, it will be used to add + struct elements to. If it is an instance (or in fact anything + that has a __dict__ attribute), an attribute will be added for + each struct element. In the latter two cases, 'object' itself + is returned. + +unpack2(fmt, data, object=None) + Convenience function. Same as unpack, except data may be longer + than needed. The returned value is a tuple: (object, leftoverdata). + +calcsize(fmt) + like struct.calcsize(), but uses our own fmt strings: + it returns the size of the data in bytes. +""" + +from fontTools.misc.fixedTools import fixedToFloat as fi2fl, floatToFixed as fl2fi +from fontTools.misc.textTools import tobytes, tostr +import struct +import re + +__version__ = "1.2" +__copyright__ = "Copyright 1998, Just van Rossum " + + +class Error(Exception): + pass + + +def pack(fmt, obj): + formatstring, names, fixes = getformat(fmt, keep_pad_byte=True) + elements = [] + if not isinstance(obj, dict): + obj = obj.__dict__ + for name in names.keys(): + value = obj[name] + if name in fixes: + # fixed point conversion + value = fl2fi(value, fixes[name]) + elif isinstance(value, str): + value = tobytes(value) + elements.append(value) + # Check it fits + try: + struct.pack(names[name], value) + except Exception as e: + raise ValueError( + "Value %s does not fit in format %s for %s" % (value, names[name], name) + ) from e + data = struct.pack(*(formatstring,) + tuple(elements)) + return data + + +def unpack(fmt, data, obj=None): + if obj is None: + obj = {} + data = tobytes(data) + formatstring, names, fixes = getformat(fmt) + if isinstance(obj, dict): + d = obj + else: + d = obj.__dict__ + elements = struct.unpack(formatstring, data) + for i, name in enumerate(names.keys()): + value = elements[i] + if name in fixes: + # fixed point conversion + value = fi2fl(value, fixes[name]) + elif isinstance(value, bytes): + try: + value = tostr(value) + except UnicodeDecodeError: + pass + d[name] = value + return obj + + +def unpack2(fmt, data, obj=None): + length = calcsize(fmt) + return unpack(fmt, data[:length], obj), data[length:] + + +def calcsize(fmt): + formatstring, names, fixes = getformat(fmt) + return struct.calcsize(formatstring) + + +# matches "name:formatchar" (whitespace is allowed) +_elementRE = re.compile( + r"\s*" # whitespace + r"([A-Za-z_][A-Za-z_0-9]*)" # name (python identifier) + r"\s*:\s*" # whitespace : whitespace + r"([xcbB?hHiIlLqQfd]|" # formatchar... + r"[0-9]+[ps]|" # ...formatchar... + r"([0-9]+)\.([0-9]+)(F))" # ...formatchar + r"\s*" # whitespace + r"(#.*)?$" # [comment] + end of string +) + +# matches the special struct fmt chars and 'x' (pad byte) +_extraRE = re.compile(r"\s*([x@=<>!])\s*(#.*)?$") + +# matches an "empty" string, possibly containing whitespace and/or a comment +_emptyRE = re.compile(r"\s*(#.*)?$") + +_fixedpointmappings = {8: "b", 16: "h", 32: "l"} + +_formatcache = {} + + +def getformat(fmt, keep_pad_byte=False): + fmt = tostr(fmt, encoding="ascii") + try: + formatstring, names, fixes = _formatcache[fmt] + except KeyError: + lines = re.split("[\n;]", fmt) + formatstring = "" + names = {} + fixes = {} + for line in lines: + if _emptyRE.match(line): + continue + m = _extraRE.match(line) + if m: + formatchar = m.group(1) + if formatchar != "x" and formatstring: + raise Error("a special fmt char must be first") + else: + m = _elementRE.match(line) + if not m: + raise Error("syntax error in fmt: '%s'" % line) + name = m.group(1) + formatchar = m.group(2) + if keep_pad_byte or formatchar != "x": + names[name] = formatchar + if m.group(3): + # fixed point + before = int(m.group(3)) + after = int(m.group(4)) + bits = before + after + if bits not in [8, 16, 32]: + raise Error("fixed point must be 8, 16 or 32 bits long") + formatchar = _fixedpointmappings[bits] + names[name] = formatchar + assert m.group(5) == "F" + fixes[name] = after + formatstring += formatchar + _formatcache[fmt] = formatstring, names, fixes + return formatstring, names, fixes + + +def _test(): + fmt = """ + # comments are allowed + > # big endian (see documentation for struct) + # empty lines are allowed: + + ashort: h + along: l + abyte: b # a byte + achar: c + astr: 5s + afloat: f; adouble: d # multiple "statements" are allowed + afixed: 16.16F + abool: ? + apad: x + """ + + print("size:", calcsize(fmt)) + + class foo(object): + pass + + i = foo() + + i.ashort = 0x7FFF + i.along = 0x7FFFFFFF + i.abyte = 0x7F + i.achar = "a" + i.astr = "12345" + i.afloat = 0.5 + i.adouble = 0.5 + i.afixed = 1.5 + i.abool = True + + data = pack(fmt, i) + print("data:", repr(data)) + print(unpack(fmt, data)) + i2 = foo() + unpack(fmt, data, i2) + print(vars(i2)) + + +if __name__ == "__main__": + _test() diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/symfont.py b/.venv/lib/python3.13/site-packages/fontTools/misc/symfont.py new file mode 100644 index 0000000000000000000000000000000000000000..9bba2d2d5672a2acdbb0763397288b49a2b7a8de --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/symfont.py @@ -0,0 +1,242 @@ +from fontTools.pens.basePen import BasePen +from functools import partial +from itertools import count +import sympy as sp +import sys + +n = 3 # Max Bezier degree; 3 for cubic, 2 for quadratic + +t, x, y = sp.symbols("t x y", real=True) +c = sp.symbols("c", real=False) # Complex representation instead of x/y + +X = tuple(sp.symbols("x:%d" % (n + 1), real=True)) +Y = tuple(sp.symbols("y:%d" % (n + 1), real=True)) +P = tuple(zip(*(sp.symbols("p:%d[%s]" % (n + 1, w), real=True) for w in "01"))) +C = tuple(sp.symbols("c:%d" % (n + 1), real=False)) + +# Cubic Bernstein basis functions +BinomialCoefficient = [(1, 0)] +for i in range(1, n + 1): + last = BinomialCoefficient[-1] + this = tuple(last[j - 1] + last[j] for j in range(len(last))) + (0,) + BinomialCoefficient.append(this) +BinomialCoefficient = tuple(tuple(item[:-1]) for item in BinomialCoefficient) +del last, this + +BernsteinPolynomial = tuple( + tuple(c * t**i * (1 - t) ** (n - i) for i, c in enumerate(coeffs)) + for n, coeffs in enumerate(BinomialCoefficient) +) + +BezierCurve = tuple( + tuple( + sum(P[i][j] * bernstein for i, bernstein in enumerate(bernsteins)) + for j in range(2) + ) + for n, bernsteins in enumerate(BernsteinPolynomial) +) +BezierCurveC = tuple( + sum(C[i] * bernstein for i, bernstein in enumerate(bernsteins)) + for n, bernsteins in enumerate(BernsteinPolynomial) +) + + +def green(f, curveXY): + f = -sp.integrate(sp.sympify(f), y) + f = f.subs({x: curveXY[0], y: curveXY[1]}) + f = sp.integrate(f * sp.diff(curveXY[0], t), (t, 0, 1)) + return f + + +class _BezierFuncsLazy(dict): + def __init__(self, symfunc): + self._symfunc = symfunc + self._bezfuncs = {} + + def __missing__(self, i): + args = ["p%d" % d for d in range(i + 1)] + f = green(self._symfunc, BezierCurve[i]) + f = sp.gcd_terms(f.collect(sum(P, ()))) # Optimize + return sp.lambdify(args, f) + + +class GreenPen(BasePen): + _BezierFuncs = {} + + @classmethod + def _getGreenBezierFuncs(celf, func): + funcstr = str(func) + if not funcstr in celf._BezierFuncs: + celf._BezierFuncs[funcstr] = _BezierFuncsLazy(func) + return celf._BezierFuncs[funcstr] + + def __init__(self, func, glyphset=None): + BasePen.__init__(self, glyphset) + self._funcs = self._getGreenBezierFuncs(func) + self.value = 0 + + def _moveTo(self, p0): + self._startPoint = p0 + + def _closePath(self): + p0 = self._getCurrentPoint() + if p0 != self._startPoint: + self._lineTo(self._startPoint) + + def _endPath(self): + p0 = self._getCurrentPoint() + if p0 != self._startPoint: + # Green theorem is not defined on open contours. + raise NotImplementedError + + def _lineTo(self, p1): + p0 = self._getCurrentPoint() + self.value += self._funcs[1](p0, p1) + + def _qCurveToOne(self, p1, p2): + p0 = self._getCurrentPoint() + self.value += self._funcs[2](p0, p1, p2) + + def _curveToOne(self, p1, p2, p3): + p0 = self._getCurrentPoint() + self.value += self._funcs[3](p0, p1, p2, p3) + + +# Sample pens. +# Do not use this in real code. +# Use fontTools.pens.momentsPen.MomentsPen instead. +AreaPen = partial(GreenPen, func=1) +MomentXPen = partial(GreenPen, func=x) +MomentYPen = partial(GreenPen, func=y) +MomentXXPen = partial(GreenPen, func=x * x) +MomentYYPen = partial(GreenPen, func=y * y) +MomentXYPen = partial(GreenPen, func=x * y) + + +def printGreenPen(penName, funcs, file=sys.stdout, docstring=None): + if docstring is not None: + print('"""%s"""' % docstring) + + print( + """from fontTools.pens.basePen import BasePen, OpenContourError +try: + import cython +except (AttributeError, ImportError): + # if cython not installed, use mock module with no-op decorators and types + from fontTools.misc import cython +COMPILED = cython.compiled + + +__all__ = ["%s"] + +class %s(BasePen): + + def __init__(self, glyphset=None): + BasePen.__init__(self, glyphset) +""" + % (penName, penName), + file=file, + ) + for name, f in funcs: + print(" self.%s = 0" % name, file=file) + print( + """ + def _moveTo(self, p0): + self._startPoint = p0 + + def _closePath(self): + p0 = self._getCurrentPoint() + if p0 != self._startPoint: + self._lineTo(self._startPoint) + + def _endPath(self): + p0 = self._getCurrentPoint() + if p0 != self._startPoint: + raise OpenContourError( + "Glyph statistics is not defined on open contours." + ) +""", + end="", + file=file, + ) + + for n in (1, 2, 3): + subs = {P[i][j]: [X, Y][j][i] for i in range(n + 1) for j in range(2)} + greens = [green(f, BezierCurve[n]) for name, f in funcs] + greens = [sp.gcd_terms(f.collect(sum(P, ()))) for f in greens] # Optimize + greens = [f.subs(subs) for f in greens] # Convert to p to x/y + defs, exprs = sp.cse( + greens, + optimizations="basic", + symbols=(sp.Symbol("r%d" % i) for i in count()), + ) + + print() + for name, value in defs: + print(" @cython.locals(%s=cython.double)" % name, file=file) + if n == 1: + print( + """\ + @cython.locals(x0=cython.double, y0=cython.double) + @cython.locals(x1=cython.double, y1=cython.double) + def _lineTo(self, p1): + x0,y0 = self._getCurrentPoint() + x1,y1 = p1 +""", + file=file, + ) + elif n == 2: + print( + """\ + @cython.locals(x0=cython.double, y0=cython.double) + @cython.locals(x1=cython.double, y1=cython.double) + @cython.locals(x2=cython.double, y2=cython.double) + def _qCurveToOne(self, p1, p2): + x0,y0 = self._getCurrentPoint() + x1,y1 = p1 + x2,y2 = p2 +""", + file=file, + ) + elif n == 3: + print( + """\ + @cython.locals(x0=cython.double, y0=cython.double) + @cython.locals(x1=cython.double, y1=cython.double) + @cython.locals(x2=cython.double, y2=cython.double) + @cython.locals(x3=cython.double, y3=cython.double) + def _curveToOne(self, p1, p2, p3): + x0,y0 = self._getCurrentPoint() + x1,y1 = p1 + x2,y2 = p2 + x3,y3 = p3 +""", + file=file, + ) + for name, value in defs: + print(" %s = %s" % (name, value), file=file) + + print(file=file) + for name, value in zip([f[0] for f in funcs], exprs): + print(" self.%s += %s" % (name, value), file=file) + + print( + """ +if __name__ == '__main__': + from fontTools.misc.symfont import x, y, printGreenPen + printGreenPen('%s', [""" + % penName, + file=file, + ) + for name, f in funcs: + print(" ('%s', %s)," % (name, str(f)), file=file) + print(" ])", file=file) + + +if __name__ == "__main__": + import sys + + if sys.argv[1:]: + penName = sys.argv[1] + funcs = [(name, eval(f)) for name, f in zip(sys.argv[2::2], sys.argv[3::2])] + printGreenPen(penName, funcs, file=sys.stdout) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/testTools.py b/.venv/lib/python3.13/site-packages/fontTools/misc/testTools.py new file mode 100644 index 0000000000000000000000000000000000000000..e2eaf3833216a996103cfe682009057668768c45 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/testTools.py @@ -0,0 +1,233 @@ +"""Helpers for writing unit tests.""" + +from collections.abc import Iterable +from io import BytesIO +import os +import re +import shutil +import sys +import tempfile +from unittest import TestCase as _TestCase +from fontTools.config import Config +from fontTools.misc.textTools import tobytes +from fontTools.misc.xmlWriter import XMLWriter + + +def parseXML(xmlSnippet): + """Parses a snippet of XML. + + Input can be either a single string (unicode or UTF-8 bytes), or a + a sequence of strings. + + The result is in the same format that would be returned by + XMLReader, but the parser imposes no constraints on the root + element so it can be called on small snippets of TTX files. + """ + # To support snippets with multiple elements, we add a fake root. + reader = TestXMLReader_() + xml = b"" + if isinstance(xmlSnippet, bytes): + xml += xmlSnippet + elif isinstance(xmlSnippet, str): + xml += tobytes(xmlSnippet, "utf-8") + elif isinstance(xmlSnippet, Iterable): + xml += b"".join(tobytes(s, "utf-8") for s in xmlSnippet) + else: + raise TypeError( + "expected string or sequence of strings; found %r" + % type(xmlSnippet).__name__ + ) + xml += b"" + reader.parser.Parse(xml, 1) + return reader.root[2] + + +def parseXmlInto(font, parseInto, xmlSnippet): + parsed_xml = [e for e in parseXML(xmlSnippet.strip()) if not isinstance(e, str)] + for name, attrs, content in parsed_xml: + parseInto.fromXML(name, attrs, content, font) + if hasattr(parseInto, "populateDefaults"): + parseInto.populateDefaults() + return parseInto + + +class FakeFont: + def __init__(self, glyphs): + self.glyphOrder_ = glyphs + self.reverseGlyphOrderDict_ = {g: i for i, g in enumerate(glyphs)} + self.lazy = False + self.tables = {} + self.cfg = Config() + + def __contains__(self, tag): + return tag in self.tables + + def __getitem__(self, tag): + return self.tables[tag] + + def __setitem__(self, tag, table): + self.tables[tag] = table + + def get(self, tag, default=None): + return self.tables.get(tag, default) + + def getGlyphID(self, name): + return self.reverseGlyphOrderDict_[name] + + def getGlyphIDMany(self, lst): + return [self.getGlyphID(gid) for gid in lst] + + def getGlyphName(self, glyphID): + if glyphID < len(self.glyphOrder_): + return self.glyphOrder_[glyphID] + else: + return "glyph%.5d" % glyphID + + def getGlyphNameMany(self, lst): + return [self.getGlyphName(gid) for gid in lst] + + def getGlyphOrder(self): + return self.glyphOrder_ + + def getReverseGlyphMap(self): + return self.reverseGlyphOrderDict_ + + def getGlyphNames(self): + return sorted(self.getGlyphOrder()) + + +class TestXMLReader_(object): + def __init__(self): + from xml.parsers.expat import ParserCreate + + self.parser = ParserCreate() + self.parser.StartElementHandler = self.startElement_ + self.parser.EndElementHandler = self.endElement_ + self.parser.CharacterDataHandler = self.addCharacterData_ + self.root = None + self.stack = [] + + def startElement_(self, name, attrs): + element = (name, attrs, []) + if self.stack: + self.stack[-1][2].append(element) + else: + self.root = element + self.stack.append(element) + + def endElement_(self, name): + self.stack.pop() + + def addCharacterData_(self, data): + self.stack[-1][2].append(data) + + +def makeXMLWriter(newlinestr="\n"): + # don't write OS-specific new lines + writer = XMLWriter(BytesIO(), newlinestr=newlinestr) + # erase XML declaration + writer.file.seek(0) + writer.file.truncate() + return writer + + +def getXML(func, ttFont=None): + """Call the passed toXML function and return the written content as a + list of lines (unicode strings). + Result is stripped of XML declaration and OS-specific newline characters. + """ + writer = makeXMLWriter() + func(writer, ttFont) + xml = writer.file.getvalue().decode("utf-8") + # toXML methods must always end with a writer.newline() + assert xml.endswith("\n") + return xml.splitlines() + + +def stripVariableItemsFromTTX( + string: str, + ttLibVersion: bool = True, + checkSumAdjustment: bool = True, + modified: bool = True, + created: bool = True, + sfntVersion: bool = False, # opt-in only +) -> str: + """Strip stuff like ttLibVersion, checksums, timestamps, etc. from TTX dumps.""" + # ttlib changes with the fontTools version + if ttLibVersion: + string = re.sub(' ttLibVersion="[^"]+"', "", string) + # sometimes (e.g. some subsetter tests) we don't care whether it's OTF or TTF + if sfntVersion: + string = re.sub(' sfntVersion="[^"]+"', "", string) + # head table checksum and creation and mod date changes with each save. + if checkSumAdjustment: + string = re.sub('', "", string) + if modified: + string = re.sub('', "", string) + if created: + string = re.sub('', "", string) + return string + + +class MockFont(object): + """A font-like object that automatically adds any looked up glyphname + to its glyphOrder.""" + + def __init__(self): + self._glyphOrder = [".notdef"] + + class AllocatingDict(dict): + def __missing__(reverseDict, key): + self._glyphOrder.append(key) + gid = len(reverseDict) + reverseDict[key] = gid + return gid + + self._reverseGlyphOrder = AllocatingDict({".notdef": 0}) + self.lazy = False + + def getGlyphID(self, glyph): + gid = self._reverseGlyphOrder[glyph] + return gid + + def getReverseGlyphMap(self): + return self._reverseGlyphOrder + + def getGlyphName(self, gid): + return self._glyphOrder[gid] + + def getGlyphOrder(self): + return self._glyphOrder + + +class TestCase(_TestCase): + def __init__(self, methodName): + _TestCase.__init__(self, methodName) + # Python 3 renamed assertRaisesRegexp to assertRaisesRegex, + # and fires deprecation warnings if a program uses the old name. + if not hasattr(self, "assertRaisesRegex"): + self.assertRaisesRegex = self.assertRaisesRegexp + + +class DataFilesHandler(TestCase): + def setUp(self): + self.tempdir = None + self.num_tempfiles = 0 + + def tearDown(self): + if self.tempdir: + shutil.rmtree(self.tempdir) + + def getpath(self, testfile): + folder = os.path.dirname(sys.modules[self.__module__].__file__) + return os.path.join(folder, "data", testfile) + + def temp_dir(self): + if not self.tempdir: + self.tempdir = tempfile.mkdtemp() + + def temp_font(self, font_path, file_name): + self.temp_dir() + temppath = os.path.join(self.tempdir, file_name) + shutil.copy2(font_path, temppath) + return temppath diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/textTools.py b/.venv/lib/python3.13/site-packages/fontTools/misc/textTools.py new file mode 100644 index 0000000000000000000000000000000000000000..f38cfe4ede5b1176cf14c131059f213e40966478 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/textTools.py @@ -0,0 +1,156 @@ +"""fontTools.misc.textTools.py -- miscellaneous routines.""" + +from __future__ import annotations + +import ast +import string + + +# alias kept for backward compatibility +safeEval = ast.literal_eval + + +class Tag(str): + @staticmethod + def transcode(blob): + if isinstance(blob, bytes): + blob = blob.decode("latin-1") + return blob + + def __new__(self, content): + return str.__new__(self, self.transcode(content)) + + def __ne__(self, other): + return not self.__eq__(other) + + def __eq__(self, other): + return str.__eq__(self, self.transcode(other)) + + def __hash__(self): + return str.__hash__(self) + + def tobytes(self): + return self.encode("latin-1") + + +def readHex(content): + """Convert a list of hex strings to binary data.""" + return deHexStr(strjoin(chunk for chunk in content if isinstance(chunk, str))) + + +def deHexStr(hexdata): + """Convert a hex string to binary data.""" + hexdata = strjoin(hexdata.split()) + if len(hexdata) % 2: + hexdata = hexdata + "0" + data = [] + for i in range(0, len(hexdata), 2): + data.append(bytechr(int(hexdata[i : i + 2], 16))) + return bytesjoin(data) + + +def hexStr(data): + """Convert binary data to a hex string.""" + h = string.hexdigits + r = "" + for c in data: + i = byteord(c) + r = r + h[(i >> 4) & 0xF] + h[i & 0xF] + return r + + +def num2binary(l, bits=32): + items = [] + binary = "" + for i in range(bits): + if l & 0x1: + binary = "1" + binary + else: + binary = "0" + binary + l = l >> 1 + if not ((i + 1) % 8): + items.append(binary) + binary = "" + if binary: + items.append(binary) + items.reverse() + assert l in (0, -1), "number doesn't fit in number of bits" + return " ".join(items) + + +def binary2num(bin): + bin = strjoin(bin.split()) + l = 0 + for digit in bin: + l = l << 1 + if digit != "0": + l = l | 0x1 + return l + + +def caselessSort(alist): + """Return a sorted copy of a list. If there are only strings + in the list, it will not consider case. + """ + + try: + return sorted(alist, key=lambda a: (a.lower(), a)) + except TypeError: + return sorted(alist) + + +def pad(data, size): + r"""Pad byte string 'data' with null bytes until its length is a + multiple of 'size'. + + >>> len(pad(b'abcd', 4)) + 4 + >>> len(pad(b'abcde', 2)) + 6 + >>> len(pad(b'abcde', 4)) + 8 + >>> pad(b'abcdef', 4) == b'abcdef\x00\x00' + True + """ + data = tobytes(data) + if size > 1: + remainder = len(data) % size + if remainder: + data += b"\0" * (size - remainder) + return data + + +def tostr(s: str | bytes, encoding: str = "ascii", errors: str = "strict") -> str: + if not isinstance(s, str): + return s.decode(encoding, errors) + else: + return s + + +def tobytes(s: str | bytes, encoding: str = "ascii", errors: str = "strict") -> bytes: + if isinstance(s, str): + return s.encode(encoding, errors) + else: + return bytes(s) + + +def bytechr(n): + return bytes([n]) + + +def byteord(c): + return c if isinstance(c, int) else ord(c) + + +def strjoin(iterable, joiner=""): + return tostr(joiner).join(iterable) + + +def bytesjoin(iterable, joiner=b""): + return tobytes(joiner).join(tobytes(item) for item in iterable) + + +if __name__ == "__main__": + import doctest, sys + + sys.exit(doctest.testmod().failed) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/transform.py b/.venv/lib/python3.13/site-packages/fontTools/misc/transform.py new file mode 100644 index 0000000000000000000000000000000000000000..aeacc30fcb183cee3f47310ebf4606d69184cdc1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/transform.py @@ -0,0 +1,516 @@ +"""Affine 2D transformation matrix class. + +The Transform class implements various transformation matrix operations, +both on the matrix itself, as well as on 2D coordinates. + +Transform instances are effectively immutable: all methods that operate on the +transformation itself always return a new instance. This has as the +interesting side effect that Transform instances are hashable, ie. they can be +used as dictionary keys. + +This module exports the following symbols: + +Transform + this is the main class +Identity + Transform instance set to the identity transformation +Offset + Convenience function that returns a translating transformation +Scale + Convenience function that returns a scaling transformation + +The DecomposedTransform class implements a transformation with separate +translate, rotation, scale, skew, and transformation-center components. + +:Example: + + >>> t = Transform(2, 0, 0, 3, 0, 0) + >>> t.transformPoint((100, 100)) + (200, 300) + >>> t = Scale(2, 3) + >>> t.transformPoint((100, 100)) + (200, 300) + >>> t.transformPoint((0, 0)) + (0, 0) + >>> t = Offset(2, 3) + >>> t.transformPoint((100, 100)) + (102, 103) + >>> t.transformPoint((0, 0)) + (2, 3) + >>> t2 = t.scale(0.5) + >>> t2.transformPoint((100, 100)) + (52.0, 53.0) + >>> import math + >>> t3 = t2.rotate(math.pi / 2) + >>> t3.transformPoint((0, 0)) + (2.0, 3.0) + >>> t3.transformPoint((100, 100)) + (-48.0, 53.0) + >>> t = Identity.scale(0.5).translate(100, 200).skew(0.1, 0.2) + >>> t.transformPoints([(0, 0), (1, 1), (100, 100)]) + [(50.0, 100.0), (50.550167336042726, 100.60135501775433), (105.01673360427253, 160.13550177543362)] + >>> +""" + +from __future__ import annotations + +import math +from typing import NamedTuple +from dataclasses import dataclass + + +__all__ = ["Transform", "Identity", "Offset", "Scale", "DecomposedTransform"] + + +_EPSILON = 1e-15 +_ONE_EPSILON = 1 - _EPSILON +_MINUS_ONE_EPSILON = -1 + _EPSILON + + +def _normSinCos(v: float) -> float: + if abs(v) < _EPSILON: + v = 0 + elif v > _ONE_EPSILON: + v = 1 + elif v < _MINUS_ONE_EPSILON: + v = -1 + return v + + +class Transform(NamedTuple): + """2x2 transformation matrix plus offset, a.k.a. Affine transform. + Transform instances are immutable: all transforming methods, eg. + rotate(), return a new Transform instance. + + :Example: + + >>> t = Transform() + >>> t + + >>> t.scale(2) + + >>> t.scale(2.5, 5.5) + + >>> + >>> t.scale(2, 3).transformPoint((100, 100)) + (200, 300) + + Transform's constructor takes six arguments, all of which are + optional, and can be used as keyword arguments:: + + >>> Transform(12) + + >>> Transform(dx=12) + + >>> Transform(yx=12) + + + Transform instances also behave like sequences of length 6:: + + >>> len(Identity) + 6 + >>> list(Identity) + [1, 0, 0, 1, 0, 0] + >>> tuple(Identity) + (1, 0, 0, 1, 0, 0) + + Transform instances are comparable:: + + >>> t1 = Identity.scale(2, 3).translate(4, 6) + >>> t2 = Identity.translate(8, 18).scale(2, 3) + >>> t1 == t2 + 1 + + But beware of floating point rounding errors:: + + >>> t1 = Identity.scale(0.2, 0.3).translate(0.4, 0.6) + >>> t2 = Identity.translate(0.08, 0.18).scale(0.2, 0.3) + >>> t1 + + >>> t2 + + >>> t1 == t2 + 0 + + Transform instances are hashable, meaning you can use them as + keys in dictionaries:: + + >>> d = {Scale(12, 13): None} + >>> d + {: None} + + But again, beware of floating point rounding errors:: + + >>> t1 = Identity.scale(0.2, 0.3).translate(0.4, 0.6) + >>> t2 = Identity.translate(0.08, 0.18).scale(0.2, 0.3) + >>> t1 + + >>> t2 + + >>> d = {t1: None} + >>> d + {: None} + >>> d[t2] + Traceback (most recent call last): + File "", line 1, in ? + KeyError: + """ + + xx: float = 1 + xy: float = 0 + yx: float = 0 + yy: float = 1 + dx: float = 0 + dy: float = 0 + + def transformPoint(self, p): + """Transform a point. + + :Example: + + >>> t = Transform() + >>> t = t.scale(2.5, 5.5) + >>> t.transformPoint((100, 100)) + (250.0, 550.0) + """ + (x, y) = p + xx, xy, yx, yy, dx, dy = self + return (xx * x + yx * y + dx, xy * x + yy * y + dy) + + def transformPoints(self, points): + """Transform a list of points. + + :Example: + + >>> t = Scale(2, 3) + >>> t.transformPoints([(0, 0), (0, 100), (100, 100), (100, 0)]) + [(0, 0), (0, 300), (200, 300), (200, 0)] + >>> + """ + xx, xy, yx, yy, dx, dy = self + return [(xx * x + yx * y + dx, xy * x + yy * y + dy) for x, y in points] + + def transformVector(self, v): + """Transform an (dx, dy) vector, treating translation as zero. + + :Example: + + >>> t = Transform(2, 0, 0, 2, 10, 20) + >>> t.transformVector((3, -4)) + (6, -8) + >>> + """ + (dx, dy) = v + xx, xy, yx, yy = self[:4] + return (xx * dx + yx * dy, xy * dx + yy * dy) + + def transformVectors(self, vectors): + """Transform a list of (dx, dy) vector, treating translation as zero. + + :Example: + >>> t = Transform(2, 0, 0, 2, 10, 20) + >>> t.transformVectors([(3, -4), (5, -6)]) + [(6, -8), (10, -12)] + >>> + """ + xx, xy, yx, yy = self[:4] + return [(xx * dx + yx * dy, xy * dx + yy * dy) for dx, dy in vectors] + + def translate(self, x: float = 0, y: float = 0): + """Return a new transformation, translated (offset) by x, y. + + :Example: + >>> t = Transform() + >>> t.translate(20, 30) + + >>> + """ + return self.transform((1, 0, 0, 1, x, y)) + + def scale(self, x: float = 1, y: float | None = None): + """Return a new transformation, scaled by x, y. The 'y' argument + may be None, which implies to use the x value for y as well. + + :Example: + >>> t = Transform() + >>> t.scale(5) + + >>> t.scale(5, 6) + + >>> + """ + if y is None: + y = x + return self.transform((x, 0, 0, y, 0, 0)) + + def rotate(self, angle: float): + """Return a new transformation, rotated by 'angle' (radians). + + :Example: + >>> import math + >>> t = Transform() + >>> t.rotate(math.pi / 2) + + >>> + """ + c = _normSinCos(math.cos(angle)) + s = _normSinCos(math.sin(angle)) + return self.transform((c, s, -s, c, 0, 0)) + + def skew(self, x: float = 0, y: float = 0): + """Return a new transformation, skewed by x and y. + + :Example: + >>> import math + >>> t = Transform() + >>> t.skew(math.pi / 4) + + >>> + """ + return self.transform((1, math.tan(y), math.tan(x), 1, 0, 0)) + + def transform(self, other): + """Return a new transformation, transformed by another + transformation. + + :Example: + >>> t = Transform(2, 0, 0, 3, 1, 6) + >>> t.transform((4, 3, 2, 1, 5, 6)) + + >>> + """ + xx1, xy1, yx1, yy1, dx1, dy1 = other + xx2, xy2, yx2, yy2, dx2, dy2 = self + return self.__class__( + xx1 * xx2 + xy1 * yx2, + xx1 * xy2 + xy1 * yy2, + yx1 * xx2 + yy1 * yx2, + yx1 * xy2 + yy1 * yy2, + xx2 * dx1 + yx2 * dy1 + dx2, + xy2 * dx1 + yy2 * dy1 + dy2, + ) + + def reverseTransform(self, other): + """Return a new transformation, which is the other transformation + transformed by self. self.reverseTransform(other) is equivalent to + other.transform(self). + + :Example: + >>> t = Transform(2, 0, 0, 3, 1, 6) + >>> t.reverseTransform((4, 3, 2, 1, 5, 6)) + + >>> Transform(4, 3, 2, 1, 5, 6).transform((2, 0, 0, 3, 1, 6)) + + >>> + """ + xx1, xy1, yx1, yy1, dx1, dy1 = self + xx2, xy2, yx2, yy2, dx2, dy2 = other + return self.__class__( + xx1 * xx2 + xy1 * yx2, + xx1 * xy2 + xy1 * yy2, + yx1 * xx2 + yy1 * yx2, + yx1 * xy2 + yy1 * yy2, + xx2 * dx1 + yx2 * dy1 + dx2, + xy2 * dx1 + yy2 * dy1 + dy2, + ) + + def inverse(self): + """Return the inverse transformation. + + :Example: + >>> t = Identity.translate(2, 3).scale(4, 5) + >>> t.transformPoint((10, 20)) + (42, 103) + >>> it = t.inverse() + >>> it.transformPoint((42, 103)) + (10.0, 20.0) + >>> + """ + if self == Identity: + return self + xx, xy, yx, yy, dx, dy = self + det = xx * yy - yx * xy + xx, xy, yx, yy = yy / det, -xy / det, -yx / det, xx / det + dx, dy = -xx * dx - yx * dy, -xy * dx - yy * dy + return self.__class__(xx, xy, yx, yy, dx, dy) + + def toPS(self) -> str: + """Return a PostScript representation + + :Example: + + >>> t = Identity.scale(2, 3).translate(4, 5) + >>> t.toPS() + '[2 0 0 3 8 15]' + >>> + """ + return "[%s %s %s %s %s %s]" % self + + def toDecomposed(self) -> "DecomposedTransform": + """Decompose into a DecomposedTransform.""" + return DecomposedTransform.fromTransform(self) + + def __bool__(self) -> bool: + """Returns True if transform is not identity, False otherwise. + + :Example: + + >>> bool(Identity) + False + >>> bool(Transform()) + False + >>> bool(Scale(1.)) + False + >>> bool(Scale(2)) + True + >>> bool(Offset()) + False + >>> bool(Offset(0)) + False + >>> bool(Offset(2)) + True + """ + return self != Identity + + def __repr__(self) -> str: + return "<%s [%g %g %g %g %g %g]>" % ((self.__class__.__name__,) + self) + + +Identity = Transform() + + +def Offset(x: float = 0, y: float = 0) -> Transform: + """Return the identity transformation offset by x, y. + + :Example: + >>> Offset(2, 3) + + >>> + """ + return Transform(1, 0, 0, 1, x, y) + + +def Scale(x: float, y: float | None = None) -> Transform: + """Return the identity transformation scaled by x, y. The 'y' argument + may be None, which implies to use the x value for y as well. + + :Example: + >>> Scale(2, 3) + + >>> + """ + if y is None: + y = x + return Transform(x, 0, 0, y, 0, 0) + + +@dataclass +class DecomposedTransform: + """The DecomposedTransform class implements a transformation with separate + translate, rotation, scale, skew, and transformation-center components. + """ + + translateX: float = 0 + translateY: float = 0 + rotation: float = 0 # in degrees, counter-clockwise + scaleX: float = 1 + scaleY: float = 1 + skewX: float = 0 # in degrees, clockwise + skewY: float = 0 # in degrees, counter-clockwise + tCenterX: float = 0 + tCenterY: float = 0 + + def __bool__(self): + return ( + self.translateX != 0 + or self.translateY != 0 + or self.rotation != 0 + or self.scaleX != 1 + or self.scaleY != 1 + or self.skewX != 0 + or self.skewY != 0 + or self.tCenterX != 0 + or self.tCenterY != 0 + ) + + @classmethod + def fromTransform(self, transform): + """Return a DecomposedTransform() equivalent of this transformation. + The returned solution always has skewY = 0, and angle in the (-180, 180]. + + :Example: + >>> DecomposedTransform.fromTransform(Transform(3, 0, 0, 2, 0, 0)) + DecomposedTransform(translateX=0, translateY=0, rotation=0.0, scaleX=3.0, scaleY=2.0, skewX=0.0, skewY=0.0, tCenterX=0, tCenterY=0) + >>> DecomposedTransform.fromTransform(Transform(0, 0, 0, 1, 0, 0)) + DecomposedTransform(translateX=0, translateY=0, rotation=0.0, scaleX=0.0, scaleY=1.0, skewX=0.0, skewY=0.0, tCenterX=0, tCenterY=0) + >>> DecomposedTransform.fromTransform(Transform(0, 0, 1, 1, 0, 0)) + DecomposedTransform(translateX=0, translateY=0, rotation=-45.0, scaleX=0.0, scaleY=1.4142135623730951, skewX=0.0, skewY=0.0, tCenterX=0, tCenterY=0) + """ + # Adapted from an answer on + # https://math.stackexchange.com/questions/13150/extracting-rotation-scale-values-from-2d-transformation-matrix + + a, b, c, d, x, y = transform + + sx = math.copysign(1, a) + if sx < 0: + a *= sx + b *= sx + + delta = a * d - b * c + + rotation = 0 + scaleX = scaleY = 0 + skewX = 0 + + # Apply the QR-like decomposition. + if a != 0 or b != 0: + r = math.sqrt(a * a + b * b) + rotation = math.acos(a / r) if b >= 0 else -math.acos(a / r) + scaleX, scaleY = (r, delta / r) + skewX = math.atan((a * c + b * d) / (r * r)) + elif c != 0 or d != 0: + s = math.sqrt(c * c + d * d) + rotation = math.pi / 2 - ( + math.acos(-c / s) if d >= 0 else -math.acos(c / s) + ) + scaleX, scaleY = (delta / s, s) + else: + # a = b = c = d = 0 + pass + + return DecomposedTransform( + x, + y, + math.degrees(rotation), + scaleX * sx, + scaleY, + math.degrees(skewX) * sx, + 0.0, + 0, + 0, + ) + + def toTransform(self) -> Transform: + """Return the Transform() equivalent of this transformation. + + :Example: + >>> DecomposedTransform(scaleX=2, scaleY=2).toTransform() + + >>> + """ + t = Transform() + t = t.translate( + self.translateX + self.tCenterX, self.translateY + self.tCenterY + ) + t = t.rotate(math.radians(self.rotation)) + t = t.scale(self.scaleX, self.scaleY) + t = t.skew(math.radians(self.skewX), math.radians(self.skewY)) + t = t.translate(-self.tCenterX, -self.tCenterY) + return t + + +if __name__ == "__main__": + import sys + import doctest + + sys.exit(doctest.testmod().failed) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/treeTools.py b/.venv/lib/python3.13/site-packages/fontTools/misc/treeTools.py new file mode 100644 index 0000000000000000000000000000000000000000..24e10ba5b19ef41d56a552527680a4c73503cc3c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/treeTools.py @@ -0,0 +1,45 @@ +"""Generic tools for working with trees.""" + +from math import ceil, log + + +def build_n_ary_tree(leaves, n): + """Build N-ary tree from sequence of leaf nodes. + + Return a list of lists where each non-leaf node is a list containing + max n nodes. + """ + if not leaves: + return [] + + assert n > 1 + + depth = ceil(log(len(leaves), n)) + + if depth <= 1: + return list(leaves) + + # Fully populate complete subtrees of root until we have enough leaves left + root = [] + unassigned = None + full_step = n ** (depth - 1) + for i in range(0, len(leaves), full_step): + subtree = leaves[i : i + full_step] + if len(subtree) < full_step: + unassigned = subtree + break + while len(subtree) > n: + subtree = [subtree[k : k + n] for k in range(0, len(subtree), n)] + root.append(subtree) + + if unassigned: + # Recurse to fill the last subtree, which is the only partially populated one + subtree = build_n_ary_tree(unassigned, n) + if len(subtree) <= n - len(root): + # replace last subtree with its children if they can still fit + root.extend(subtree) + else: + root.append(subtree) + assert len(root) <= n + + return root diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/vector.py b/.venv/lib/python3.13/site-packages/fontTools/misc/vector.py new file mode 100644 index 0000000000000000000000000000000000000000..02c62e6512a04f3497f7c9987a1f414b30cf6b05 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/vector.py @@ -0,0 +1,147 @@ +from numbers import Number +import math +import operator +import warnings + + +__all__ = ["Vector"] + + +class Vector(tuple): + """A math-like vector. + + Represents an n-dimensional numeric vector. ``Vector`` objects support + vector addition and subtraction, scalar multiplication and division, + negation, rounding, and comparison tests. + """ + + __slots__ = () + + def __new__(cls, values, keep=False): + if keep is not False: + warnings.warn( + "the 'keep' argument has been deprecated", + DeprecationWarning, + ) + if type(values) == Vector: + # No need to create a new object + return values + return super().__new__(cls, values) + + def __repr__(self): + return f"{self.__class__.__name__}({super().__repr__()})" + + def _vectorOp(self, other, op): + if isinstance(other, Vector): + assert len(self) == len(other) + return self.__class__(op(a, b) for a, b in zip(self, other)) + if isinstance(other, Number): + return self.__class__(op(v, other) for v in self) + raise NotImplementedError() + + def _scalarOp(self, other, op): + if isinstance(other, Number): + return self.__class__(op(v, other) for v in self) + raise NotImplementedError() + + def _unaryOp(self, op): + return self.__class__(op(v) for v in self) + + def __add__(self, other): + return self._vectorOp(other, operator.add) + + __radd__ = __add__ + + def __sub__(self, other): + return self._vectorOp(other, operator.sub) + + def __rsub__(self, other): + return self._vectorOp(other, _operator_rsub) + + def __mul__(self, other): + return self._scalarOp(other, operator.mul) + + __rmul__ = __mul__ + + def __truediv__(self, other): + return self._scalarOp(other, operator.truediv) + + def __rtruediv__(self, other): + return self._scalarOp(other, _operator_rtruediv) + + def __pos__(self): + return self._unaryOp(operator.pos) + + def __neg__(self): + return self._unaryOp(operator.neg) + + def __round__(self, *, round=round): + return self._unaryOp(round) + + def __eq__(self, other): + if isinstance(other, list): + # bw compat Vector([1, 2, 3]) == [1, 2, 3] + other = tuple(other) + return super().__eq__(other) + + def __ne__(self, other): + return not self.__eq__(other) + + def __bool__(self): + return any(self) + + __nonzero__ = __bool__ + + def __abs__(self): + return math.sqrt(sum(x * x for x in self)) + + def length(self): + """Return the length of the vector. Equivalent to abs(vector).""" + return abs(self) + + def normalized(self): + """Return the normalized vector of the vector.""" + return self / abs(self) + + def dot(self, other): + """Performs vector dot product, returning the sum of + ``a[0] * b[0], a[1] * b[1], ...``""" + assert len(self) == len(other) + return sum(a * b for a, b in zip(self, other)) + + # Deprecated methods/properties + + def toInt(self): + warnings.warn( + "the 'toInt' method has been deprecated, use round(vector) instead", + DeprecationWarning, + ) + return self.__round__() + + @property + def values(self): + warnings.warn( + "the 'values' attribute has been deprecated, use " + "the vector object itself instead", + DeprecationWarning, + ) + return list(self) + + @values.setter + def values(self, values): + raise AttributeError( + "can't set attribute, the 'values' attribute has been deprecated", + ) + + def isclose(self, other: "Vector", **kwargs) -> bool: + """Return True if the vector is close to another Vector.""" + assert len(self) == len(other) + return all(math.isclose(a, b, **kwargs) for a, b in zip(self, other)) + + +def _operator_rsub(a, b): + return operator.sub(b, a) + + +def _operator_rtruediv(a, b): + return operator.truediv(b, a) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/visitor.py b/.venv/lib/python3.13/site-packages/fontTools/misc/visitor.py new file mode 100644 index 0000000000000000000000000000000000000000..20381f91cb6b7136985dd6d88f759477f8df65b4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/visitor.py @@ -0,0 +1,158 @@ +"""Generic visitor pattern implementation for Python objects.""" + +import enum +import weakref + + +class Visitor(object): + defaultStop = False + + _visitors = { + # By default we skip visiting weak references to avoid recursion + # issues. Users can override this by registering a visit + # function for weakref.ProxyType. + weakref.ProxyType: {None: lambda self, obj, *args, **kwargs: False} + } + + @classmethod + def _register(celf, clazzes_attrs): + assert celf != Visitor, "Subclass Visitor instead." + if "_visitors" not in celf.__dict__: + celf._visitors = {} + + def wrapper(method): + assert method.__name__ == "visit" + for clazzes, attrs in clazzes_attrs: + if type(clazzes) != tuple: + clazzes = (clazzes,) + if type(attrs) == str: + attrs = (attrs,) + for clazz in clazzes: + _visitors = celf._visitors.setdefault(clazz, {}) + for attr in attrs: + assert attr not in _visitors, ( + "Oops, class '%s' has visitor function for '%s' defined already." + % (clazz.__name__, attr) + ) + _visitors[attr] = method + return None + + return wrapper + + @classmethod + def register(celf, clazzes): + if type(clazzes) != tuple: + clazzes = (clazzes,) + return celf._register([(clazzes, (None,))]) + + @classmethod + def register_attr(celf, clazzes, attrs): + clazzes_attrs = [] + if type(clazzes) != tuple: + clazzes = (clazzes,) + if type(attrs) == str: + attrs = (attrs,) + for clazz in clazzes: + clazzes_attrs.append((clazz, attrs)) + return celf._register(clazzes_attrs) + + @classmethod + def register_attrs(celf, clazzes_attrs): + return celf._register(clazzes_attrs) + + @classmethod + def _visitorsFor(celf, thing, _default={}): + typ = type(thing) + + for celf in celf.mro(): + _visitors = getattr(celf, "_visitors", None) + if _visitors is None: + break + + for base in typ.mro(): + m = celf._visitors.get(base, None) + if m is not None: + return m + + return _default + + def visitObject(self, obj, *args, **kwargs): + """Called to visit an object. This function loops over all non-private + attributes of the objects and calls any user-registered (via + ``@register_attr()`` or ``@register_attrs()``) ``visit()`` functions. + + The visitor will proceed to call ``self.visitAttr()``, unless there is a + user-registered visit function and: + + * It returns ``False``; or + * It returns ``None`` (or doesn't return anything) and + ``visitor.defaultStop`` is ``True`` (non-default). + """ + + keys = sorted(vars(obj).keys()) + _visitors = self._visitorsFor(obj) + defaultVisitor = _visitors.get("*", None) + for key in keys: + if key[0] == "_": + continue + value = getattr(obj, key) + visitorFunc = _visitors.get(key, defaultVisitor) + if visitorFunc is not None: + ret = visitorFunc(self, obj, key, value, *args, **kwargs) + if ret == False or (ret is None and self.defaultStop): + continue + self.visitAttr(obj, key, value, *args, **kwargs) + + def visitAttr(self, obj, attr, value, *args, **kwargs): + """Called to visit an attribute of an object.""" + self.visit(value, *args, **kwargs) + + def visitList(self, obj, *args, **kwargs): + """Called to visit any value that is a list.""" + for value in obj: + self.visit(value, *args, **kwargs) + + def visitDict(self, obj, *args, **kwargs): + """Called to visit any value that is a dictionary.""" + for value in obj.values(): + self.visit(value, *args, **kwargs) + + def visitLeaf(self, obj, *args, **kwargs): + """Called to visit any value that is not an object, list, + or dictionary.""" + pass + + def visit(self, obj, *args, **kwargs): + """This is the main entry to the visitor. The visitor will visit object + ``obj``. + + The visitor will first determine if there is a registered (via + ``@register()``) visit function for the type of object. If there is, it + will be called, and ``(visitor, obj, *args, **kwargs)`` will be passed + to the user visit function. + + The visitor will not recurse if there is a user-registered visit + function and: + + * It returns ``False``; or + * It returns ``None`` (or doesn't return anything) and + ``visitor.defaultStop`` is ``True`` (non-default) + + Otherwise, the visitor will proceed to dispatch to one of + ``self.visitObject()``, ``self.visitList()``, ``self.visitDict()``, or + ``self.visitLeaf()`` (any of which can be overriden in a subclass). + """ + + visitorFunc = self._visitorsFor(obj).get(None, None) + if visitorFunc is not None: + ret = visitorFunc(self, obj, *args, **kwargs) + if ret == False or (ret is None and self.defaultStop): + return + if hasattr(obj, "__dict__") and not isinstance(obj, enum.Enum): + self.visitObject(obj, *args, **kwargs) + elif isinstance(obj, list): + self.visitList(obj, *args, **kwargs) + elif isinstance(obj, dict): + self.visitDict(obj, *args, **kwargs) + else: + self.visitLeaf(obj, *args, **kwargs) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/xmlReader.py b/.venv/lib/python3.13/site-packages/fontTools/misc/xmlReader.py new file mode 100644 index 0000000000000000000000000000000000000000..d8e502f141e9cb5df6ea11352b565c9a9cd4aa3d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/xmlReader.py @@ -0,0 +1,188 @@ +from fontTools import ttLib +from fontTools.misc.textTools import safeEval +from fontTools.ttLib.tables.DefaultTable import DefaultTable +import sys +import os +import logging + + +log = logging.getLogger(__name__) + + +class TTXParseError(Exception): + pass + + +BUFSIZE = 0x4000 + + +class XMLReader(object): + def __init__( + self, fileOrPath, ttFont, progress=None, quiet=None, contentOnly=False + ): + if fileOrPath == "-": + fileOrPath = sys.stdin + if not hasattr(fileOrPath, "read"): + self.file = open(fileOrPath, "rb") + self._closeStream = True + else: + # assume readable file object + self.file = fileOrPath + self._closeStream = False + self.ttFont = ttFont + self.progress = progress + if quiet is not None: + from fontTools.misc.loggingTools import deprecateArgument + + deprecateArgument("quiet", "configure logging instead") + self.quiet = quiet + self.root = None + self.contentStack = [] + self.contentOnly = contentOnly + self.stackSize = 0 + + def read(self, rootless=False): + if rootless: + self.stackSize += 1 + if self.progress: + self.file.seek(0, 2) + fileSize = self.file.tell() + self.progress.set(0, fileSize // 100 or 1) + self.file.seek(0) + self._parseFile(self.file) + if self._closeStream: + self.close() + if rootless: + self.stackSize -= 1 + + def close(self): + self.file.close() + + def _parseFile(self, file): + from xml.parsers.expat import ParserCreate + + parser = ParserCreate() + parser.StartElementHandler = self._startElementHandler + parser.EndElementHandler = self._endElementHandler + parser.CharacterDataHandler = self._characterDataHandler + + pos = 0 + while True: + chunk = file.read(BUFSIZE) + if not chunk: + parser.Parse(chunk, 1) + break + pos = pos + len(chunk) + if self.progress: + self.progress.set(pos // 100) + parser.Parse(chunk, 0) + + def _startElementHandler(self, name, attrs): + if self.stackSize == 1 and self.contentOnly: + # We already know the table we're parsing, skip + # parsing the table tag and continue to + # stack '2' which begins parsing content + self.contentStack.append([]) + self.stackSize = 2 + return + stackSize = self.stackSize + self.stackSize = stackSize + 1 + subFile = attrs.get("src") + if subFile is not None: + if hasattr(self.file, "name"): + # if file has a name, get its parent directory + dirname = os.path.dirname(self.file.name) + else: + # else fall back to using the current working directory + dirname = os.getcwd() + subFile = os.path.join(dirname, subFile) + if not stackSize: + if name != "ttFont": + raise TTXParseError("illegal root tag: %s" % name) + if self.ttFont.reader is None and not self.ttFont.tables: + sfntVersion = attrs.get("sfntVersion") + if sfntVersion is not None: + if len(sfntVersion) != 4: + sfntVersion = safeEval('"' + sfntVersion + '"') + self.ttFont.sfntVersion = sfntVersion + self.contentStack.append([]) + elif stackSize == 1: + if subFile is not None: + subReader = XMLReader(subFile, self.ttFont, self.progress) + subReader.read() + self.contentStack.append([]) + return + tag = ttLib.xmlToTag(name) + msg = "Parsing '%s' table..." % tag + if self.progress: + self.progress.setLabel(msg) + log.info(msg) + if tag == "GlyphOrder": + tableClass = ttLib.GlyphOrder + elif "ERROR" in attrs or ("raw" in attrs and safeEval(attrs["raw"])): + tableClass = DefaultTable + else: + tableClass = ttLib.getTableClass(tag) + if tableClass is None: + tableClass = DefaultTable + if tag == "loca" and tag in self.ttFont: + # Special-case the 'loca' table as we need the + # original if the 'glyf' table isn't recompiled. + self.currentTable = self.ttFont[tag] + else: + self.currentTable = tableClass(tag) + self.ttFont[tag] = self.currentTable + self.contentStack.append([]) + elif stackSize == 2 and subFile is not None: + subReader = XMLReader(subFile, self.ttFont, self.progress, contentOnly=True) + subReader.read() + self.contentStack.append([]) + self.root = subReader.root + elif stackSize == 2: + self.contentStack.append([]) + self.root = (name, attrs, self.contentStack[-1]) + else: + l = [] + self.contentStack[-1].append((name, attrs, l)) + self.contentStack.append(l) + + def _characterDataHandler(self, data): + if self.stackSize > 1: + # parser parses in chunks, so we may get multiple calls + # for the same text node; thus we need to append the data + # to the last item in the content stack: + # https://github.com/fonttools/fonttools/issues/2614 + if ( + data != "\n" + and self.contentStack[-1] + and isinstance(self.contentStack[-1][-1], str) + and self.contentStack[-1][-1] != "\n" + ): + self.contentStack[-1][-1] += data + else: + self.contentStack[-1].append(data) + + def _endElementHandler(self, name): + self.stackSize = self.stackSize - 1 + del self.contentStack[-1] + if not self.contentOnly: + if self.stackSize == 1: + self.root = None + elif self.stackSize == 2: + name, attrs, content = self.root + self.currentTable.fromXML(name, attrs, content, self.ttFont) + self.root = None + + +class ProgressPrinter(object): + def __init__(self, title, maxval=100): + print(title) + + def set(self, val, maxval=None): + pass + + def increment(self, val=1): + pass + + def setLabel(self, text): + print(text) diff --git a/.venv/lib/python3.13/site-packages/fontTools/misc/xmlWriter.py b/.venv/lib/python3.13/site-packages/fontTools/misc/xmlWriter.py new file mode 100644 index 0000000000000000000000000000000000000000..0553e885e7450a2c422b5fd5d362a03f4d7d3120 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/misc/xmlWriter.py @@ -0,0 +1,240 @@ +"""xmlWriter.py -- Simple XML authoring class""" + +from __future__ import annotations + +from typing import BinaryIO, Callable, TextIO +from fontTools.misc.textTools import byteord, strjoin, tobytes, tostr +import sys +import os +import string +import logging +import itertools + +INDENT = " " +TTX_LOG = logging.getLogger("fontTools.ttx") +REPLACEMENT = "?" +ILLEGAL_XML_CHARS = dict.fromkeys( + itertools.chain( + range(0x00, 0x09), + (0x0B, 0x0C), + range(0x0E, 0x20), + range(0xD800, 0xE000), + (0xFFFE, 0xFFFF), + ), + REPLACEMENT, +) + + +class XMLWriter(object): + def __init__( + self, + fileOrPath: str | os.PathLike[str] | BinaryIO | TextIO, + indentwhite: str = INDENT, + idlefunc: Callable[[], None] | None = None, + encoding: str = "utf_8", + newlinestr: str | bytes = "\n", + ) -> None: + if encoding.lower().replace("-", "").replace("_", "") != "utf8": + raise Exception("Only UTF-8 encoding is supported.") + if fileOrPath == "-": + fileOrPath = sys.stdout + self.filename: str | os.PathLike[str] | None + if not hasattr(fileOrPath, "write"): + if not isinstance(fileOrPath, (str, os.PathLike)): + raise TypeError( + "fileOrPath must be a file path (str or PathLike) if it isn't an object with a `write` method." + ) + self.filename = fileOrPath + self.file = open(fileOrPath, "wb") + self._closeStream = True + else: + self.filename = None + # assume writable file object + self.file = fileOrPath + self._closeStream = False + + # Figure out if writer expects bytes or unicodes + try: + # The bytes check should be first. See: + # https://github.com/fonttools/fonttools/pull/233 + self.file.write(b"") + self.totype = tobytes + except TypeError: + # This better not fail. + self.file.write("") + self.totype = tostr + self.indentwhite = self.totype(indentwhite) + if newlinestr is None: + self.newlinestr = self.totype(os.linesep) + else: + self.newlinestr = self.totype(newlinestr) + self.indentlevel = 0 + self.stack = [] + self.needindent = 1 + self.idlefunc = idlefunc + self.idlecounter = 0 + self._writeraw('') + self.newline() + + def __enter__(self): + return self + + def __exit__(self, exception_type, exception_value, traceback): + self.close() + + def close(self) -> None: + if self._closeStream: + assert not isinstance(self.file, (str, os.PathLike)) + self.file.close() + + def write(self, string, indent=True): + """Writes text.""" + self._writeraw(escape(string), indent=indent) + + def writecdata(self, string): + """Writes text in a CDATA section.""" + self._writeraw("") + + def write8bit(self, data, strip=False): + """Writes a bytes() sequence into the XML, escaping + non-ASCII bytes. When this is read in xmlReader, + the original bytes can be recovered by encoding to + 'latin-1'.""" + self._writeraw(escape8bit(data), strip=strip) + + def write_noindent(self, string): + """Writes text without indentation.""" + self._writeraw(escape(string), indent=False) + + def _writeraw(self, data, indent=True, strip=False): + """Writes bytes, possibly indented.""" + if indent and self.needindent: + self.file.write(self.indentlevel * self.indentwhite) + self.needindent = 0 + s = self.totype(data, encoding="utf_8") + if strip: + s = s.strip() + self.file.write(s) + + def newline(self): + self.file.write(self.newlinestr) + self.needindent = 1 + idlecounter = self.idlecounter + if not idlecounter % 100 and self.idlefunc is not None: + self.idlefunc() + self.idlecounter = idlecounter + 1 + + def comment(self, data): + data = escape(data) + lines = data.split("\n") + self._writeraw("") + + def simpletag(self, _TAG_, *args, **kwargs): + attrdata = self.stringifyattrs(*args, **kwargs) + data = "<%s%s/>" % (_TAG_, attrdata) + self._writeraw(data) + + def begintag(self, _TAG_, *args, **kwargs): + attrdata = self.stringifyattrs(*args, **kwargs) + data = "<%s%s>" % (_TAG_, attrdata) + self._writeraw(data) + self.stack.append(_TAG_) + self.indent() + + def endtag(self, _TAG_): + assert self.stack and self.stack[-1] == _TAG_, "nonmatching endtag" + del self.stack[-1] + self.dedent() + data = "" % _TAG_ + self._writeraw(data) + + def dumphex(self, data): + linelength = 16 + hexlinelength = linelength * 2 + chunksize = 8 + for i in range(0, len(data), linelength): + hexline = hexStr(data[i : i + linelength]) + line = "" + white = "" + for j in range(0, hexlinelength, chunksize): + line = line + white + hexline[j : j + chunksize] + white = " " + self._writeraw(line) + self.newline() + + def indent(self): + self.indentlevel = self.indentlevel + 1 + + def dedent(self): + assert self.indentlevel > 0 + self.indentlevel = self.indentlevel - 1 + + def stringifyattrs(self, *args, **kwargs): + if kwargs: + assert not args + attributes = sorted(kwargs.items()) + elif args: + assert len(args) == 1 + attributes = args[0] + else: + return "" + data = "" + for attr, value in attributes: + if not isinstance(value, (bytes, str)): + value = str(value) + data = data + ' %s="%s"' % (attr, escapeattr(value)) + return data + + +def escape(data): + """Escape characters not allowed in `XML 1.0 `_.""" + data = tostr(data, "utf_8") + data = data.replace("&", "&") + data = data.replace("<", "<") + data = data.replace(">", ">") + data = data.replace("\r", " ") + + newData = data.translate(ILLEGAL_XML_CHARS) + if newData != data: + maxLen = 10 + preview = repr(data) + if len(data) > maxLen: + preview = repr(data[:maxLen])[1:-1] + "..." + TTX_LOG.warning( + "Illegal XML character(s) found; replacing offending string %r with %r", + preview, + REPLACEMENT, + ) + return newData + + +def escapeattr(data): + data = escape(data) + data = data.replace('"', """) + return data + + +def escape8bit(data): + """Input is Unicode string.""" + + def escapechar(c): + n = ord(c) + if 32 <= n <= 127 and c not in "<&>": + return c + else: + return "&#" + repr(n) + ";" + + return strjoin(map(escapechar, data.decode("latin-1"))) + + +def hexStr(s): + h = string.hexdigits + r = "" + for c in s: + i = byteord(c) + r = r + h[(i >> 4) & 0xF] + h[i & 0xF] + return r diff --git a/.venv/lib/python3.13/site-packages/fontTools/otlLib/optimize/__init__.py b/.venv/lib/python3.13/site-packages/fontTools/otlLib/optimize/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..25bce9cd2cdaa51338c83b7ecb9059b592b5574f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/otlLib/optimize/__init__.py @@ -0,0 +1,53 @@ +from argparse import RawTextHelpFormatter +from fontTools.otlLib.optimize.gpos import COMPRESSION_LEVEL, compact +from fontTools.ttLib import TTFont + + +def main(args=None): + """Optimize the layout tables of an existing font""" + from argparse import ArgumentParser + + from fontTools import configLogger + + parser = ArgumentParser( + prog="otlLib.optimize", + description=main.__doc__, + formatter_class=RawTextHelpFormatter, + ) + parser.add_argument("font") + parser.add_argument( + "-o", metavar="OUTPUTFILE", dest="outfile", default=None, help="output file" + ) + parser.add_argument( + "--gpos-compression-level", + help=COMPRESSION_LEVEL.help, + default=COMPRESSION_LEVEL.default, + choices=list(range(10)), + type=int, + ) + logging_group = parser.add_mutually_exclusive_group(required=False) + logging_group.add_argument( + "-v", "--verbose", action="store_true", help="Run more verbosely." + ) + logging_group.add_argument( + "-q", "--quiet", action="store_true", help="Turn verbosity off." + ) + options = parser.parse_args(args) + + configLogger( + level=("DEBUG" if options.verbose else "ERROR" if options.quiet else "INFO") + ) + + font = TTFont(options.font) + compact(font, options.gpos_compression_level) + font.save(options.outfile or options.font) + + +if __name__ == "__main__": + import sys + + if len(sys.argv) > 1: + sys.exit(main()) + import doctest + + sys.exit(doctest.testmod().failed) diff --git a/.venv/lib/python3.13/site-packages/fontTools/otlLib/optimize/__main__.py b/.venv/lib/python3.13/site-packages/fontTools/otlLib/optimize/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..b0ae9081ca8dac338bcf085c71adad87805e3bad --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/otlLib/optimize/__main__.py @@ -0,0 +1,6 @@ +import sys +from fontTools.otlLib.optimize import main + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.venv/lib/python3.13/site-packages/fontTools/otlLib/optimize/gpos.py b/.venv/lib/python3.13/site-packages/fontTools/otlLib/optimize/gpos.py new file mode 100644 index 0000000000000000000000000000000000000000..3edbfeb306ca38adb839e997cc3b6f1ede914572 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/otlLib/optimize/gpos.py @@ -0,0 +1,439 @@ +import logging +import os +from collections import defaultdict, namedtuple +from dataclasses import dataclass +from functools import cached_property, reduce +from itertools import chain +from math import log2 +from typing import DefaultDict, Dict, Iterable, List, Sequence, Tuple + +from fontTools.config import OPTIONS +from fontTools.misc.intTools import bit_count, bit_indices +from fontTools.ttLib import TTFont +from fontTools.ttLib.tables import otBase, otTables + +log = logging.getLogger(__name__) + +COMPRESSION_LEVEL = OPTIONS[f"{__name__}:COMPRESSION_LEVEL"] + +# Kept because ufo2ft depends on it, to be removed once ufo2ft uses the config instead +# https://github.com/fonttools/fonttools/issues/2592 +GPOS_COMPACT_MODE_ENV_KEY = "FONTTOOLS_GPOS_COMPACT_MODE" +GPOS_COMPACT_MODE_DEFAULT = str(COMPRESSION_LEVEL.default) + + +def _compression_level_from_env() -> int: + env_level = GPOS_COMPACT_MODE_DEFAULT + if GPOS_COMPACT_MODE_ENV_KEY in os.environ: + import warnings + + warnings.warn( + f"'{GPOS_COMPACT_MODE_ENV_KEY}' environment variable is deprecated. " + "Please set the 'fontTools.otlLib.optimize.gpos:COMPRESSION_LEVEL' option " + "in TTFont.cfg.", + DeprecationWarning, + ) + + env_level = os.environ[GPOS_COMPACT_MODE_ENV_KEY] + if len(env_level) == 1 and env_level in "0123456789": + return int(env_level) + raise ValueError(f"Bad {GPOS_COMPACT_MODE_ENV_KEY}={env_level}") + + +def compact(font: TTFont, level: int) -> TTFont: + # Ideal plan: + # 1. Find lookups of Lookup Type 2: Pair Adjustment Positioning Subtable + # https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#lookup-type-2-pair-adjustment-positioning-subtable + # 2. Extract glyph-glyph kerning and class-kerning from all present subtables + # 3. Regroup into different subtable arrangements + # 4. Put back into the lookup + # + # Actual implementation: + # 2. Only class kerning is optimized currently + # 3. If the input kerning is already in several subtables, the subtables + # are not grouped together first; instead each subtable is treated + # independently, so currently this step is: + # Split existing subtables into more smaller subtables + gpos = font.get("GPOS") + + # If the font does not contain a GPOS table, there is nothing to do. + if gpos is None: + return font + + for lookup in gpos.table.LookupList.Lookup: + if lookup.LookupType == 2: + compact_lookup(font, level, lookup) + elif lookup.LookupType == 9 and lookup.SubTable[0].ExtensionLookupType == 2: + compact_ext_lookup(font, level, lookup) + + return font + + +def compact_lookup(font: TTFont, level: int, lookup: otTables.Lookup) -> None: + new_subtables = compact_pair_pos(font, level, lookup.SubTable) + lookup.SubTable = new_subtables + lookup.SubTableCount = len(new_subtables) + + +def compact_ext_lookup(font: TTFont, level: int, lookup: otTables.Lookup) -> None: + new_subtables = compact_pair_pos( + font, level, [ext_subtable.ExtSubTable for ext_subtable in lookup.SubTable] + ) + new_ext_subtables = [] + for subtable in new_subtables: + ext_subtable = otTables.ExtensionPos() + ext_subtable.Format = 1 + ext_subtable.ExtSubTable = subtable + new_ext_subtables.append(ext_subtable) + lookup.SubTable = new_ext_subtables + lookup.SubTableCount = len(new_ext_subtables) + + +def compact_pair_pos( + font: TTFont, level: int, subtables: Sequence[otTables.PairPos] +) -> Sequence[otTables.PairPos]: + new_subtables = [] + for subtable in subtables: + if subtable.Format == 1: + # Not doing anything to Format 1 (yet?) + new_subtables.append(subtable) + elif subtable.Format == 2: + new_subtables.extend(compact_class_pairs(font, level, subtable)) + return new_subtables + + +def compact_class_pairs( + font: TTFont, level: int, subtable: otTables.PairPos +) -> List[otTables.PairPos]: + from fontTools.otlLib.builder import buildPairPosClassesSubtable + + subtables = [] + classes1: DefaultDict[int, List[str]] = defaultdict(list) + for g in subtable.Coverage.glyphs: + classes1[subtable.ClassDef1.classDefs.get(g, 0)].append(g) + classes2: DefaultDict[int, List[str]] = defaultdict(list) + for g, i in subtable.ClassDef2.classDefs.items(): + classes2[i].append(g) + all_pairs = {} + for i, class1 in enumerate(subtable.Class1Record): + for j, class2 in enumerate(class1.Class2Record): + if is_really_zero(class2): + continue + all_pairs[(tuple(sorted(classes1[i])), tuple(sorted(classes2[j])))] = ( + getattr(class2, "Value1", None), + getattr(class2, "Value2", None), + ) + grouped_pairs = cluster_pairs_by_class2_coverage_custom_cost(font, all_pairs, level) + for pairs in grouped_pairs: + subtables.append(buildPairPosClassesSubtable(pairs, font.getReverseGlyphMap())) + return subtables + + +def is_really_zero(class2: otTables.Class2Record) -> bool: + v1 = getattr(class2, "Value1", None) + v2 = getattr(class2, "Value2", None) + return (v1 is None or v1.getEffectiveFormat() == 0) and ( + v2 is None or v2.getEffectiveFormat() == 0 + ) + + +Pairs = Dict[ + Tuple[Tuple[str, ...], Tuple[str, ...]], + Tuple[otBase.ValueRecord, otBase.ValueRecord], +] + + +# Adapted from https://github.com/fonttools/fonttools/blob/f64f0b42f2d1163b2d85194e0979def539f5dca3/Lib/fontTools/ttLib/tables/otTables.py#L935-L958 +def _getClassRanges(glyphIDs: Iterable[int]): + glyphIDs = sorted(glyphIDs) + last = glyphIDs[0] + ranges = [[last]] + for glyphID in glyphIDs[1:]: + if glyphID != last + 1: + ranges[-1].append(last) + ranges.append([glyphID]) + last = glyphID + ranges[-1].append(last) + return ranges, glyphIDs[0], glyphIDs[-1] + + +# Adapted from https://github.com/fonttools/fonttools/blob/f64f0b42f2d1163b2d85194e0979def539f5dca3/Lib/fontTools/ttLib/tables/otTables.py#L960-L989 +def _classDef_bytes( + class_data: List[Tuple[List[Tuple[int, int]], int, int]], + class_ids: List[int], + coverage=False, +): + if not class_ids: + return 0 + first_ranges, min_glyph_id, max_glyph_id = class_data[class_ids[0]] + range_count = len(first_ranges) + for i in class_ids[1:]: + data = class_data[i] + range_count += len(data[0]) + min_glyph_id = min(min_glyph_id, data[1]) + max_glyph_id = max(max_glyph_id, data[2]) + glyphCount = max_glyph_id - min_glyph_id + 1 + # https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-1 + format1_bytes = 6 + glyphCount * 2 + # https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-2 + format2_bytes = 4 + range_count * 6 + return min(format1_bytes, format2_bytes) + + +ClusteringContext = namedtuple( + "ClusteringContext", + [ + "lines", + "all_class1", + "all_class1_data", + "all_class2_data", + "valueFormat1_bytes", + "valueFormat2_bytes", + ], +) + + +@dataclass +class Cluster: + ctx: ClusteringContext + indices_bitmask: int + + @cached_property + def indices(self): + return bit_indices(self.indices_bitmask) + + @cached_property + def column_indices(self): + # Indices of columns that have a 1 in at least 1 line + # => binary OR all the lines + bitmask = reduce(int.__or__, (self.ctx.lines[i] for i in self.indices)) + return bit_indices(bitmask) + + @property + def width(self): + # Add 1 because Class2=0 cannot be used but needs to be encoded. + return len(self.column_indices) + 1 + + @cached_property + def cost(self): + return ( + # 2 bytes to store the offset to this subtable in the Lookup table above + 2 + # Contents of the subtable + # From: https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#pair-adjustment-positioning-format-2-class-pair-adjustment + # uint16 posFormat Format identifier: format = 2 + + 2 + # Offset16 coverageOffset Offset to Coverage table, from beginning of PairPos subtable. + + 2 + + self.coverage_bytes + # uint16 valueFormat1 ValueRecord definition — for the first glyph of the pair (may be zero). + + 2 + # uint16 valueFormat2 ValueRecord definition — for the second glyph of the pair (may be zero). + + 2 + # Offset16 classDef1Offset Offset to ClassDef table, from beginning of PairPos subtable — for the first glyph of the pair. + + 2 + + self.classDef1_bytes + # Offset16 classDef2Offset Offset to ClassDef table, from beginning of PairPos subtable — for the second glyph of the pair. + + 2 + + self.classDef2_bytes + # uint16 class1Count Number of classes in classDef1 table — includes Class 0. + + 2 + # uint16 class2Count Number of classes in classDef2 table — includes Class 0. + + 2 + # Class1Record class1Records[class1Count] Array of Class1 records, ordered by classes in classDef1. + + (self.ctx.valueFormat1_bytes + self.ctx.valueFormat2_bytes) + * len(self.indices) + * self.width + ) + + @property + def coverage_bytes(self): + format1_bytes = ( + # From https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-format-1 + # uint16 coverageFormat Format identifier — format = 1 + # uint16 glyphCount Number of glyphs in the glyph array + 4 + # uint16 glyphArray[glyphCount] Array of glyph IDs — in numerical order + + sum(len(self.ctx.all_class1[i]) for i in self.indices) * 2 + ) + ranges = sorted( + chain.from_iterable(self.ctx.all_class1_data[i][0] for i in self.indices) + ) + merged_range_count = 0 + last = None + for start, end in ranges: + if last is not None and start != last + 1: + merged_range_count += 1 + last = end + format2_bytes = ( + # From https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-format-2 + # uint16 coverageFormat Format identifier — format = 2 + # uint16 rangeCount Number of RangeRecords + 4 + # RangeRecord rangeRecords[rangeCount] Array of glyph ranges — ordered by startGlyphID. + # uint16 startGlyphID First glyph ID in the range + # uint16 endGlyphID Last glyph ID in the range + # uint16 startCoverageIndex Coverage Index of first glyph ID in range + + merged_range_count * 6 + ) + return min(format1_bytes, format2_bytes) + + @property + def classDef1_bytes(self): + # We can skip encoding one of the Class1 definitions, and use + # Class1=0 to represent it instead, because Class1 is gated by the + # Coverage definition. Use Class1=0 for the highest byte savings. + # Going through all options takes too long, pick the biggest class + # = what happens in otlLib.builder.ClassDefBuilder.classes() + biggest_index = max(self.indices, key=lambda i: len(self.ctx.all_class1[i])) + return _classDef_bytes( + self.ctx.all_class1_data, [i for i in self.indices if i != biggest_index] + ) + + @property + def classDef2_bytes(self): + # All Class2 need to be encoded because we can't use Class2=0 + return _classDef_bytes(self.ctx.all_class2_data, self.column_indices) + + +def cluster_pairs_by_class2_coverage_custom_cost( + font: TTFont, + pairs: Pairs, + compression: int = 5, +) -> List[Pairs]: + if not pairs: + # The subtable was actually empty? + return [pairs] + + # Sorted for reproducibility/determinism + all_class1 = sorted(set(pair[0] for pair in pairs)) + all_class2 = sorted(set(pair[1] for pair in pairs)) + + # Use Python's big ints for binary vectors representing each line + lines = [ + sum( + 1 << i if (class1, class2) in pairs else 0 + for i, class2 in enumerate(all_class2) + ) + for class1 in all_class1 + ] + + # Map glyph names to ids and work with ints throughout for ClassDef formats + name_to_id = font.getReverseGlyphMap() + # Each entry in the arrays below is (range_count, min_glyph_id, max_glyph_id) + all_class1_data = [ + _getClassRanges(name_to_id[name] for name in cls) for cls in all_class1 + ] + all_class2_data = [ + _getClassRanges(name_to_id[name] for name in cls) for cls in all_class2 + ] + + format1 = 0 + format2 = 0 + for pair, value in pairs.items(): + format1 |= value[0].getEffectiveFormat() if value[0] else 0 + format2 |= value[1].getEffectiveFormat() if value[1] else 0 + valueFormat1_bytes = bit_count(format1) * 2 + valueFormat2_bytes = bit_count(format2) * 2 + + ctx = ClusteringContext( + lines, + all_class1, + all_class1_data, + all_class2_data, + valueFormat1_bytes, + valueFormat2_bytes, + ) + + cluster_cache: Dict[int, Cluster] = {} + + def make_cluster(indices: int) -> Cluster: + cluster = cluster_cache.get(indices, None) + if cluster is not None: + return cluster + cluster = Cluster(ctx, indices) + cluster_cache[indices] = cluster + return cluster + + def merge(cluster: Cluster, other: Cluster) -> Cluster: + return make_cluster(cluster.indices_bitmask | other.indices_bitmask) + + # Agglomerative clustering by hand, checking the cost gain of the new + # cluster against the previously separate clusters + # Start with 1 cluster per line + # cluster = set of lines = new subtable + clusters = [make_cluster(1 << i) for i in range(len(lines))] + + # Cost of 1 cluster with everything + # `(1 << len) - 1` gives a bitmask full of 1's of length `len` + cost_before_splitting = make_cluster((1 << len(lines)) - 1).cost + log.debug(f" len(clusters) = {len(clusters)}") + + while len(clusters) > 1: + lowest_cost_change = None + best_cluster_index = None + best_other_index = None + best_merged = None + for i, cluster in enumerate(clusters): + for j, other in enumerate(clusters[i + 1 :]): + merged = merge(cluster, other) + cost_change = merged.cost - cluster.cost - other.cost + if lowest_cost_change is None or cost_change < lowest_cost_change: + lowest_cost_change = cost_change + best_cluster_index = i + best_other_index = i + 1 + j + best_merged = merged + assert lowest_cost_change is not None + assert best_cluster_index is not None + assert best_other_index is not None + assert best_merged is not None + + # If the best merge we found is still taking down the file size, then + # there's no question: we must do it, because it's beneficial in both + # ways (lower file size and lower number of subtables). However, if the + # best merge we found is not reducing file size anymore, then we need to + # look at the other stop criteria = the compression factor. + if lowest_cost_change > 0: + # Stop critera: check whether we should keep merging. + # Compute size reduction brought by splitting + cost_after_splitting = sum(c.cost for c in clusters) + # size_reduction so that after = before * (1 - size_reduction) + # E.g. before = 1000, after = 800, 1 - 800/1000 = 0.2 + size_reduction = 1 - cost_after_splitting / cost_before_splitting + + # Force more merging by taking into account the compression number. + # Target behaviour: compression number = 1 to 9, default 5 like gzip + # - 1 = accept to add 1 subtable to reduce size by 50% + # - 5 = accept to add 5 subtables to reduce size by 50% + # See https://github.com/harfbuzz/packtab/blob/master/Lib/packTab/__init__.py#L690-L691 + # Given the size reduction we have achieved so far, compute how many + # new subtables are acceptable. + max_new_subtables = -log2(1 - size_reduction) * compression + log.debug( + f" len(clusters) = {len(clusters):3d} size_reduction={size_reduction:5.2f} max_new_subtables={max_new_subtables}", + ) + if compression == 9: + # Override level 9 to mean: create any number of subtables + max_new_subtables = len(clusters) + + # If we have managed to take the number of new subtables below the + # threshold, then we can stop. + if len(clusters) <= max_new_subtables + 1: + break + + # No reason to stop yet, do the merge and move on to the next. + del clusters[best_other_index] + clusters[best_cluster_index] = best_merged + + # All clusters are final; turn bitmasks back into the "Pairs" format + pairs_by_class1: Dict[Tuple[str, ...], Pairs] = defaultdict(dict) + for pair, values in pairs.items(): + pairs_by_class1[pair[0]][pair] = values + pairs_groups: List[Pairs] = [] + for cluster in clusters: + pairs_group: Pairs = dict() + for i in cluster.indices: + class1 = all_class1[i] + pairs_group.update(pairs_by_class1[class1]) + pairs_groups.append(pairs_group) + return pairs_groups diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/__init__.py b/.venv/lib/python3.13/site-packages/fontTools/pens/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..156cb232a7aa80eee1526c7598f72043de10473f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/__init__.py @@ -0,0 +1 @@ +"""Empty __init__.py file to signal Python this directory is a package.""" diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/areaPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/areaPen.py new file mode 100644 index 0000000000000000000000000000000000000000..004bb06b091ceb777cca2c02f8481a2785a46d35 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/areaPen.py @@ -0,0 +1,52 @@ +"""Calculate the area of a glyph.""" + +from fontTools.pens.basePen import BasePen + + +__all__ = ["AreaPen"] + + +class AreaPen(BasePen): + def __init__(self, glyphset=None): + BasePen.__init__(self, glyphset) + self.value = 0 + + def _moveTo(self, p0): + self._p0 = self._startPoint = p0 + + def _lineTo(self, p1): + x0, y0 = self._p0 + x1, y1 = p1 + self.value -= (x1 - x0) * (y1 + y0) * 0.5 + self._p0 = p1 + + def _qCurveToOne(self, p1, p2): + # https://github.com/Pomax/bezierinfo/issues/44 + p0 = self._p0 + x0, y0 = p0[0], p0[1] + x1, y1 = p1[0] - x0, p1[1] - y0 + x2, y2 = p2[0] - x0, p2[1] - y0 + self.value -= (x2 * y1 - x1 * y2) / 3 + self._lineTo(p2) + self._p0 = p2 + + def _curveToOne(self, p1, p2, p3): + # https://github.com/Pomax/bezierinfo/issues/44 + p0 = self._p0 + x0, y0 = p0[0], p0[1] + x1, y1 = p1[0] - x0, p1[1] - y0 + x2, y2 = p2[0] - x0, p2[1] - y0 + x3, y3 = p3[0] - x0, p3[1] - y0 + self.value -= (x1 * (-y2 - y3) + x2 * (y1 - 2 * y3) + x3 * (y1 + 2 * y2)) * 0.15 + self._lineTo(p3) + self._p0 = p3 + + def _closePath(self): + self._lineTo(self._startPoint) + del self._p0, self._startPoint + + def _endPath(self): + if self._p0 != self._startPoint: + # Area is not defined for open contours. + raise NotImplementedError + del self._p0, self._startPoint diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/basePen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/basePen.py new file mode 100644 index 0000000000000000000000000000000000000000..ba38f7009088b21b84db7297fe5e20970347473d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/basePen.py @@ -0,0 +1,475 @@ +"""fontTools.pens.basePen.py -- Tools and base classes to build pen objects. + +The Pen Protocol + +A Pen is a kind of object that standardizes the way how to "draw" outlines: +it is a middle man between an outline and a drawing. In other words: +it is an abstraction for drawing outlines, making sure that outline objects +don't need to know the details about how and where they're being drawn, and +that drawings don't need to know the details of how outlines are stored. + +The most basic pattern is this:: + + outline.draw(pen) # 'outline' draws itself onto 'pen' + +Pens can be used to render outlines to the screen, but also to construct +new outlines. Eg. an outline object can be both a drawable object (it has a +draw() method) as well as a pen itself: you *build* an outline using pen +methods. + +The AbstractPen class defines the Pen protocol. It implements almost +nothing (only no-op closePath() and endPath() methods), but is useful +for documentation purposes. Subclassing it basically tells the reader: +"this class implements the Pen protocol.". An examples of an AbstractPen +subclass is :py:class:`fontTools.pens.transformPen.TransformPen`. + +The BasePen class is a base implementation useful for pens that actually +draw (for example a pen renders outlines using a native graphics engine). +BasePen contains a lot of base functionality, making it very easy to build +a pen that fully conforms to the pen protocol. Note that if you subclass +BasePen, you *don't* override moveTo(), lineTo(), etc., but _moveTo(), +_lineTo(), etc. See the BasePen doc string for details. Examples of +BasePen subclasses are fontTools.pens.boundsPen.BoundsPen and +fontTools.pens.cocoaPen.CocoaPen. + +Coordinates are usually expressed as (x, y) tuples, but generally any +sequence of length 2 will do. +""" + +from typing import Tuple, Dict + +from fontTools.misc.loggingTools import LogMixin +from fontTools.misc.transform import DecomposedTransform, Identity + +__all__ = [ + "AbstractPen", + "NullPen", + "BasePen", + "PenError", + "decomposeSuperBezierSegment", + "decomposeQuadraticSegment", +] + + +class PenError(Exception): + """Represents an error during penning.""" + + +class OpenContourError(PenError): + pass + + +class AbstractPen: + def moveTo(self, pt: Tuple[float, float]) -> None: + """Begin a new sub path, set the current point to 'pt'. You must + end each sub path with a call to pen.closePath() or pen.endPath(). + """ + raise NotImplementedError + + def lineTo(self, pt: Tuple[float, float]) -> None: + """Draw a straight line from the current point to 'pt'.""" + raise NotImplementedError + + def curveTo(self, *points: Tuple[float, float]) -> None: + """Draw a cubic bezier with an arbitrary number of control points. + + The last point specified is on-curve, all others are off-curve + (control) points. If the number of control points is > 2, the + segment is split into multiple bezier segments. This works + like this: + + Let n be the number of control points (which is the number of + arguments to this call minus 1). If n==2, a plain vanilla cubic + bezier is drawn. If n==1, we fall back to a quadratic segment and + if n==0 we draw a straight line. It gets interesting when n>2: + n-1 PostScript-style cubic segments will be drawn as if it were + one curve. See decomposeSuperBezierSegment(). + + The conversion algorithm used for n>2 is inspired by NURB + splines, and is conceptually equivalent to the TrueType "implied + points" principle. See also decomposeQuadraticSegment(). + """ + raise NotImplementedError + + def qCurveTo(self, *points: Tuple[float, float]) -> None: + """Draw a whole string of quadratic curve segments. + + The last point specified is on-curve, all others are off-curve + points. + + This method implements TrueType-style curves, breaking up curves + using 'implied points': between each two consequtive off-curve points, + there is one implied point exactly in the middle between them. See + also decomposeQuadraticSegment(). + + The last argument (normally the on-curve point) may be None. + This is to support contours that have NO on-curve points (a rarely + seen feature of TrueType outlines). + """ + raise NotImplementedError + + def closePath(self) -> None: + """Close the current sub path. You must call either pen.closePath() + or pen.endPath() after each sub path. + """ + pass + + def endPath(self) -> None: + """End the current sub path, but don't close it. You must call + either pen.closePath() or pen.endPath() after each sub path. + """ + pass + + def addComponent( + self, + glyphName: str, + transformation: Tuple[float, float, float, float, float, float], + ) -> None: + """Add a sub glyph. The 'transformation' argument must be a 6-tuple + containing an affine transformation, or a Transform object from the + fontTools.misc.transform module. More precisely: it should be a + sequence containing 6 numbers. + """ + raise NotImplementedError + + def addVarComponent( + self, + glyphName: str, + transformation: DecomposedTransform, + location: Dict[str, float], + ) -> None: + """Add a VarComponent sub glyph. The 'transformation' argument + must be a DecomposedTransform from the fontTools.misc.transform module, + and the 'location' argument must be a dictionary mapping axis tags + to their locations. + """ + # GlyphSet decomposes for us + raise AttributeError + + +class NullPen(AbstractPen): + """A pen that does nothing.""" + + def moveTo(self, pt): + pass + + def lineTo(self, pt): + pass + + def curveTo(self, *points): + pass + + def qCurveTo(self, *points): + pass + + def closePath(self): + pass + + def endPath(self): + pass + + def addComponent(self, glyphName, transformation): + pass + + def addVarComponent(self, glyphName, transformation, location): + pass + + +class LoggingPen(LogMixin, AbstractPen): + """A pen with a ``log`` property (see fontTools.misc.loggingTools.LogMixin)""" + + pass + + +class MissingComponentError(KeyError): + """Indicates a component pointing to a non-existent glyph in the glyphset.""" + + +class DecomposingPen(LoggingPen): + """Implements a 'addComponent' method that decomposes components + (i.e. draws them onto self as simple contours). + It can also be used as a mixin class (e.g. see ContourRecordingPen). + + You must override moveTo, lineTo, curveTo and qCurveTo. You may + additionally override closePath, endPath and addComponent. + + By default a warning message is logged when a base glyph is missing; + set the class variable ``skipMissingComponents`` to False if you want + all instances of a sub-class to raise a :class:`MissingComponentError` + exception by default. + """ + + skipMissingComponents = True + # alias error for convenience + MissingComponentError = MissingComponentError + + def __init__( + self, + glyphSet, + *args, + skipMissingComponents=None, + reverseFlipped=False, + **kwargs, + ): + """Takes a 'glyphSet' argument (dict), in which the glyphs that are referenced + as components are looked up by their name. + + If the optional 'reverseFlipped' argument is True, components whose transformation + matrix has a negative determinant will be decomposed with a reversed path direction + to compensate for the flip. + + The optional 'skipMissingComponents' argument can be set to True/False to + override the homonymous class attribute for a given pen instance. + """ + super(DecomposingPen, self).__init__(*args, **kwargs) + self.glyphSet = glyphSet + self.skipMissingComponents = ( + self.__class__.skipMissingComponents + if skipMissingComponents is None + else skipMissingComponents + ) + self.reverseFlipped = reverseFlipped + + def addComponent(self, glyphName, transformation): + """Transform the points of the base glyph and draw it onto self.""" + from fontTools.pens.transformPen import TransformPen + + try: + glyph = self.glyphSet[glyphName] + except KeyError: + if not self.skipMissingComponents: + raise MissingComponentError(glyphName) + self.log.warning("glyph '%s' is missing from glyphSet; skipped" % glyphName) + else: + pen = self + if transformation != Identity: + pen = TransformPen(pen, transformation) + if self.reverseFlipped: + # if the transformation has a negative determinant, it will + # reverse the contour direction of the component + a, b, c, d = transformation[:4] + det = a * d - b * c + if det < 0: + from fontTools.pens.reverseContourPen import ReverseContourPen + + pen = ReverseContourPen(pen) + glyph.draw(pen) + + def addVarComponent(self, glyphName, transformation, location): + # GlyphSet decomposes for us + raise AttributeError + + +class BasePen(DecomposingPen): + """Base class for drawing pens. You must override _moveTo, _lineTo and + _curveToOne. You may additionally override _closePath, _endPath, + addComponent, addVarComponent, and/or _qCurveToOne. You should not + override any other methods. + """ + + def __init__(self, glyphSet=None): + super(BasePen, self).__init__(glyphSet) + self.__currentPoint = None + + # must override + + def _moveTo(self, pt): + raise NotImplementedError + + def _lineTo(self, pt): + raise NotImplementedError + + def _curveToOne(self, pt1, pt2, pt3): + raise NotImplementedError + + # may override + + def _closePath(self): + pass + + def _endPath(self): + pass + + def _qCurveToOne(self, pt1, pt2): + """This method implements the basic quadratic curve type. The + default implementation delegates the work to the cubic curve + function. Optionally override with a native implementation. + """ + pt0x, pt0y = self.__currentPoint + pt1x, pt1y = pt1 + pt2x, pt2y = pt2 + mid1x = pt0x + 0.66666666666666667 * (pt1x - pt0x) + mid1y = pt0y + 0.66666666666666667 * (pt1y - pt0y) + mid2x = pt2x + 0.66666666666666667 * (pt1x - pt2x) + mid2y = pt2y + 0.66666666666666667 * (pt1y - pt2y) + self._curveToOne((mid1x, mid1y), (mid2x, mid2y), pt2) + + # don't override + + def _getCurrentPoint(self): + """Return the current point. This is not part of the public + interface, yet is useful for subclasses. + """ + return self.__currentPoint + + def closePath(self): + self._closePath() + self.__currentPoint = None + + def endPath(self): + self._endPath() + self.__currentPoint = None + + def moveTo(self, pt): + self._moveTo(pt) + self.__currentPoint = pt + + def lineTo(self, pt): + self._lineTo(pt) + self.__currentPoint = pt + + def curveTo(self, *points): + n = len(points) - 1 # 'n' is the number of control points + assert n >= 0 + if n == 2: + # The common case, we have exactly two BCP's, so this is a standard + # cubic bezier. Even though decomposeSuperBezierSegment() handles + # this case just fine, we special-case it anyway since it's so + # common. + self._curveToOne(*points) + self.__currentPoint = points[-1] + elif n > 2: + # n is the number of control points; split curve into n-1 cubic + # bezier segments. The algorithm used here is inspired by NURB + # splines and the TrueType "implied point" principle, and ensures + # the smoothest possible connection between two curve segments, + # with no disruption in the curvature. It is practical since it + # allows one to construct multiple bezier segments with a much + # smaller amount of points. + _curveToOne = self._curveToOne + for pt1, pt2, pt3 in decomposeSuperBezierSegment(points): + _curveToOne(pt1, pt2, pt3) + self.__currentPoint = pt3 + elif n == 1: + self.qCurveTo(*points) + elif n == 0: + self.lineTo(points[0]) + else: + raise AssertionError("can't get there from here") + + def qCurveTo(self, *points): + n = len(points) - 1 # 'n' is the number of control points + assert n >= 0 + if points[-1] is None: + # Special case for TrueType quadratics: it is possible to + # define a contour with NO on-curve points. BasePen supports + # this by allowing the final argument (the expected on-curve + # point) to be None. We simulate the feature by making the implied + # on-curve point between the last and the first off-curve points + # explicit. + x, y = points[-2] # last off-curve point + nx, ny = points[0] # first off-curve point + impliedStartPoint = (0.5 * (x + nx), 0.5 * (y + ny)) + self.__currentPoint = impliedStartPoint + self._moveTo(impliedStartPoint) + points = points[:-1] + (impliedStartPoint,) + if n > 0: + # Split the string of points into discrete quadratic curve + # segments. Between any two consecutive off-curve points + # there's an implied on-curve point exactly in the middle. + # This is where the segment splits. + _qCurveToOne = self._qCurveToOne + for pt1, pt2 in decomposeQuadraticSegment(points): + _qCurveToOne(pt1, pt2) + self.__currentPoint = pt2 + else: + self.lineTo(points[0]) + + +def decomposeSuperBezierSegment(points): + """Split the SuperBezier described by 'points' into a list of regular + bezier segments. The 'points' argument must be a sequence with length + 3 or greater, containing (x, y) coordinates. The last point is the + destination on-curve point, the rest of the points are off-curve points. + The start point should not be supplied. + + This function returns a list of (pt1, pt2, pt3) tuples, which each + specify a regular curveto-style bezier segment. + """ + n = len(points) - 1 + assert n > 1 + bezierSegments = [] + pt1, pt2, pt3 = points[0], None, None + for i in range(2, n + 1): + # calculate points in between control points. + nDivisions = min(i, 3, n - i + 2) + for j in range(1, nDivisions): + factor = j / nDivisions + temp1 = points[i - 1] + temp2 = points[i - 2] + temp = ( + temp2[0] + factor * (temp1[0] - temp2[0]), + temp2[1] + factor * (temp1[1] - temp2[1]), + ) + if pt2 is None: + pt2 = temp + else: + pt3 = (0.5 * (pt2[0] + temp[0]), 0.5 * (pt2[1] + temp[1])) + bezierSegments.append((pt1, pt2, pt3)) + pt1, pt2, pt3 = temp, None, None + bezierSegments.append((pt1, points[-2], points[-1])) + return bezierSegments + + +def decomposeQuadraticSegment(points): + """Split the quadratic curve segment described by 'points' into a list + of "atomic" quadratic segments. The 'points' argument must be a sequence + with length 2 or greater, containing (x, y) coordinates. The last point + is the destination on-curve point, the rest of the points are off-curve + points. The start point should not be supplied. + + This function returns a list of (pt1, pt2) tuples, which each specify a + plain quadratic bezier segment. + """ + n = len(points) - 1 + assert n > 0 + quadSegments = [] + for i in range(n - 1): + x, y = points[i] + nx, ny = points[i + 1] + impliedPt = (0.5 * (x + nx), 0.5 * (y + ny)) + quadSegments.append((points[i], impliedPt)) + quadSegments.append((points[-2], points[-1])) + return quadSegments + + +class _TestPen(BasePen): + """Test class that prints PostScript to stdout.""" + + def _moveTo(self, pt): + print("%s %s moveto" % (pt[0], pt[1])) + + def _lineTo(self, pt): + print("%s %s lineto" % (pt[0], pt[1])) + + def _curveToOne(self, bcp1, bcp2, pt): + print( + "%s %s %s %s %s %s curveto" + % (bcp1[0], bcp1[1], bcp2[0], bcp2[1], pt[0], pt[1]) + ) + + def _closePath(self): + print("closepath") + + +if __name__ == "__main__": + pen = _TestPen(None) + pen.moveTo((0, 0)) + pen.lineTo((0, 100)) + pen.curveTo((50, 75), (60, 50), (50, 25), (0, 0)) + pen.closePath() + + pen = _TestPen(None) + # testing the "no on-curve point" scenario + pen.qCurveTo((0, 0), (0, 100), (100, 100), (100, 0), None) + pen.closePath() diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/boundsPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/boundsPen.py new file mode 100644 index 0000000000000000000000000000000000000000..c92184413eadc5c22c02ffe65ef2d84da9c6183c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/boundsPen.py @@ -0,0 +1,98 @@ +from fontTools.misc.arrayTools import updateBounds, pointInRect, unionRect +from fontTools.misc.bezierTools import calcCubicBounds, calcQuadraticBounds +from fontTools.pens.basePen import BasePen + + +__all__ = ["BoundsPen", "ControlBoundsPen"] + + +class ControlBoundsPen(BasePen): + """Pen to calculate the "control bounds" of a shape. This is the + bounding box of all control points, so may be larger than the + actual bounding box if there are curves that don't have points + on their extremes. + + When the shape has been drawn, the bounds are available as the + ``bounds`` attribute of the pen object. It's a 4-tuple:: + + (xMin, yMin, xMax, yMax). + + If ``ignoreSinglePoints`` is True, single points are ignored. + """ + + def __init__(self, glyphSet, ignoreSinglePoints=False): + BasePen.__init__(self, glyphSet) + self.ignoreSinglePoints = ignoreSinglePoints + self.init() + + def init(self): + self.bounds = None + self._start = None + + def _moveTo(self, pt): + self._start = pt + if not self.ignoreSinglePoints: + self._addMoveTo() + + def _addMoveTo(self): + if self._start is None: + return + bounds = self.bounds + if bounds: + self.bounds = updateBounds(bounds, self._start) + else: + x, y = self._start + self.bounds = (x, y, x, y) + self._start = None + + def _lineTo(self, pt): + self._addMoveTo() + self.bounds = updateBounds(self.bounds, pt) + + def _curveToOne(self, bcp1, bcp2, pt): + self._addMoveTo() + bounds = self.bounds + bounds = updateBounds(bounds, bcp1) + bounds = updateBounds(bounds, bcp2) + bounds = updateBounds(bounds, pt) + self.bounds = bounds + + def _qCurveToOne(self, bcp, pt): + self._addMoveTo() + bounds = self.bounds + bounds = updateBounds(bounds, bcp) + bounds = updateBounds(bounds, pt) + self.bounds = bounds + + +class BoundsPen(ControlBoundsPen): + """Pen to calculate the bounds of a shape. It calculates the + correct bounds even when the shape contains curves that don't + have points on their extremes. This is somewhat slower to compute + than the "control bounds". + + When the shape has been drawn, the bounds are available as the + ``bounds`` attribute of the pen object. It's a 4-tuple:: + + (xMin, yMin, xMax, yMax) + """ + + def _curveToOne(self, bcp1, bcp2, pt): + self._addMoveTo() + bounds = self.bounds + bounds = updateBounds(bounds, pt) + if not pointInRect(bcp1, bounds) or not pointInRect(bcp2, bounds): + bounds = unionRect( + bounds, calcCubicBounds(self._getCurrentPoint(), bcp1, bcp2, pt) + ) + self.bounds = bounds + + def _qCurveToOne(self, bcp, pt): + self._addMoveTo() + bounds = self.bounds + bounds = updateBounds(bounds, pt) + if not pointInRect(bcp, bounds): + bounds = unionRect( + bounds, calcQuadraticBounds(self._getCurrentPoint(), bcp, pt) + ) + self.bounds = bounds diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/cairoPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/cairoPen.py new file mode 100644 index 0000000000000000000000000000000000000000..9cd5da9128fc0054cf748de703540afa7685b7b2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/cairoPen.py @@ -0,0 +1,26 @@ +"""Pen to draw to a Cairo graphics library context.""" + +from fontTools.pens.basePen import BasePen + + +__all__ = ["CairoPen"] + + +class CairoPen(BasePen): + """Pen to draw to a Cairo graphics library context.""" + + def __init__(self, glyphSet, context): + BasePen.__init__(self, glyphSet) + self.context = context + + def _moveTo(self, p): + self.context.move_to(*p) + + def _lineTo(self, p): + self.context.line_to(*p) + + def _curveToOne(self, p1, p2, p3): + self.context.curve_to(*p1, *p2, *p3) + + def _closePath(self): + self.context.close_path() diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/cocoaPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/cocoaPen.py new file mode 100644 index 0000000000000000000000000000000000000000..5369c3097187b6929df58e93284199a1729ea275 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/cocoaPen.py @@ -0,0 +1,26 @@ +from fontTools.pens.basePen import BasePen + + +__all__ = ["CocoaPen"] + + +class CocoaPen(BasePen): + def __init__(self, glyphSet, path=None): + BasePen.__init__(self, glyphSet) + if path is None: + from AppKit import NSBezierPath + + path = NSBezierPath.bezierPath() + self.path = path + + def _moveTo(self, p): + self.path.moveToPoint_(p) + + def _lineTo(self, p): + self.path.lineToPoint_(p) + + def _curveToOne(self, p1, p2, p3): + self.path.curveToPoint_controlPoint1_controlPoint2_(p3, p1, p2) + + def _closePath(self): + self.path.closePath() diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/cu2quPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/cu2quPen.py new file mode 100644 index 0000000000000000000000000000000000000000..5730b325cf056f2e6633f7e6294853af21b1182e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/cu2quPen.py @@ -0,0 +1,325 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import operator +from fontTools.cu2qu import curve_to_quadratic, curves_to_quadratic +from fontTools.pens.basePen import decomposeSuperBezierSegment +from fontTools.pens.filterPen import FilterPen +from fontTools.pens.reverseContourPen import ReverseContourPen +from fontTools.pens.pointPen import BasePointToSegmentPen +from fontTools.pens.pointPen import ReverseContourPointPen + + +class Cu2QuPen(FilterPen): + """A filter pen to convert cubic bezier curves to quadratic b-splines + using the FontTools SegmentPen protocol. + + Args: + + other_pen: another SegmentPen used to draw the transformed outline. + max_err: maximum approximation error in font units. For optimal results, + if you know the UPEM of the font, we recommend setting this to a + value equal, or close to UPEM / 1000. + reverse_direction: flip the contours' direction but keep starting point. + stats: a dictionary counting the point numbers of quadratic segments. + all_quadratic: if True (default), only quadratic b-splines are generated. + if False, quadratic curves or cubic curves are generated depending + on which one is more economical. + """ + + def __init__( + self, + other_pen, + max_err, + reverse_direction=False, + stats=None, + all_quadratic=True, + ): + if reverse_direction: + other_pen = ReverseContourPen(other_pen) + super().__init__(other_pen) + self.max_err = max_err + self.stats = stats + self.all_quadratic = all_quadratic + + def _convert_curve(self, pt1, pt2, pt3): + curve = (self.current_pt, pt1, pt2, pt3) + result = curve_to_quadratic(curve, self.max_err, self.all_quadratic) + if self.stats is not None: + n = str(len(result) - 2) + self.stats[n] = self.stats.get(n, 0) + 1 + if self.all_quadratic: + self.qCurveTo(*result[1:]) + else: + if len(result) == 3: + self.qCurveTo(*result[1:]) + else: + assert len(result) == 4 + super().curveTo(*result[1:]) + + def curveTo(self, *points): + n = len(points) + if n == 3: + # this is the most common case, so we special-case it + self._convert_curve(*points) + elif n > 3: + for segment in decomposeSuperBezierSegment(points): + self._convert_curve(*segment) + else: + self.qCurveTo(*points) + + +class Cu2QuPointPen(BasePointToSegmentPen): + """A filter pen to convert cubic bezier curves to quadratic b-splines + using the FontTools PointPen protocol. + + Args: + other_point_pen: another PointPen used to draw the transformed outline. + max_err: maximum approximation error in font units. For optimal results, + if you know the UPEM of the font, we recommend setting this to a + value equal, or close to UPEM / 1000. + reverse_direction: reverse the winding direction of all contours. + stats: a dictionary counting the point numbers of quadratic segments. + all_quadratic: if True (default), only quadratic b-splines are generated. + if False, quadratic curves or cubic curves are generated depending + on which one is more economical. + """ + + __points_required = { + "move": (1, operator.eq), + "line": (1, operator.eq), + "qcurve": (2, operator.ge), + "curve": (3, operator.eq), + } + + def __init__( + self, + other_point_pen, + max_err, + reverse_direction=False, + stats=None, + all_quadratic=True, + ): + BasePointToSegmentPen.__init__(self) + if reverse_direction: + self.pen = ReverseContourPointPen(other_point_pen) + else: + self.pen = other_point_pen + self.max_err = max_err + self.stats = stats + self.all_quadratic = all_quadratic + + def _flushContour(self, segments): + assert len(segments) >= 1 + closed = segments[0][0] != "move" + new_segments = [] + prev_points = segments[-1][1] + prev_on_curve = prev_points[-1][0] + for segment_type, points in segments: + if segment_type == "curve": + for sub_points in self._split_super_bezier_segments(points): + on_curve, smooth, name, kwargs = sub_points[-1] + bcp1, bcp2 = sub_points[0][0], sub_points[1][0] + cubic = [prev_on_curve, bcp1, bcp2, on_curve] + quad = curve_to_quadratic(cubic, self.max_err, self.all_quadratic) + if self.stats is not None: + n = str(len(quad) - 2) + self.stats[n] = self.stats.get(n, 0) + 1 + new_points = [(pt, False, None, {}) for pt in quad[1:-1]] + new_points.append((on_curve, smooth, name, kwargs)) + if self.all_quadratic or len(new_points) == 2: + new_segments.append(["qcurve", new_points]) + else: + new_segments.append(["curve", new_points]) + prev_on_curve = sub_points[-1][0] + else: + new_segments.append([segment_type, points]) + prev_on_curve = points[-1][0] + if closed: + # the BasePointToSegmentPen.endPath method that calls _flushContour + # rotates the point list of closed contours so that they end with + # the first on-curve point. We restore the original starting point. + new_segments = new_segments[-1:] + new_segments[:-1] + self._drawPoints(new_segments) + + def _split_super_bezier_segments(self, points): + sub_segments = [] + # n is the number of control points + n = len(points) - 1 + if n == 2: + # a simple bezier curve segment + sub_segments.append(points) + elif n > 2: + # a "super" bezier; decompose it + on_curve, smooth, name, kwargs = points[-1] + num_sub_segments = n - 1 + for i, sub_points in enumerate( + decomposeSuperBezierSegment([pt for pt, _, _, _ in points]) + ): + new_segment = [] + for point in sub_points[:-1]: + new_segment.append((point, False, None, {})) + if i == (num_sub_segments - 1): + # the last on-curve keeps its original attributes + new_segment.append((on_curve, smooth, name, kwargs)) + else: + # on-curves of sub-segments are always "smooth" + new_segment.append((sub_points[-1], True, None, {})) + sub_segments.append(new_segment) + else: + raise AssertionError("expected 2 control points, found: %d" % n) + return sub_segments + + def _drawPoints(self, segments): + pen = self.pen + pen.beginPath() + last_offcurves = [] + points_required = self.__points_required + for i, (segment_type, points) in enumerate(segments): + if segment_type in points_required: + n, op = points_required[segment_type] + assert op(len(points), n), ( + f"illegal {segment_type!r} segment point count: " + f"expected {n}, got {len(points)}" + ) + offcurves = points[:-1] + if i == 0: + # any off-curve points preceding the first on-curve + # will be appended at the end of the contour + last_offcurves = offcurves + else: + for pt, smooth, name, kwargs in offcurves: + pen.addPoint(pt, None, smooth, name, **kwargs) + pt, smooth, name, kwargs = points[-1] + if pt is None: + assert segment_type == "qcurve" + # special quadratic contour with no on-curve points: + # we need to skip the "None" point. See also the Pen + # protocol's qCurveTo() method and fontTools.pens.basePen + pass + else: + pen.addPoint(pt, segment_type, smooth, name, **kwargs) + else: + raise AssertionError("unexpected segment type: %r" % segment_type) + for pt, smooth, name, kwargs in last_offcurves: + pen.addPoint(pt, None, smooth, name, **kwargs) + pen.endPath() + + def addComponent(self, baseGlyphName, transformation): + assert self.currentPath is None + self.pen.addComponent(baseGlyphName, transformation) + + +class Cu2QuMultiPen: + """A filter multi-pen to convert cubic bezier curves to quadratic b-splines + in a interpolation-compatible manner, using the FontTools SegmentPen protocol. + + Args: + + other_pens: list of SegmentPens used to draw the transformed outlines. + max_err: maximum approximation error in font units. For optimal results, + if you know the UPEM of the font, we recommend setting this to a + value equal, or close to UPEM / 1000. + reverse_direction: flip the contours' direction but keep starting point. + + This pen does not follow the normal SegmentPen protocol. Instead, its + moveTo/lineTo/qCurveTo/curveTo methods take a list of tuples that are + arguments that would normally be passed to a SegmentPen, one item for + each of the pens in other_pens. + """ + + # TODO Simplify like 3e8ebcdce592fe8a59ca4c3a294cc9724351e1ce + # Remove start_pts and _add_moveTO + + def __init__(self, other_pens, max_err, reverse_direction=False): + if reverse_direction: + other_pens = [ + ReverseContourPen(pen, outputImpliedClosingLine=True) + for pen in other_pens + ] + self.pens = other_pens + self.max_err = max_err + self.start_pts = None + self.current_pts = None + + def _check_contour_is_open(self): + if self.current_pts is None: + raise AssertionError("moveTo is required") + + def _check_contour_is_closed(self): + if self.current_pts is not None: + raise AssertionError("closePath or endPath is required") + + def _add_moveTo(self): + if self.start_pts is not None: + for pt, pen in zip(self.start_pts, self.pens): + pen.moveTo(*pt) + self.start_pts = None + + def moveTo(self, pts): + self._check_contour_is_closed() + self.start_pts = self.current_pts = pts + self._add_moveTo() + + def lineTo(self, pts): + self._check_contour_is_open() + self._add_moveTo() + for pt, pen in zip(pts, self.pens): + pen.lineTo(*pt) + self.current_pts = pts + + def qCurveTo(self, pointsList): + self._check_contour_is_open() + if len(pointsList[0]) == 1: + self.lineTo([(points[0],) for points in pointsList]) + return + self._add_moveTo() + current_pts = [] + for points, pen in zip(pointsList, self.pens): + pen.qCurveTo(*points) + current_pts.append((points[-1],)) + self.current_pts = current_pts + + def _curves_to_quadratic(self, pointsList): + curves = [] + for current_pt, points in zip(self.current_pts, pointsList): + curves.append(current_pt + points) + quadratics = curves_to_quadratic(curves, [self.max_err] * len(curves)) + pointsList = [] + for quadratic in quadratics: + pointsList.append(quadratic[1:]) + self.qCurveTo(pointsList) + + def curveTo(self, pointsList): + self._check_contour_is_open() + self._curves_to_quadratic(pointsList) + + def closePath(self): + self._check_contour_is_open() + if self.start_pts is None: + for pen in self.pens: + pen.closePath() + self.current_pts = self.start_pts = None + + def endPath(self): + self._check_contour_is_open() + if self.start_pts is None: + for pen in self.pens: + pen.endPath() + self.current_pts = self.start_pts = None + + def addComponent(self, glyphName, transformations): + self._check_contour_is_closed() + for trans, pen in zip(transformations, self.pens): + pen.addComponent(glyphName, trans) diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/explicitClosingLinePen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/explicitClosingLinePen.py new file mode 100644 index 0000000000000000000000000000000000000000..e3c9c943cc504e970d4e9ec9f96c3817d8383ccf --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/explicitClosingLinePen.py @@ -0,0 +1,101 @@ +from fontTools.pens.filterPen import ContourFilterPen + + +class ExplicitClosingLinePen(ContourFilterPen): + """A filter pen that adds an explicit lineTo to the first point of each closed + contour if the end point of the last segment is not already the same as the first point. + Otherwise, it passes the contour through unchanged. + + >>> from pprint import pprint + >>> from fontTools.pens.recordingPen import RecordingPen + >>> rec = RecordingPen() + >>> pen = ExplicitClosingLinePen(rec) + >>> pen.moveTo((0, 0)) + >>> pen.lineTo((100, 0)) + >>> pen.lineTo((100, 100)) + >>> pen.closePath() + >>> pprint(rec.value) + [('moveTo', ((0, 0),)), + ('lineTo', ((100, 0),)), + ('lineTo', ((100, 100),)), + ('lineTo', ((0, 0),)), + ('closePath', ())] + >>> rec = RecordingPen() + >>> pen = ExplicitClosingLinePen(rec) + >>> pen.moveTo((0, 0)) + >>> pen.lineTo((100, 0)) + >>> pen.lineTo((100, 100)) + >>> pen.lineTo((0, 0)) + >>> pen.closePath() + >>> pprint(rec.value) + [('moveTo', ((0, 0),)), + ('lineTo', ((100, 0),)), + ('lineTo', ((100, 100),)), + ('lineTo', ((0, 0),)), + ('closePath', ())] + >>> rec = RecordingPen() + >>> pen = ExplicitClosingLinePen(rec) + >>> pen.moveTo((0, 0)) + >>> pen.curveTo((100, 0), (0, 100), (100, 100)) + >>> pen.closePath() + >>> pprint(rec.value) + [('moveTo', ((0, 0),)), + ('curveTo', ((100, 0), (0, 100), (100, 100))), + ('lineTo', ((0, 0),)), + ('closePath', ())] + >>> rec = RecordingPen() + >>> pen = ExplicitClosingLinePen(rec) + >>> pen.moveTo((0, 0)) + >>> pen.curveTo((100, 0), (0, 100), (100, 100)) + >>> pen.lineTo((0, 0)) + >>> pen.closePath() + >>> pprint(rec.value) + [('moveTo', ((0, 0),)), + ('curveTo', ((100, 0), (0, 100), (100, 100))), + ('lineTo', ((0, 0),)), + ('closePath', ())] + >>> rec = RecordingPen() + >>> pen = ExplicitClosingLinePen(rec) + >>> pen.moveTo((0, 0)) + >>> pen.curveTo((100, 0), (0, 100), (0, 0)) + >>> pen.closePath() + >>> pprint(rec.value) + [('moveTo', ((0, 0),)), + ('curveTo', ((100, 0), (0, 100), (0, 0))), + ('closePath', ())] + >>> rec = RecordingPen() + >>> pen = ExplicitClosingLinePen(rec) + >>> pen.moveTo((0, 0)) + >>> pen.closePath() + >>> pprint(rec.value) + [('moveTo', ((0, 0),)), ('closePath', ())] + >>> rec = RecordingPen() + >>> pen = ExplicitClosingLinePen(rec) + >>> pen.closePath() + >>> pprint(rec.value) + [('closePath', ())] + >>> rec = RecordingPen() + >>> pen = ExplicitClosingLinePen(rec) + >>> pen.moveTo((0, 0)) + >>> pen.lineTo((100, 0)) + >>> pen.lineTo((100, 100)) + >>> pen.endPath() + >>> pprint(rec.value) + [('moveTo', ((0, 0),)), + ('lineTo', ((100, 0),)), + ('lineTo', ((100, 100),)), + ('endPath', ())] + """ + + def filterContour(self, contour): + if ( + not contour + or contour[0][0] != "moveTo" + or contour[-1][0] != "closePath" + or len(contour) < 3 + ): + return + movePt = contour[0][1][0] + lastSeg = contour[-2][1] + if lastSeg and movePt != lastSeg[-1]: + contour[-1:] = [("lineTo", (movePt,)), ("closePath", ())] diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/filterPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/filterPen.py new file mode 100644 index 0000000000000000000000000000000000000000..73be8fa98e59c15af3a00f3aa51cd561ae19b92b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/filterPen.py @@ -0,0 +1,433 @@ +from __future__ import annotations + +from fontTools.pens.basePen import AbstractPen, DecomposingPen +from fontTools.pens.pointPen import ( + AbstractPointPen, + DecomposingPointPen, + ReverseFlipped, +) +from fontTools.pens.recordingPen import RecordingPen + + +class _PassThruComponentsMixin(object): + def addComponent(self, glyphName, transformation, **kwargs): + self._outPen.addComponent(glyphName, transformation, **kwargs) + + +class FilterPen(_PassThruComponentsMixin, AbstractPen): + """Base class for pens that apply some transformation to the coordinates + they receive and pass them to another pen. + + You can override any of its methods. The default implementation does + nothing, but passes the commands unmodified to the other pen. + + >>> from fontTools.pens.recordingPen import RecordingPen + >>> rec = RecordingPen() + >>> pen = FilterPen(rec) + >>> v = iter(rec.value) + + >>> pen.moveTo((0, 0)) + >>> next(v) + ('moveTo', ((0, 0),)) + + >>> pen.lineTo((1, 1)) + >>> next(v) + ('lineTo', ((1, 1),)) + + >>> pen.curveTo((2, 2), (3, 3), (4, 4)) + >>> next(v) + ('curveTo', ((2, 2), (3, 3), (4, 4))) + + >>> pen.qCurveTo((5, 5), (6, 6), (7, 7), (8, 8)) + >>> next(v) + ('qCurveTo', ((5, 5), (6, 6), (7, 7), (8, 8))) + + >>> pen.closePath() + >>> next(v) + ('closePath', ()) + + >>> pen.moveTo((9, 9)) + >>> next(v) + ('moveTo', ((9, 9),)) + + >>> pen.endPath() + >>> next(v) + ('endPath', ()) + + >>> pen.addComponent('foo', (1, 0, 0, 1, 0, 0)) + >>> next(v) + ('addComponent', ('foo', (1, 0, 0, 1, 0, 0))) + """ + + def __init__(self, outPen): + self._outPen = outPen + self.current_pt = None + + def moveTo(self, pt): + self._outPen.moveTo(pt) + self.current_pt = pt + + def lineTo(self, pt): + self._outPen.lineTo(pt) + self.current_pt = pt + + def curveTo(self, *points): + self._outPen.curveTo(*points) + self.current_pt = points[-1] + + def qCurveTo(self, *points): + self._outPen.qCurveTo(*points) + self.current_pt = points[-1] + + def closePath(self): + self._outPen.closePath() + self.current_pt = None + + def endPath(self): + self._outPen.endPath() + self.current_pt = None + + +class ContourFilterPen(_PassThruComponentsMixin, RecordingPen): + """A "buffered" filter pen that accumulates contour data, passes + it through a ``filterContour`` method when the contour is closed or ended, + and finally draws the result with the output pen. + + Components are passed through unchanged. + """ + + def __init__(self, outPen): + super(ContourFilterPen, self).__init__() + self._outPen = outPen + + def closePath(self): + super(ContourFilterPen, self).closePath() + self._flushContour() + + def endPath(self): + super(ContourFilterPen, self).endPath() + self._flushContour() + + def _flushContour(self): + result = self.filterContour(self.value) + if result is not None: + self.value = result + self.replay(self._outPen) + self.value = [] + + def filterContour(self, contour): + """Subclasses must override this to perform the filtering. + + The contour is a list of pen (operator, operands) tuples. + Operators are strings corresponding to the AbstractPen methods: + "moveTo", "lineTo", "curveTo", "qCurveTo", "closePath" and + "endPath". The operands are the positional arguments that are + passed to each method. + + If the method doesn't return a value (i.e. returns None), it's + assumed that the argument was modified in-place. + Otherwise, the return value is drawn with the output pen. + """ + return # or return contour + + +class FilterPointPen(_PassThruComponentsMixin, AbstractPointPen): + """Baseclass for point pens that apply some transformation to the + coordinates they receive and pass them to another point pen. + + You can override any of its methods. The default implementation does + nothing, but passes the commands unmodified to the other pen. + + >>> from fontTools.pens.recordingPen import RecordingPointPen + >>> rec = RecordingPointPen() + >>> pen = FilterPointPen(rec) + >>> v = iter(rec.value) + >>> pen.beginPath(identifier="abc") + >>> next(v) + ('beginPath', (), {'identifier': 'abc'}) + >>> pen.addPoint((1, 2), "line", False) + >>> next(v) + ('addPoint', ((1, 2), 'line', False, None), {}) + >>> pen.addComponent("a", (2, 0, 0, 2, 10, -10), identifier="0001") + >>> next(v) + ('addComponent', ('a', (2, 0, 0, 2, 10, -10)), {'identifier': '0001'}) + >>> pen.endPath() + >>> next(v) + ('endPath', (), {}) + """ + + def __init__(self, outPen): + self._outPen = outPen + + def beginPath(self, identifier=None, **kwargs): + kwargs = dict(kwargs) + if identifier is not None: + kwargs["identifier"] = identifier + self._outPen.beginPath(**kwargs) + + def endPath(self): + self._outPen.endPath() + + def addPoint( + self, + pt, + segmentType=None, + smooth=False, + name=None, + identifier=None, + **kwargs, + ): + kwargs = dict(kwargs) + if identifier is not None: + kwargs["identifier"] = identifier + self._outPen.addPoint(pt, segmentType, smooth, name, **kwargs) + + +class _DecomposingFilterMixinBase: + """Base mixin class with common `addComponent` logic for decomposing filter pens.""" + + def addComponent(self, baseGlyphName, transformation, **kwargs): + # only decompose the component if it's included in the set + if self.include is None or baseGlyphName in self.include: + # if we're decomposing nested components, temporarily set include to None + include_bak = self.include + if self.decomposeNested and self.include: + self.include = None + try: + super().addComponent(baseGlyphName, transformation, **kwargs) + finally: + if self.include != include_bak: + self.include = include_bak + else: + _PassThruComponentsMixin.addComponent( + self, baseGlyphName, transformation, **kwargs + ) + + +class _DecomposingFilterPenMixin(_DecomposingFilterMixinBase): + """Mixin class that decomposes components as regular contours for segment pens. + + Used by DecomposingFilterPen. + + Takes two required parameters, another segment pen 'outPen' to draw + with, and a 'glyphSet' dict of drawable glyph objects to draw components from. + + The 'skipMissingComponents' and 'reverseFlipped' optional arguments work the + same as in the DecomposingPen. reverseFlipped is bool only (True/False). + + In addition, the decomposing filter pens also take the following two options: + + 'include' is an optional set of component base glyph names to consider for + decomposition; the default include=None means decompose all components no matter + the base glyph name). + + 'decomposeNested' (bool) controls whether to recurse decomposition into nested + components of components (this only matters when 'include' was also provided); + if False, only decompose top-level components included in the set, but not + also their children. + """ + + # raises MissingComponentError if base glyph is not found in glyphSet + skipMissingComponents = False + + def __init__( + self, + outPen, + glyphSet, + skipMissingComponents=None, + reverseFlipped: bool = False, + include: set[str] | None = None, + decomposeNested: bool = True, + **kwargs, + ): + assert isinstance( + reverseFlipped, bool + ), f"Expected bool, got {type(reverseFlipped).__name__}" + super().__init__( + outPen=outPen, + glyphSet=glyphSet, + skipMissingComponents=skipMissingComponents, + reverseFlipped=reverseFlipped, + **kwargs, + ) + self.include = include + self.decomposeNested = decomposeNested + + +class _DecomposingFilterPointPenMixin(_DecomposingFilterMixinBase): + """Mixin class that decomposes components as regular contours for point pens. + + Takes two required parameters, another point pen 'outPen' to draw + with, and a 'glyphSet' dict of drawable glyph objects to draw components from. + + The 'skipMissingComponents' and 'reverseFlipped' optional arguments work the + same as in the DecomposingPointPen. reverseFlipped accepts bool | ReverseFlipped + (see DecomposingPointPen). + + In addition, the decomposing filter pens also take the following two options: + + 'include' is an optional set of component base glyph names to consider for + decomposition; the default include=None means decompose all components no matter + the base glyph name). + + 'decomposeNested' (bool) controls whether to recurse decomposition into nested + components of components (this only matters when 'include' was also provided); + if False, only decompose top-level components included in the set, but not + also their children. + """ + + # raises MissingComponentError if base glyph is not found in glyphSet + skipMissingComponents = False + + def __init__( + self, + outPen, + glyphSet, + skipMissingComponents=None, + reverseFlipped: bool | ReverseFlipped = False, + include: set[str] | None = None, + decomposeNested: bool = True, + **kwargs, + ): + super().__init__( + outPen=outPen, + glyphSet=glyphSet, + skipMissingComponents=skipMissingComponents, + reverseFlipped=reverseFlipped, + **kwargs, + ) + self.include = include + self.decomposeNested = decomposeNested + + +class DecomposingFilterPen(_DecomposingFilterPenMixin, DecomposingPen, FilterPen): + """Filter pen that draws components as regular contours.""" + + pass + + +class DecomposingFilterPointPen( + _DecomposingFilterPointPenMixin, DecomposingPointPen, FilterPointPen +): + """Filter point pen that draws components as regular contours.""" + + pass + + +class ContourFilterPointPen(_PassThruComponentsMixin, AbstractPointPen): + """A "buffered" filter point pen that accumulates contour data, passes + it through a ``filterContour`` method when the contour is closed or ended, + and finally draws the result with the output point pen. + + Components are passed through unchanged. + + The ``filterContour`` method can modify the contour in-place (return None) + or return a new contour to replace it. + """ + + def __init__(self, outPen): + self._outPen = outPen + self.currentContour = None + self.currentContourKwargs = None + + def beginPath(self, identifier=None, **kwargs): + if self.currentContour is not None: + raise ValueError("Path already begun") + kwargs = dict(kwargs) + if identifier is not None: + kwargs["identifier"] = identifier + self.currentContour = [] + self.currentContourKwargs = kwargs + + def endPath(self): + if self.currentContour is None: + raise ValueError("Path not begun") + self._flushContour() + self.currentContour = None + self.currentContourKwargs = None + + def _flushContour(self): + """Flush the current contour to the output pen.""" + result = self.filterContour(self.currentContour) + if result is not None: + self.currentContour = result + + # Draw the filtered contour + self._outPen.beginPath(**self.currentContourKwargs) + for pt, segmentType, smooth, name, kwargs in self.currentContour: + self._outPen.addPoint(pt, segmentType, smooth, name, **kwargs) + self._outPen.endPath() + + def filterContour(self, contour): + """Subclasses must override this to perform the filtering. + + The contour is a list of (pt, segmentType, smooth, name, kwargs) tuples. + If the method doesn't return a value (i.e. returns None), it's + assumed that the contour was modified in-place. + Otherwise, the return value replaces the original contour. + """ + return # or return contour + + def addPoint( + self, + pt, + segmentType=None, + smooth=False, + name=None, + identifier=None, + **kwargs, + ): + if self.currentContour is None: + raise ValueError("Path not begun") + kwargs = dict(kwargs) + if identifier is not None: + kwargs["identifier"] = identifier + self.currentContour.append((pt, segmentType, smooth, name, kwargs)) + + +class OnCurveFirstPointPen(ContourFilterPointPen): + """Filter point pen that ensures closed contours start with an on-curve point. + + If a closed contour starts with an off-curve point (segmentType=None), it rotates + the points list so that the first on-curve point (segmentType != None) becomes + the start point. Open contours and contours already starting with on-curve points + are passed through unchanged. + + >>> from fontTools.pens.recordingPen import RecordingPointPen + >>> rec = RecordingPointPen() + >>> pen = OnCurveFirstPointPen(rec) + >>> # Closed contour starting with off-curve - will be rotated + >>> pen.beginPath() + >>> pen.addPoint((0, 0), None) # off-curve + >>> pen.addPoint((100, 100), "line") # on-curve - will become start + >>> pen.addPoint((200, 0), None) # off-curve + >>> pen.addPoint((300, 100), "curve") # on-curve + >>> pen.endPath() + >>> # The contour should now start with (100, 100) "line" + >>> rec.value[0] + ('beginPath', (), {}) + >>> rec.value[1] + ('addPoint', ((100, 100), 'line', False, None), {}) + >>> rec.value[2] + ('addPoint', ((200, 0), None, False, None), {}) + >>> rec.value[3] + ('addPoint', ((300, 100), 'curve', False, None), {}) + >>> rec.value[4] + ('addPoint', ((0, 0), None, False, None), {}) + """ + + def filterContour(self, contour): + """Rotate closed contour to start with first on-curve point if needed.""" + if not contour: + return + + # Check if it's a closed contour (no "move" segmentType) + is_closed = contour[0][1] != "move" + + if is_closed and contour[0][1] is None: + # Closed contour starting with off-curve - need to rotate + # Find the first on-curve point + for i, (pt, segmentType, smooth, name, kwargs) in enumerate(contour): + if segmentType is not None: + # Rotate the points list so it starts with the first on-curve point + return contour[i:] + contour[:i] diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/freetypePen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/freetypePen.py new file mode 100644 index 0000000000000000000000000000000000000000..065da932a2b8437b09d0f72dc9821516da45473a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/freetypePen.py @@ -0,0 +1,462 @@ +# -*- coding: utf-8 -*- + +"""Pen to rasterize paths with FreeType.""" + +__all__ = ["FreeTypePen"] + +import os +import ctypes +import platform +import subprocess +import collections +import math + +import freetype +from freetype.raw import FT_Outline_Get_Bitmap, FT_Outline_Get_BBox, FT_Outline_Get_CBox +from freetype.ft_types import FT_Pos +from freetype.ft_structs import FT_Vector, FT_BBox, FT_Bitmap, FT_Outline +from freetype.ft_enums import ( + FT_OUTLINE_NONE, + FT_OUTLINE_EVEN_ODD_FILL, + FT_PIXEL_MODE_GRAY, + FT_CURVE_TAG_ON, + FT_CURVE_TAG_CONIC, + FT_CURVE_TAG_CUBIC, +) +from freetype.ft_errors import FT_Exception + +from fontTools.pens.basePen import BasePen, PenError +from fontTools.misc.roundTools import otRound +from fontTools.misc.transform import Transform + +Contour = collections.namedtuple("Contour", ("points", "tags")) + + +class FreeTypePen(BasePen): + """Pen to rasterize paths with FreeType. Requires `freetype-py` module. + + Constructs ``FT_Outline`` from the paths, and renders it within a bitmap + buffer. + + For ``array()`` and ``show()``, `numpy` and `matplotlib` must be installed. + For ``image()``, `Pillow` is required. Each module is lazily loaded when the + corresponding method is called. + + Args: + glyphSet: a dictionary of drawable glyph objects keyed by name + used to resolve component references in composite glyphs. + + Examples: + If `numpy` and `matplotlib` is available, the following code will + show the glyph image of `fi` in a new window:: + + from fontTools.ttLib import TTFont + from fontTools.pens.freetypePen import FreeTypePen + from fontTools.misc.transform import Offset + pen = FreeTypePen(None) + font = TTFont('SourceSansPro-Regular.otf') + glyph = font.getGlyphSet()['fi'] + glyph.draw(pen) + width, ascender, descender = glyph.width, font['OS/2'].usWinAscent, -font['OS/2'].usWinDescent + height = ascender - descender + pen.show(width=width, height=height, transform=Offset(0, -descender)) + + Combining with `uharfbuzz`, you can typeset a chunk of glyphs in a pen:: + + import uharfbuzz as hb + from fontTools.pens.freetypePen import FreeTypePen + from fontTools.pens.transformPen import TransformPen + from fontTools.misc.transform import Offset + + en1, en2, ar, ja = 'Typesetting', 'Jeff', 'صف الحروف', 'たいぷせっと' + for text, font_path, direction, typo_ascender, typo_descender, vhea_ascender, vhea_descender, contain, features in ( + (en1, 'NotoSans-Regular.ttf', 'ltr', 2189, -600, None, None, False, {"kern": True, "liga": True}), + (en2, 'NotoSans-Regular.ttf', 'ltr', 2189, -600, None, None, True, {"kern": True, "liga": True}), + (ar, 'NotoSansArabic-Regular.ttf', 'rtl', 1374, -738, None, None, False, {"kern": True, "liga": True}), + (ja, 'NotoSansJP-Regular.otf', 'ltr', 880, -120, 500, -500, False, {"palt": True, "kern": True}), + (ja, 'NotoSansJP-Regular.otf', 'ttb', 880, -120, 500, -500, False, {"vert": True, "vpal": True, "vkrn": True}) + ): + blob = hb.Blob.from_file_path(font_path) + face = hb.Face(blob) + font = hb.Font(face) + buf = hb.Buffer() + buf.direction = direction + buf.add_str(text) + buf.guess_segment_properties() + hb.shape(font, buf, features) + + x, y = 0, 0 + pen = FreeTypePen(None) + for info, pos in zip(buf.glyph_infos, buf.glyph_positions): + gid = info.codepoint + transformed = TransformPen(pen, Offset(x + pos.x_offset, y + pos.y_offset)) + font.draw_glyph_with_pen(gid, transformed) + x += pos.x_advance + y += pos.y_advance + + offset, width, height = None, None, None + if direction in ('ltr', 'rtl'): + offset = (0, -typo_descender) + width = x + height = typo_ascender - typo_descender + else: + offset = (-vhea_descender, -y) + width = vhea_ascender - vhea_descender + height = -y + pen.show(width=width, height=height, transform=Offset(*offset), contain=contain) + + For Jupyter Notebook, the rendered image will be displayed in a cell if + you replace ``show()`` with ``image()`` in the examples. + """ + + def __init__(self, glyphSet): + BasePen.__init__(self, glyphSet) + self.contours = [] + + def outline(self, transform=None, evenOdd=False): + """Converts the current contours to ``FT_Outline``. + + Args: + transform: An optional 6-tuple containing an affine transformation, + or a ``Transform`` object from the ``fontTools.misc.transform`` + module. + evenOdd: Pass ``True`` for even-odd fill instead of non-zero. + """ + transform = transform or Transform() + if not hasattr(transform, "transformPoint"): + transform = Transform(*transform) + n_contours = len(self.contours) + n_points = sum((len(contour.points) for contour in self.contours)) + points = [] + for contour in self.contours: + for point in contour.points: + point = transform.transformPoint(point) + points.append( + FT_Vector( + FT_Pos(otRound(point[0] * 64)), FT_Pos(otRound(point[1] * 64)) + ) + ) + tags = [] + for contour in self.contours: + for tag in contour.tags: + tags.append(tag) + contours = [] + contours_sum = 0 + for contour in self.contours: + contours_sum += len(contour.points) + contours.append(contours_sum - 1) + flags = FT_OUTLINE_EVEN_ODD_FILL if evenOdd else FT_OUTLINE_NONE + return FT_Outline( + (ctypes.c_short)(n_contours), + (ctypes.c_short)(n_points), + (FT_Vector * n_points)(*points), + (ctypes.c_ubyte * n_points)(*tags), + (ctypes.c_short * n_contours)(*contours), + (ctypes.c_int)(flags), + ) + + def buffer( + self, width=None, height=None, transform=None, contain=False, evenOdd=False + ): + """Renders the current contours within a bitmap buffer. + + Args: + width: Image width of the bitmap in pixels. If omitted, it + automatically fits to the bounding box of the contours. + height: Image height of the bitmap in pixels. If omitted, it + automatically fits to the bounding box of the contours. + transform: An optional 6-tuple containing an affine transformation, + or a ``Transform`` object from the ``fontTools.misc.transform`` + module. The bitmap size is not affected by this matrix. + contain: If ``True``, the image size will be automatically expanded + so that it fits to the bounding box of the paths. Useful for + rendering glyphs with negative sidebearings without clipping. + evenOdd: Pass ``True`` for even-odd fill instead of non-zero. + + Returns: + A tuple of ``(buffer, size)``, where ``buffer`` is a ``bytes`` + object of the resulted bitmap and ``size`` is a 2-tuple of its + dimension. + + Notes: + The image size should always be given explicitly if you need to get + a proper glyph image. When ``width`` and ``height`` are omitted, it + forcifully fits to the bounding box and the side bearings get + cropped. If you pass ``0`` to both ``width`` and ``height`` and set + ``contain`` to ``True``, it expands to the bounding box while + maintaining the origin of the contours, meaning that LSB will be + maintained but RSB won’t. The difference between the two becomes + more obvious when rotate or skew transformation is applied. + + Example: + .. code-block:: pycon + + >>> + >> pen = FreeTypePen(None) + >> glyph.draw(pen) + >> buf, size = pen.buffer(width=500, height=1000) + >> type(buf), len(buf), size + (, 500000, (500, 1000)) + """ + transform = transform or Transform() + if not hasattr(transform, "transformPoint"): + transform = Transform(*transform) + contain_x, contain_y = contain or width is None, contain or height is None + if contain_x or contain_y: + dx, dy = transform.dx, transform.dy + bbox = self.bbox + p1, p2, p3, p4 = ( + transform.transformPoint((bbox[0], bbox[1])), + transform.transformPoint((bbox[2], bbox[1])), + transform.transformPoint((bbox[0], bbox[3])), + transform.transformPoint((bbox[2], bbox[3])), + ) + px, py = (p1[0], p2[0], p3[0], p4[0]), (p1[1], p2[1], p3[1], p4[1]) + if contain_x: + if width is None: + dx = dx - min(*px) + width = max(*px) - min(*px) + else: + dx = dx - min(min(*px), 0.0) + width = max(width, max(*px) - min(min(*px), 0.0)) + if contain_y: + if height is None: + dy = dy - min(*py) + height = max(*py) - min(*py) + else: + dy = dy - min(min(*py), 0.0) + height = max(height, max(*py) - min(min(*py), 0.0)) + transform = Transform(*transform[:4], dx, dy) + width, height = math.ceil(width), math.ceil(height) + buf = ctypes.create_string_buffer(width * height) + bitmap = FT_Bitmap( + (ctypes.c_int)(height), + (ctypes.c_int)(width), + (ctypes.c_int)(width), + (ctypes.POINTER(ctypes.c_ubyte))(buf), + (ctypes.c_short)(256), + (ctypes.c_ubyte)(FT_PIXEL_MODE_GRAY), + (ctypes.c_char)(0), + (ctypes.c_void_p)(None), + ) + outline = self.outline(transform=transform, evenOdd=evenOdd) + err = FT_Outline_Get_Bitmap( + freetype.get_handle(), ctypes.byref(outline), ctypes.byref(bitmap) + ) + if err != 0: + raise FT_Exception(err) + return buf.raw, (width, height) + + def array( + self, width=None, height=None, transform=None, contain=False, evenOdd=False + ): + """Returns the rendered contours as a numpy array. Requires `numpy`. + + Args: + width: Image width of the bitmap in pixels. If omitted, it + automatically fits to the bounding box of the contours. + height: Image height of the bitmap in pixels. If omitted, it + automatically fits to the bounding box of the contours. + transform: An optional 6-tuple containing an affine transformation, + or a ``Transform`` object from the ``fontTools.misc.transform`` + module. The bitmap size is not affected by this matrix. + contain: If ``True``, the image size will be automatically expanded + so that it fits to the bounding box of the paths. Useful for + rendering glyphs with negative sidebearings without clipping. + evenOdd: Pass ``True`` for even-odd fill instead of non-zero. + + Returns: + A ``numpy.ndarray`` object with a shape of ``(height, width)``. + Each element takes a value in the range of ``[0.0, 1.0]``. + + Notes: + The image size should always be given explicitly if you need to get + a proper glyph image. When ``width`` and ``height`` are omitted, it + forcifully fits to the bounding box and the side bearings get + cropped. If you pass ``0`` to both ``width`` and ``height`` and set + ``contain`` to ``True``, it expands to the bounding box while + maintaining the origin of the contours, meaning that LSB will be + maintained but RSB won’t. The difference between the two becomes + more obvious when rotate or skew transformation is applied. + + Example: + .. code-block:: pycon + + >>> + >> pen = FreeTypePen(None) + >> glyph.draw(pen) + >> arr = pen.array(width=500, height=1000) + >> type(a), a.shape + (, (1000, 500)) + """ + + import numpy as np + + buf, size = self.buffer( + width=width, + height=height, + transform=transform, + contain=contain, + evenOdd=evenOdd, + ) + return np.frombuffer(buf, "B").reshape((size[1], size[0])) / 255.0 + + def show( + self, width=None, height=None, transform=None, contain=False, evenOdd=False + ): + """Plots the rendered contours with `pyplot`. Requires `numpy` and + `matplotlib`. + + Args: + width: Image width of the bitmap in pixels. If omitted, it + automatically fits to the bounding box of the contours. + height: Image height of the bitmap in pixels. If omitted, it + automatically fits to the bounding box of the contours. + transform: An optional 6-tuple containing an affine transformation, + or a ``Transform`` object from the ``fontTools.misc.transform`` + module. The bitmap size is not affected by this matrix. + contain: If ``True``, the image size will be automatically expanded + so that it fits to the bounding box of the paths. Useful for + rendering glyphs with negative sidebearings without clipping. + evenOdd: Pass ``True`` for even-odd fill instead of non-zero. + + Notes: + The image size should always be given explicitly if you need to get + a proper glyph image. When ``width`` and ``height`` are omitted, it + forcifully fits to the bounding box and the side bearings get + cropped. If you pass ``0`` to both ``width`` and ``height`` and set + ``contain`` to ``True``, it expands to the bounding box while + maintaining the origin of the contours, meaning that LSB will be + maintained but RSB won’t. The difference between the two becomes + more obvious when rotate or skew transformation is applied. + + Example: + .. code-block:: pycon + + >>> + >> pen = FreeTypePen(None) + >> glyph.draw(pen) + >> pen.show(width=500, height=1000) + """ + from matplotlib import pyplot as plt + + a = self.array( + width=width, + height=height, + transform=transform, + contain=contain, + evenOdd=evenOdd, + ) + plt.imshow(a, cmap="gray_r", vmin=0, vmax=1) + plt.show() + + def image( + self, width=None, height=None, transform=None, contain=False, evenOdd=False + ): + """Returns the rendered contours as a PIL image. Requires `Pillow`. + Can be used to display a glyph image in Jupyter Notebook. + + Args: + width: Image width of the bitmap in pixels. If omitted, it + automatically fits to the bounding box of the contours. + height: Image height of the bitmap in pixels. If omitted, it + automatically fits to the bounding box of the contours. + transform: An optional 6-tuple containing an affine transformation, + or a ``Transform`` object from the ``fontTools.misc.transform`` + module. The bitmap size is not affected by this matrix. + contain: If ``True``, the image size will be automatically expanded + so that it fits to the bounding box of the paths. Useful for + rendering glyphs with negative sidebearings without clipping. + evenOdd: Pass ``True`` for even-odd fill instead of non-zero. + + Returns: + A ``PIL.image`` object. The image is filled in black with alpha + channel obtained from the rendered bitmap. + + Notes: + The image size should always be given explicitly if you need to get + a proper glyph image. When ``width`` and ``height`` are omitted, it + forcifully fits to the bounding box and the side bearings get + cropped. If you pass ``0`` to both ``width`` and ``height`` and set + ``contain`` to ``True``, it expands to the bounding box while + maintaining the origin of the contours, meaning that LSB will be + maintained but RSB won’t. The difference between the two becomes + more obvious when rotate or skew transformation is applied. + + Example: + .. code-block:: pycon + + >>> + >> pen = FreeTypePen(None) + >> glyph.draw(pen) + >> img = pen.image(width=500, height=1000) + >> type(img), img.size + (, (500, 1000)) + """ + from PIL import Image + + buf, size = self.buffer( + width=width, + height=height, + transform=transform, + contain=contain, + evenOdd=evenOdd, + ) + img = Image.new("L", size, 0) + img.putalpha(Image.frombuffer("L", size, buf)) + return img + + @property + def bbox(self): + """Computes the exact bounding box of an outline. + + Returns: + A tuple of ``(xMin, yMin, xMax, yMax)``. + """ + bbox = FT_BBox() + outline = self.outline() + FT_Outline_Get_BBox(ctypes.byref(outline), ctypes.byref(bbox)) + return (bbox.xMin / 64.0, bbox.yMin / 64.0, bbox.xMax / 64.0, bbox.yMax / 64.0) + + @property + def cbox(self): + """Returns an outline's ‘control box’. + + Returns: + A tuple of ``(xMin, yMin, xMax, yMax)``. + """ + cbox = FT_BBox() + outline = self.outline() + FT_Outline_Get_CBox(ctypes.byref(outline), ctypes.byref(cbox)) + return (cbox.xMin / 64.0, cbox.yMin / 64.0, cbox.xMax / 64.0, cbox.yMax / 64.0) + + def _moveTo(self, pt): + contour = Contour([], []) + self.contours.append(contour) + contour.points.append(pt) + contour.tags.append(FT_CURVE_TAG_ON) + + def _lineTo(self, pt): + if not (self.contours and len(self.contours[-1].points) > 0): + raise PenError("Contour missing required initial moveTo") + contour = self.contours[-1] + contour.points.append(pt) + contour.tags.append(FT_CURVE_TAG_ON) + + def _curveToOne(self, p1, p2, p3): + if not (self.contours and len(self.contours[-1].points) > 0): + raise PenError("Contour missing required initial moveTo") + t1, t2, t3 = FT_CURVE_TAG_CUBIC, FT_CURVE_TAG_CUBIC, FT_CURVE_TAG_ON + contour = self.contours[-1] + for p, t in ((p1, t1), (p2, t2), (p3, t3)): + contour.points.append(p) + contour.tags.append(t) + + def _qCurveToOne(self, p1, p2): + if not (self.contours and len(self.contours[-1].points) > 0): + raise PenError("Contour missing required initial moveTo") + t1, t2 = FT_CURVE_TAG_CONIC, FT_CURVE_TAG_ON + contour = self.contours[-1] + for p, t in ((p1, t1), (p2, t2)): + contour.points.append(p) + contour.tags.append(t) diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/hashPointPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/hashPointPen.py new file mode 100644 index 0000000000000000000000000000000000000000..f15dcabbfd51c7706480ccf35e398c81686cc0f5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/hashPointPen.py @@ -0,0 +1,89 @@ +# Modified from https://github.com/adobe-type-tools/psautohint/blob/08b346865710ed3c172f1eb581d6ef243b203f99/python/psautohint/ufoFont.py#L800-L838 +import hashlib + +from fontTools.pens.basePen import MissingComponentError +from fontTools.pens.pointPen import AbstractPointPen + + +class HashPointPen(AbstractPointPen): + """ + This pen can be used to check if a glyph's contents (outlines plus + components) have changed. + + Components are added as the original outline plus each composite's + transformation. + + Example: You have some TrueType hinting code for a glyph which you want to + compile. The hinting code specifies a hash value computed with HashPointPen + that was valid for the glyph's outlines at the time the hinting code was + written. Now you can calculate the hash for the glyph's current outlines to + check if the outlines have changed, which would probably make the hinting + code invalid. + + > glyph = ufo[name] + > hash_pen = HashPointPen(glyph.width, ufo) + > glyph.drawPoints(hash_pen) + > ttdata = glyph.lib.get("public.truetype.instructions", None) + > stored_hash = ttdata.get("id", None) # The hash is stored in the "id" key + > if stored_hash is None or stored_hash != hash_pen.hash: + > logger.error(f"Glyph hash mismatch, glyph '{name}' will have no instructions in font.") + > else: + > # The hash values are identical, the outline has not changed. + > # Compile the hinting code ... + > pass + + If you want to compare a glyph from a source format which supports floating point + coordinates and transformations against a glyph from a format which has restrictions + on the precision of floats, e.g. UFO vs. TTF, you must use an appropriate rounding + function to make the values comparable. For TTF fonts with composites, this + construct can be used to make the transform values conform to F2Dot14: + + > ttf_hash_pen = HashPointPen(ttf_glyph_width, ttFont.getGlyphSet()) + > ttf_round_pen = RoundingPointPen(ttf_hash_pen, transformRoundFunc=partial(floatToFixedToFloat, precisionBits=14)) + > ufo_hash_pen = HashPointPen(ufo_glyph.width, ufo) + > ttf_glyph.drawPoints(ttf_round_pen, ttFont["glyf"]) + > ufo_round_pen = RoundingPointPen(ufo_hash_pen, transformRoundFunc=partial(floatToFixedToFloat, precisionBits=14)) + > ufo_glyph.drawPoints(ufo_round_pen) + > assert ttf_hash_pen.hash == ufo_hash_pen.hash + """ + + def __init__(self, glyphWidth=0, glyphSet=None): + self.glyphset = glyphSet + self.data = ["w%s" % round(glyphWidth, 9)] + + @property + def hash(self): + data = "".join(self.data) + if len(data) >= 128: + data = hashlib.sha512(data.encode("ascii")).hexdigest() + return data + + def beginPath(self, identifier=None, **kwargs): + pass + + def endPath(self): + self.data.append("|") + + def addPoint( + self, + pt, + segmentType=None, + smooth=False, + name=None, + identifier=None, + **kwargs, + ): + if segmentType is None: + pt_type = "o" # offcurve + else: + pt_type = segmentType[0] + self.data.append(f"{pt_type}{pt[0]:g}{pt[1]:+g}") + + def addComponent(self, baseGlyphName, transformation, identifier=None, **kwargs): + tr = "".join([f"{t:+}" for t in transformation]) + self.data.append("[") + try: + self.glyphset[baseGlyphName].drawPoints(self) + except KeyError: + raise MissingComponentError(baseGlyphName) + self.data.append(f"({tr})]") diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/momentsPen.c b/.venv/lib/python3.13/site-packages/fontTools/pens/momentsPen.c new file mode 100644 index 0000000000000000000000000000000000000000..309ea5460df6a5d635072b6ec7de6c408d331e78 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/momentsPen.c @@ -0,0 +1,13378 @@ +/* Generated by Cython 3.2.2 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "name": "fontTools.pens.momentsPen", + "sources": [ + "Lib/fontTools/pens/momentsPen.py" + ] + }, + "module_name": "fontTools.pens.momentsPen" +} +END: Cython Metadata */ + +#ifndef PY_SSIZE_T_CLEAN +#define PY_SSIZE_T_CLEAN +#endif /* PY_SSIZE_T_CLEAN */ +/* InitLimitedAPI */ +#if defined(Py_LIMITED_API) + #if !defined(CYTHON_LIMITED_API) + #define CYTHON_LIMITED_API 1 + #endif +#elif defined(CYTHON_LIMITED_API) + #ifdef _MSC_VER + #pragma message ("Limited API usage is enabled with 'CYTHON_LIMITED_API' but 'Py_LIMITED_API' does not define a Python target version. Consider setting 'Py_LIMITED_API' instead.") + #else + #warning Limited API usage is enabled with 'CYTHON_LIMITED_API' but 'Py_LIMITED_API' does not define a Python target version. Consider setting 'Py_LIMITED_API' instead. + #endif +#endif + +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x03080000 + #error Cython requires Python 3.8+. +#else +#define __PYX_ABI_VERSION "3_2_2" +#define CYTHON_HEX_VERSION 0x030202F0 +#define CYTHON_FUTURE_DIVISION 1 +/* CModulePreamble */ +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(_WIN32) && !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#define __PYX_LIMITED_VERSION_HEX PY_VERSION_HEX +#if defined(GRAALVM_PYTHON) + /* For very preliminary testing purposes. Most variables are set the same as PyPy. + The existence of this section does not imply that anything works or is even tested */ + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 1 + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 0 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 1 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif + #undef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 +#elif defined(PYPY_VERSION) + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #ifndef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 1 + #endif + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #if PY_VERSION_HEX < 0x03090000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING 0 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PYPY_VERSION_NUM >= 0x07030C00) + #endif + #undef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC (PYPY_VERSION_NUM >= 0x07031100) + #endif + #undef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 +#elif defined(CYTHON_LIMITED_API) + #ifdef Py_LIMITED_API + #undef __PYX_LIMITED_VERSION_HEX + #define __PYX_LIMITED_VERSION_HEX Py_LIMITED_API + #endif + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 1 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 1 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #endif + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 0 + #endif + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL (__PYX_LIMITED_VERSION_HEX >= 0x030C0000) + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #undef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING 0 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #endif + #ifndef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND (__PYX_LIMITED_VERSION_HEX >= 0x030A0000) + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif + #ifndef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 1 + #endif + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #ifdef Py_GIL_DISABLED + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 1 + #else + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #endif + #if PY_VERSION_HEX < 0x030A0000 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #elif !defined(CYTHON_USE_TYPE_SLOTS) + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #ifndef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #ifndef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #elif !defined(CYTHON_USE_PYLIST_INTERNALS) + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING || PY_VERSION_HEX >= 0x030B00A2 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 1 + #elif !defined(CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS) + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #elif !defined(CYTHON_FAST_GIL) + #define CYTHON_FAST_GIL (PY_VERSION_HEX < 0x030C00A6) + #endif + #ifndef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 1 + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #ifndef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING (PY_VERSION_HEX >= 0x030d00B1) + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #ifndef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #elif !defined(CYTHON_USE_DICT_VERSIONS) + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX < 0x030C00A5 && !CYTHON_USE_MODULE_STATE) + #endif + #ifndef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 1 + #endif + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 + #endif + #ifndef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS (!CYTHON_COMPILING_IN_CPYTHON_FREETHREADING) + #endif + #if defined(CYTHON_IMMORTAL_CONSTANTS) && PY_VERSION_HEX < 0x030C0000 + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 // definitely won't work + #elif !defined(CYTHON_IMMORTAL_CONSTANTS) + #define CYTHON_IMMORTAL_CONSTANTS (PY_VERSION_HEX >= 0x030C0000 && !CYTHON_USE_MODULE_STATE && CYTHON_COMPILING_IN_CPYTHON_FREETHREADING) + #endif +#endif +#ifndef CYTHON_COMPRESS_STRINGS + #define CYTHON_COMPRESS_STRINGS 1 +#endif +#ifndef CYTHON_FAST_PYCCALL +#define CYTHON_FAST_PYCCALL CYTHON_FAST_PYCALL +#endif +#ifndef CYTHON_VECTORCALL +#if CYTHON_COMPILING_IN_LIMITED_API +#define CYTHON_VECTORCALL (__PYX_LIMITED_VERSION_HEX >= 0x030C0000) +#else +#define CYTHON_VECTORCALL (CYTHON_FAST_PYCCALL) +#endif +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(maybe_unused) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(maybe_unused) + #define CYTHON_UNUSED [[maybe_unused]] + #endif + #endif + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR + #define CYTHON_MAYBE_UNUSED_VAR(x) CYTHON_UNUSED_VAR(x) +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON && !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_USE_CPP_STD_MOVE + #if defined(__cplusplus) && (\ + __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)) + #define CYTHON_USE_CPP_STD_MOVE 1 + #else + #define CYTHON_USE_CPP_STD_MOVE 0 + #endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#include +typedef uintptr_t __pyx_uintptr_t; +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(fallthrough) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif +#ifndef Py_UNREACHABLE + #define Py_UNREACHABLE() assert(0); abort() +#endif +#ifdef __cplusplus + template + struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);}; + #define __PYX_IS_UNSIGNED(type) (__PYX_IS_UNSIGNED_IMPL::value) +#else + #define __PYX_IS_UNSIGNED(type) (((type)-1) > 0) +#endif +#if CYTHON_COMPILING_IN_PYPY == 1 + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX < 0x030A0000) +#else + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX < 0x03090000) +#endif +#define __PYX_REINTERPRET_FUNCION(func_pointer, other_pointer) ((func_pointer)(void(*)(void))(other_pointer)) + +/* CInitCode */ +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +/* PythonCompatibility */ +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#define __Pyx_BUILTIN_MODULE_NAME "builtins" +#define __Pyx_DefaultClassType PyType_Type +#if CYTHON_COMPILING_IN_LIMITED_API + #ifndef CO_OPTIMIZED + static int CO_OPTIMIZED; + #endif + #ifndef CO_NEWLOCALS + static int CO_NEWLOCALS; + #endif + #ifndef CO_VARARGS + static int CO_VARARGS; + #endif + #ifndef CO_VARKEYWORDS + static int CO_VARKEYWORDS; + #endif + #ifndef CO_ASYNC_GENERATOR + static int CO_ASYNC_GENERATOR; + #endif + #ifndef CO_GENERATOR + static int CO_GENERATOR; + #endif + #ifndef CO_COROUTINE + static int CO_COROUTINE; + #endif +#else + #ifndef CO_COROUTINE + #define CO_COROUTINE 0x80 + #endif + #ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x200 + #endif +#endif +static int __Pyx_init_co_variables(void); +#if PY_VERSION_HEX >= 0x030900A4 || defined(Py_IS_TYPE) + #define __Pyx_IS_TYPE(ob, type) Py_IS_TYPE(ob, type) +#else + #define __Pyx_IS_TYPE(ob, type) (((const PyObject*)ob)->ob_type == (type)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_Is) + #define __Pyx_Py_Is(x, y) Py_Is(x, y) +#else + #define __Pyx_Py_Is(x, y) ((x) == (y)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsNone) + #define __Pyx_Py_IsNone(ob) Py_IsNone(ob) +#else + #define __Pyx_Py_IsNone(ob) __Pyx_Py_Is((ob), Py_None) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsTrue) + #define __Pyx_Py_IsTrue(ob) Py_IsTrue(ob) +#else + #define __Pyx_Py_IsTrue(ob) __Pyx_Py_Is((ob), Py_True) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsFalse) + #define __Pyx_Py_IsFalse(ob) Py_IsFalse(ob) +#else + #define __Pyx_Py_IsFalse(ob) __Pyx_Py_Is((ob), Py_False) +#endif +#define __Pyx_NoneAsNull(obj) (__Pyx_Py_IsNone(obj) ? NULL : (obj)) +#if PY_VERSION_HEX >= 0x030900F0 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyObject_GC_IsFinalized(o) PyObject_GC_IsFinalized(o) +#else + #define __Pyx_PyObject_GC_IsFinalized(o) _PyGC_FINALIZED(o) +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef Py_TPFLAGS_SEQUENCE + #define Py_TPFLAGS_SEQUENCE 0 +#endif +#ifndef Py_TPFLAGS_MAPPING + #define Py_TPFLAGS_MAPPING 0 +#endif +#ifndef Py_TPFLAGS_IMMUTABLETYPE + #define Py_TPFLAGS_IMMUTABLETYPE (1UL << 8) +#endif +#ifndef Py_TPFLAGS_DISALLOW_INSTANTIATION + #define Py_TPFLAGS_DISALLOW_INSTANTIATION (1UL << 7) +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#ifndef METH_FASTCALL + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #if PY_VERSION_HEX >= 0x030d00A4 + # define __Pyx_PyCFunctionFast PyCFunctionFast + # define __Pyx_PyCFunctionFastWithKeywords PyCFunctionFastWithKeywords + #else + # define __Pyx_PyCFunctionFast _PyCFunctionFast + # define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords + #endif +#endif +#if CYTHON_METH_FASTCALL + #define __Pyx_METH_FASTCALL METH_FASTCALL + #define __Pyx_PyCFunction_FastCall __Pyx_PyCFunctionFast + #define __Pyx_PyCFunction_FastCallWithKeywords __Pyx_PyCFunctionFastWithKeywords +#else + #define __Pyx_METH_FASTCALL METH_VARARGS + #define __Pyx_PyCFunction_FastCall PyCFunction + #define __Pyx_PyCFunction_FastCallWithKeywords PyCFunctionWithKeywords +#endif +#if CYTHON_VECTORCALL + #define __pyx_vectorcallfunc vectorcallfunc + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET PY_VECTORCALL_ARGUMENTS_OFFSET + #define __Pyx_PyVectorcall_NARGS(n) PyVectorcall_NARGS((size_t)(n)) +#else + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET 0 + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(n)) +#endif +#if PY_VERSION_HEX >= 0x030900B1 +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_CheckExact(func) +#else +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_Check(func) +#endif +#define __Pyx_CyOrPyCFunction_Check(func) PyCFunction_Check(func) +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) (((PyCFunctionObject*)(func))->m_ml->ml_meth) +#elif !CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(func) +#endif +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FLAGS(func) (((PyCFunctionObject*)(func))->m_ml->ml_flags) +static CYTHON_INLINE PyObject* __Pyx_CyOrPyCFunction_GET_SELF(PyObject *func) { + return (__Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_STATIC) ? NULL : ((PyCFunctionObject*)func)->m_self; +} +#endif +static CYTHON_INLINE int __Pyx__IsSameCFunction(PyObject *func, void (*cfunc)(void)) { +#if CYTHON_COMPILING_IN_LIMITED_API + return PyCFunction_Check(func) && PyCFunction_GetFunction(func) == (PyCFunction) cfunc; +#else + return PyCFunction_Check(func) && PyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +#endif +} +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCFunction(func, cfunc) +#if PY_VERSION_HEX < 0x03090000 || (CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000) + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) ((void)m, PyType_FromSpecWithBases(s, b)) + typedef PyObject *(*__Pyx_PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *); +#else + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) PyType_FromModuleAndSpec(m, s, b) + #define __Pyx_PyCMethod PyCMethod +#endif +#ifndef METH_METHOD + #define METH_METHOD 0x200 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) +#elif CYTHON_COMPILING_IN_GRAAL && defined(GRAALPY_VERSION_NUM) && GRAALPY_VERSION_NUM > 0x19000000 + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) GraalPyFrame_SetLineNumber((frame), (lineno)) +#elif CYTHON_COMPILING_IN_GRAAL + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) _PyFrame_SetLineNumber((frame), (lineno)) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyThreadState_Current PyThreadState_Get() +#elif !CYTHON_FAST_THREAD_STATE + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyThreadState_Current PyThreadState_GetUnchecked() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#endif +#if CYTHON_USE_MODULE_STATE +static CYTHON_INLINE void *__Pyx__PyModule_GetState(PyObject *op) +{ + void *result; + result = PyModule_GetState(op); + if (!result) + Py_FatalError("Couldn't find the module state"); + return result; +} +#define __Pyx_PyModule_GetState(o) (__pyx_mstatetype *)__Pyx__PyModule_GetState(o) +#else +#define __Pyx_PyModule_GetState(op) ((void)op,__pyx_mstate_global) +#endif +#define __Pyx_PyObject_GetSlot(obj, name, func_ctype) __Pyx_PyType_GetSlot(Py_TYPE((PyObject *) obj), name, func_ctype) +#define __Pyx_PyObject_TryGetSlot(obj, name, func_ctype) __Pyx_PyType_TryGetSlot(Py_TYPE(obj), name, func_ctype) +#define __Pyx_PyObject_GetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_GetSubSlot(Py_TYPE(obj), sub, name, func_ctype) +#define __Pyx_PyObject_TryGetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_TryGetSubSlot(Py_TYPE(obj), sub, name, func_ctype) +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((type)->name) + #define __Pyx_PyType_TryGetSlot(type, name, func_ctype) __Pyx_PyType_GetSlot(type, name, func_ctype) + #define __Pyx_PyType_GetSubSlot(type, sub, name, func_ctype) (((type)->sub) ? ((type)->sub->name) : NULL) + #define __Pyx_PyType_TryGetSubSlot(type, sub, name, func_ctype) __Pyx_PyType_GetSubSlot(type, sub, name, func_ctype) +#else + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((func_ctype) PyType_GetSlot((type), Py_##name)) + #define __Pyx_PyType_TryGetSlot(type, name, func_ctype)\ + ((__PYX_LIMITED_VERSION_HEX >= 0x030A0000 ||\ + (PyType_GetFlags(type) & Py_TPFLAGS_HEAPTYPE) || __Pyx_get_runtime_version() >= 0x030A0000) ?\ + __Pyx_PyType_GetSlot(type, name, func_ctype) : NULL) + #define __Pyx_PyType_GetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_GetSlot(obj, name, func_ctype) + #define __Pyx_PyType_TryGetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_TryGetSlot(obj, name, func_ctype) +#endif +#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) +#define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStrWithError(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStr(PyObject *dict, PyObject *name) { + PyObject *res = __Pyx_PyDict_GetItemStrWithError(dict, name); + if (res == NULL) PyErr_Clear(); + return res; +} +#elif !CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000 +#define __Pyx_PyDict_GetItemStrWithError PyDict_GetItemWithError +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#else +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict, PyObject *name) { +#if CYTHON_COMPILING_IN_PYPY + return PyDict_GetItem(dict, name); +#else + PyDictEntry *ep; + PyDictObject *mp = (PyDictObject*) dict; + long hash = ((PyStringObject *) name)->ob_shash; + assert(hash != -1); + ep = (mp->ma_lookup)(mp, name, hash); + if (ep == NULL) { + return NULL; + } + return ep->me_value; +#endif +} +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#endif +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags) + #define __Pyx_PyType_HasFeature(type, feature) ((__Pyx_PyType_GetFlags(type) & (feature)) != 0) +#else + #define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp)) + #define __Pyx_PyType_HasFeature(type, feature) PyType_HasFeature(type, feature) +#endif +#define __Pyx_PyObject_GetIterNextFunc(iterator) __Pyx_PyObject_GetSlot(iterator, tp_iternext, iternextfunc) +#if CYTHON_USE_TYPE_SPECS +#define __Pyx_PyHeapTypeObject_GC_Del(obj) {\ + PyTypeObject *type = Py_TYPE((PyObject*)obj);\ + assert(__Pyx_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE));\ + PyObject_GC_Del(obj);\ + Py_DECREF(type);\ +} +#else +#define __Pyx_PyHeapTypeObject_GC_Del(obj) PyObject_GC_Del(obj) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_ReadChar(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((void)u, 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((void)u, (0)) + #define __Pyx_PyUnicode_DATA(u) ((void*)u) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)k, PyUnicode_ReadChar((PyObject*)(d), i)) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GetLength(u)) +#else + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_READY(op) (0) + #else + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #endif + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) ((int)PyUnicode_KIND(u)) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, (Py_UCS4) ch) + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #else + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length)) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #endif + #endif +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #if !defined(PyUnicode_DecodeUnicodeEscape) + #define PyUnicode_DecodeUnicodeEscape(s, size, errors) PyUnicode_Decode(s, size, "unicode_escape", errors) + #endif + #if !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) + #endif + #if !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) + #endif + #if !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) + #endif +#endif +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && PyUnstable_Object_IsUniquelyReferenced(obj)) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#elif CYTHON_COMPILING_IN_CPYTHON + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#else + #define __Pyx_PySequence_ListKeepNew(obj) PySequence_List(obj) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) __Pyx_IS_TYPE(obj, &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +enum __Pyx_ReferenceSharing { + __Pyx_ReferenceSharing_DefinitelyUnique, // We created it so we know it's unshared - no need to check + __Pyx_ReferenceSharing_OwnStrongReference, + __Pyx_ReferenceSharing_FunctionArgument, + __Pyx_ReferenceSharing_SharedReference, // Never trust it to be unshared because it's a global or similar +}; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && PY_VERSION_HEX >= 0x030E0000 +#define __Pyx_IS_UNIQUELY_REFERENCED(o, sharing)\ + (sharing == __Pyx_ReferenceSharing_DefinitelyUnique ? 1 :\ + (sharing == __Pyx_ReferenceSharing_FunctionArgument ? PyUnstable_Object_IsUniqueReferencedTemporary(o) :\ + (sharing == __Pyx_ReferenceSharing_OwnStrongReference ? PyUnstable_Object_IsUniquelyReferenced(o) : 0))) +#elif (CYTHON_COMPILING_IN_CPYTHON && !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING) || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_IS_UNIQUELY_REFERENCED(o, sharing) (((void)sharing), Py_REFCNT(o) == 1) +#else +#define __Pyx_IS_UNIQUELY_REFERENCED(o, sharing) (((void)o), ((void)sharing), 0) +#endif +#if CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + #define __Pyx_PyList_GetItemRef(o, i) PyList_GetItemRef(o, i) + #elif CYTHON_COMPILING_IN_LIMITED_API || !CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PyList_GetItemRef(o, i) (likely((i) >= 0) ? PySequence_GetItem(o, i) : (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) + #else + #define __Pyx_PyList_GetItemRef(o, i) PySequence_ITEM(o, i) + #endif +#elif CYTHON_COMPILING_IN_LIMITED_API || !CYTHON_ASSUME_SAFE_MACROS + #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + #define __Pyx_PyList_GetItemRef(o, i) PyList_GetItemRef(o, i) + #else + #define __Pyx_PyList_GetItemRef(o, i) __Pyx_XNewRef(PyList_GetItem(o, i)) + #endif +#else + #define __Pyx_PyList_GetItemRef(o, i) __Pyx_NewRef(PyList_GET_ITEM(o, i)) +#endif +#if CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS && !CYTHON_COMPILING_IN_LIMITED_API && CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PyList_GetItemRefFast(o, i, unsafe_shared) (__Pyx_IS_UNIQUELY_REFERENCED(o, unsafe_shared) ?\ + __Pyx_NewRef(PyList_GET_ITEM(o, i)) : __Pyx_PyList_GetItemRef(o, i)) +#else + #define __Pyx_PyList_GetItemRefFast(o, i, unsafe_shared) __Pyx_PyList_GetItemRef(o, i) +#endif +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 +#define __Pyx_PyDict_GetItemRef(dict, key, result) PyDict_GetItemRef(dict, key, result) +#elif CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS +static CYTHON_INLINE int __Pyx_PyDict_GetItemRef(PyObject *dict, PyObject *key, PyObject **result) { + *result = PyObject_GetItem(dict, key); + if (*result == NULL) { + if (PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_Clear(); + return 0; + } + return -1; + } + return 1; +} +#else +static CYTHON_INLINE int __Pyx_PyDict_GetItemRef(PyObject *dict, PyObject *key, PyObject **result) { + *result = PyDict_GetItemWithError(dict, key); + if (*result == NULL) { + return PyErr_Occurred() ? -1 : 0; + } + Py_INCREF(*result); + return 1; +} +#endif +#if defined(CYTHON_DEBUG_VISIT_CONST) && CYTHON_DEBUG_VISIT_CONST + #define __Pyx_VISIT_CONST(obj) Py_VISIT(obj) +#else + #define __Pyx_VISIT_CONST(obj) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_ITEM(o, i) PySequence_ITEM(o, i) + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) (PyTuple_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyTuple_GET_ITEM(o, i) PyTuple_GET_ITEM(o, i) + #define __Pyx_PyList_SET_ITEM(o, i, v) (PyList_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyList_GET_ITEM(o, i) PyList_GET_ITEM(o, i) +#else + #define __Pyx_PySequence_ITEM(o, i) PySequence_GetItem(o, i) + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) PyTuple_SetItem(o, i, v) + #define __Pyx_PyTuple_GET_ITEM(o, i) PyTuple_GetItem(o, i) + #define __Pyx_PyList_SET_ITEM(o, i, v) PyList_SetItem(o, i, v) + #define __Pyx_PyList_GET_ITEM(o, i) PyList_GetItem(o, i) +#endif +#if CYTHON_ASSUME_SAFE_SIZE + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_GET_SIZE(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_GET_SIZE(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_GET_SIZE(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_GET_SIZE(o) + #define __Pyx_PyUnicode_GET_LENGTH(o) PyUnicode_GET_LENGTH(o) +#else + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_Size(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_Size(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_Size(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_Size(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_Size(o) + #define __Pyx_PyUnicode_GET_LENGTH(o) PyUnicode_GetLength(o) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_InternFromString) + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) +#endif +#define __Pyx_PyLong_FromHash_t PyLong_FromSsize_t +#define __Pyx_PyLong_AsHash_t __Pyx_PyIndex_AsSsize_t +#if __PYX_LIMITED_VERSION_HEX >= 0x030A0000 + #define __Pyx_PySendResult PySendResult +#else + typedef enum { + PYGEN_RETURN = 0, + PYGEN_ERROR = -1, + PYGEN_NEXT = 1, + } __Pyx_PySendResult; +#endif +#if CYTHON_COMPILING_IN_LIMITED_API || PY_VERSION_HEX < 0x030A00A3 + typedef __Pyx_PySendResult (*__Pyx_pyiter_sendfunc)(PyObject *iter, PyObject *value, PyObject **result); +#else + #define __Pyx_pyiter_sendfunc sendfunc +#endif +#if !CYTHON_USE_AM_SEND +#define __PYX_HAS_PY_AM_SEND 0 +#elif __PYX_LIMITED_VERSION_HEX >= 0x030A0000 +#define __PYX_HAS_PY_AM_SEND 1 +#else +#define __PYX_HAS_PY_AM_SEND 2 // our own backported implementation +#endif +#if __PYX_HAS_PY_AM_SEND < 2 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods +#else + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + __Pyx_pyiter_sendfunc am_send; + } __Pyx_PyAsyncMethodsStruct; + #define __Pyx_SlotTpAsAsync(s) ((PyAsyncMethods*)(s)) +#endif +#if CYTHON_USE_AM_SEND && PY_VERSION_HEX < 0x030A00F0 + #define __Pyx_TPFLAGS_HAVE_AM_SEND (1UL << 21) +#else + #define __Pyx_TPFLAGS_HAVE_AM_SEND (0) +#endif +#if PY_VERSION_HEX >= 0x03090000 +#define __Pyx_PyInterpreterState_Get() PyInterpreterState_Get() +#else +#define __Pyx_PyInterpreterState_Get() PyThreadState_Get()->interp +#endif +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030A0000 +#ifdef __cplusplus +extern "C" +#endif +PyAPI_FUNC(void *) PyMem_Calloc(size_t nelem, size_t elsize); +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static int __Pyx_init_co_variable(PyObject *inspect, const char* name, int *write_to) { + int value; + PyObject *py_value = PyObject_GetAttrString(inspect, name); + if (!py_value) return 0; + value = (int) PyLong_AsLong(py_value); + Py_DECREF(py_value); + *write_to = value; + return value != -1 || !PyErr_Occurred(); +} +static int __Pyx_init_co_variables(void) { + PyObject *inspect; + int result; + inspect = PyImport_ImportModule("inspect"); + result = +#if !defined(CO_OPTIMIZED) + __Pyx_init_co_variable(inspect, "CO_OPTIMIZED", &CO_OPTIMIZED) && +#endif +#if !defined(CO_NEWLOCALS) + __Pyx_init_co_variable(inspect, "CO_NEWLOCALS", &CO_NEWLOCALS) && +#endif +#if !defined(CO_VARARGS) + __Pyx_init_co_variable(inspect, "CO_VARARGS", &CO_VARARGS) && +#endif +#if !defined(CO_VARKEYWORDS) + __Pyx_init_co_variable(inspect, "CO_VARKEYWORDS", &CO_VARKEYWORDS) && +#endif +#if !defined(CO_ASYNC_GENERATOR) + __Pyx_init_co_variable(inspect, "CO_ASYNC_GENERATOR", &CO_ASYNC_GENERATOR) && +#endif +#if !defined(CO_GENERATOR) + __Pyx_init_co_variable(inspect, "CO_GENERATOR", &CO_GENERATOR) && +#endif +#if !defined(CO_COROUTINE) + __Pyx_init_co_variable(inspect, "CO_COROUTINE", &CO_COROUTINE) && +#endif + 1; + Py_DECREF(inspect); + return result ? 0 : -1; +} +#else +static int __Pyx_init_co_variables(void) { + return 0; // It's a limited API-only feature +} +#endif + +/* MathInitCode */ +#if defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS) + #ifndef _USE_MATH_DEFINES + #define _USE_MATH_DEFINES + #endif +#endif +#include +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#ifndef CYTHON_CLINE_IN_TRACEBACK_RUNTIME +#define CYTHON_CLINE_IN_TRACEBACK_RUNTIME 0 +#endif +#ifndef CYTHON_CLINE_IN_TRACEBACK +#define CYTHON_CLINE_IN_TRACEBACK CYTHON_CLINE_IN_TRACEBACK_RUNTIME +#endif +#if CYTHON_CLINE_IN_TRACEBACK +#define __PYX_MARK_ERR_POS(f_index, lineno) { __pyx_filename = __pyx_f[f_index]; (void) __pyx_filename; __pyx_lineno = lineno; (void) __pyx_lineno; __pyx_clineno = __LINE__; (void) __pyx_clineno; } +#else +#define __PYX_MARK_ERR_POS(f_index, lineno) { __pyx_filename = __pyx_f[f_index]; (void) __pyx_filename; __pyx_lineno = lineno; (void) __pyx_lineno; (void) __pyx_clineno; } +#endif +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifdef CYTHON_EXTERN_C + #undef __PYX_EXTERN_C + #define __PYX_EXTERN_C CYTHON_EXTERN_C +#elif defined(__PYX_EXTERN_C) + #ifdef _MSC_VER + #pragma message ("Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead.") + #else + #warning Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead. + #endif +#else + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__fontTools__pens__momentsPen +#define __PYX_HAVE_API__fontTools__pens__momentsPen +/* Early includes */ +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s); +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char*); +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyByteArray_AsString(s) PyByteArray_AS_STRING(s) +#else + #define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AsString(s)) + #define __Pyx_PyByteArray_AsString(s) PyByteArray_AsString(s) +#endif +#define __Pyx_PyObject_AsWritableString(s) ((char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +#define __Pyx_PyUnicode_FromOrdinal(o) PyUnicode_FromOrdinal((int)o) +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +static CYTHON_INLINE PyObject *__Pyx_NewRef(PyObject *obj) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030a0000 || defined(Py_NewRef) + return Py_NewRef(obj); +#else + Py_INCREF(obj); + return obj; +#endif +} +static CYTHON_INLINE PyObject *__Pyx_XNewRef(PyObject *obj) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030a0000 || defined(Py_XNewRef) + return Py_XNewRef(obj); +#else + Py_XINCREF(obj); + return obj; +#endif +} +static CYTHON_INLINE PyObject *__Pyx_Owned_Py_None(int b); +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_Long(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyLong_FromSize_t(size_t); +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*); +#if CYTHON_ASSUME_SAFE_MACROS +#define __Pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#define __Pyx_PyFloat_AS_DOUBLE(x) PyFloat_AS_DOUBLE(x) +#else +#define __Pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#define __Pyx_PyFloat_AS_DOUBLE(x) PyFloat_AsDouble(x) +#endif +#define __Pyx_PyFloat_AsFloat(x) ((float) __Pyx_PyFloat_AsDouble(x)) +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_VERSION_HEX >= 0x030C00A7 + #ifndef _PyLong_SIGN_MASK + #define _PyLong_SIGN_MASK 3 + #endif + #ifndef _PyLong_NON_SIZE_BITS + #define _PyLong_NON_SIZE_BITS 3 + #endif + #define __Pyx_PyLong_Sign(x) (((PyLongObject*)x)->long_value.lv_tag & _PyLong_SIGN_MASK) + #define __Pyx_PyLong_IsNeg(x) ((__Pyx_PyLong_Sign(x) & 2) != 0) + #define __Pyx_PyLong_IsNonNeg(x) (!__Pyx_PyLong_IsNeg(x)) + #define __Pyx_PyLong_IsZero(x) (__Pyx_PyLong_Sign(x) & 1) + #define __Pyx_PyLong_IsPos(x) (__Pyx_PyLong_Sign(x) == 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) (__Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) ((Py_ssize_t) (((PyLongObject*)x)->long_value.lv_tag >> _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_SignedDigitCount(x)\ + ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * __Pyx_PyLong_DigitCount(x)) + #if defined(PyUnstable_Long_IsCompact) && defined(PyUnstable_Long_CompactValue) + #define __Pyx_PyLong_IsCompact(x) PyUnstable_Long_IsCompact((PyLongObject*) x) + #define __Pyx_PyLong_CompactValue(x) PyUnstable_Long_CompactValue((PyLongObject*) x) + #else + #define __Pyx_PyLong_IsCompact(x) (((PyLongObject*)x)->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_CompactValue(x) ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * (Py_ssize_t) __Pyx_PyLong_Digits(x)[0]) + #endif + typedef Py_ssize_t __Pyx_compact_pylong; + typedef size_t __Pyx_compact_upylong; + #else + #define __Pyx_PyLong_IsNeg(x) (Py_SIZE(x) < 0) + #define __Pyx_PyLong_IsNonNeg(x) (Py_SIZE(x) >= 0) + #define __Pyx_PyLong_IsZero(x) (Py_SIZE(x) == 0) + #define __Pyx_PyLong_IsPos(x) (Py_SIZE(x) > 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) ((Py_SIZE(x) == 0) ? 0 : __Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) __Pyx_sst_abs(Py_SIZE(x)) + #define __Pyx_PyLong_SignedDigitCount(x) Py_SIZE(x) + #define __Pyx_PyLong_IsCompact(x) (Py_SIZE(x) == 0 || Py_SIZE(x) == 1 || Py_SIZE(x) == -1) + #define __Pyx_PyLong_CompactValue(x)\ + ((Py_SIZE(x) == 0) ? (sdigit) 0 : ((Py_SIZE(x) < 0) ? -(sdigit)__Pyx_PyLong_Digits(x)[0] : (sdigit)__Pyx_PyLong_Digits(x)[0])) + typedef sdigit __Pyx_compact_pylong; + typedef digit __Pyx_compact_upylong; + #endif + #if PY_VERSION_HEX >= 0x030C00A5 + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->long_value.ob_digit) + #else + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->ob_digit) + #endif +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 + #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#elif __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeASCII(c_str, size, NULL) +#else + #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +/* PretendToInitialize */ +#ifdef __cplusplus +#if __cplusplus > 201103L +#include +#endif +template +static void __Pyx_pretend_to_initialize(T* ptr) { +#if __cplusplus > 201103L + if ((std::is_trivially_default_constructible::value)) +#endif + *ptr = T(); + (void)ptr; +} +#else +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } +#endif + + +#if !CYTHON_USE_MODULE_STATE +static PyObject *__pyx_m = NULL; +#endif +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * const __pyx_cfilenm = __FILE__; +static const char *__pyx_filename; + +/* #### Code section: filename_table ### */ + +static const char* const __pyx_f[] = { + "Lib/fontTools/pens/momentsPen.py", +}; +/* #### Code section: utility_code_proto_before_types ### */ +/* Atomics.proto (used by UnpackUnboundCMethod) */ +#include +#ifndef CYTHON_ATOMICS + #define CYTHON_ATOMICS 1 +#endif +#define __PYX_CYTHON_ATOMICS_ENABLED() CYTHON_ATOMICS +#define __PYX_GET_CYTHON_COMPILING_IN_CPYTHON_FREETHREADING() CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __pyx_atomic_int_type int +#define __pyx_nonatomic_int_type int +#if CYTHON_ATOMICS && (defined(__STDC_VERSION__) &&\ + (__STDC_VERSION__ >= 201112L) &&\ + !defined(__STDC_NO_ATOMICS__)) + #include +#elif CYTHON_ATOMICS && (defined(__cplusplus) && (\ + (__cplusplus >= 201103L) ||\ + (defined(_MSC_VER) && _MSC_VER >= 1700))) + #include +#endif +#if CYTHON_ATOMICS && (defined(__STDC_VERSION__) &&\ + (__STDC_VERSION__ >= 201112L) &&\ + !defined(__STDC_NO_ATOMICS__) &&\ + ATOMIC_INT_LOCK_FREE == 2) + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type atomic_int + #define __pyx_atomic_ptr_type atomic_uintptr_t + #define __pyx_nonatomic_ptr_type uintptr_t + #define __pyx_atomic_incr_relaxed(value) atomic_fetch_add_explicit(value, 1, memory_order_relaxed) + #define __pyx_atomic_incr_acq_rel(value) atomic_fetch_add_explicit(value, 1, memory_order_acq_rel) + #define __pyx_atomic_decr_acq_rel(value) atomic_fetch_sub_explicit(value, 1, memory_order_acq_rel) + #define __pyx_atomic_sub(value, arg) atomic_fetch_sub(value, arg) + #define __pyx_atomic_int_cmp_exchange(value, expected, desired) atomic_compare_exchange_strong(value, expected, desired) + #define __pyx_atomic_load(value) atomic_load(value) + #define __pyx_atomic_store(value, new_value) atomic_store(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) atomic_load_explicit(value, memory_order_relaxed) + #define __pyx_atomic_pointer_load_acquire(value) atomic_load_explicit(value, memory_order_acquire) + #define __pyx_atomic_pointer_exchange(value, new_value) atomic_exchange(value, (__pyx_nonatomic_ptr_type)new_value) + #define __pyx_atomic_pointer_cmp_exchange(value, expected, desired) atomic_compare_exchange_strong(value, expected, desired) + #if defined(__PYX_DEBUG_ATOMICS) && defined(_MSC_VER) + #pragma message ("Using standard C atomics") + #elif defined(__PYX_DEBUG_ATOMICS) + #warning "Using standard C atomics" + #endif +#elif CYTHON_ATOMICS && (defined(__cplusplus) && (\ + (__cplusplus >= 201103L) ||\ +\ + (defined(_MSC_VER) && _MSC_VER >= 1700)) &&\ + ATOMIC_INT_LOCK_FREE == 2) + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type std::atomic_int + #define __pyx_atomic_ptr_type std::atomic_uintptr_t + #define __pyx_nonatomic_ptr_type uintptr_t + #define __pyx_atomic_incr_relaxed(value) std::atomic_fetch_add_explicit(value, 1, std::memory_order_relaxed) + #define __pyx_atomic_incr_acq_rel(value) std::atomic_fetch_add_explicit(value, 1, std::memory_order_acq_rel) + #define __pyx_atomic_decr_acq_rel(value) std::atomic_fetch_sub_explicit(value, 1, std::memory_order_acq_rel) + #define __pyx_atomic_sub(value, arg) std::atomic_fetch_sub(value, arg) + #define __pyx_atomic_int_cmp_exchange(value, expected, desired) std::atomic_compare_exchange_strong(value, expected, desired) + #define __pyx_atomic_load(value) std::atomic_load(value) + #define __pyx_atomic_store(value, new_value) std::atomic_store(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) std::atomic_load_explicit(value, std::memory_order_relaxed) + #define __pyx_atomic_pointer_load_acquire(value) std::atomic_load_explicit(value, std::memory_order_acquire) + #define __pyx_atomic_pointer_exchange(value, new_value) std::atomic_exchange(value, (__pyx_nonatomic_ptr_type)new_value) + #define __pyx_atomic_pointer_cmp_exchange(value, expected, desired) std::atomic_compare_exchange_strong(value, expected, desired) + #if defined(__PYX_DEBUG_ATOMICS) && defined(_MSC_VER) + #pragma message ("Using standard C++ atomics") + #elif defined(__PYX_DEBUG_ATOMICS) + #warning "Using standard C++ atomics" + #endif +#elif CYTHON_ATOMICS && (__GNUC__ >= 5 || (__GNUC__ == 4 &&\ + (__GNUC_MINOR__ > 1 ||\ + (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ >= 2)))) + #define __pyx_atomic_ptr_type void* + #define __pyx_nonatomic_ptr_type void* + #define __pyx_atomic_incr_relaxed(value) __sync_fetch_and_add(value, 1) + #define __pyx_atomic_incr_acq_rel(value) __sync_fetch_and_add(value, 1) + #define __pyx_atomic_decr_acq_rel(value) __sync_fetch_and_sub(value, 1) + #define __pyx_atomic_sub(value, arg) __sync_fetch_and_sub(value, arg) + static CYTHON_INLINE int __pyx_atomic_int_cmp_exchange(__pyx_atomic_int_type* value, __pyx_nonatomic_int_type* expected, __pyx_nonatomic_int_type desired) { + __pyx_nonatomic_int_type old = __sync_val_compare_and_swap(value, *expected, desired); + int result = old == *expected; + *expected = old; + return result; + } + #define __pyx_atomic_load(value) __sync_fetch_and_add(value, 0) + #define __pyx_atomic_store(value, new_value) __sync_lock_test_and_set(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) __sync_fetch_and_add(value, 0) + #define __pyx_atomic_pointer_load_acquire(value) __sync_fetch_and_add(value, 0) + #define __pyx_atomic_pointer_exchange(value, new_value) __sync_lock_test_and_set(value, (__pyx_atomic_ptr_type)new_value) + static CYTHON_INLINE int __pyx_atomic_pointer_cmp_exchange(__pyx_atomic_ptr_type* value, __pyx_nonatomic_ptr_type* expected, __pyx_nonatomic_ptr_type desired) { + __pyx_nonatomic_ptr_type old = __sync_val_compare_and_swap(value, *expected, desired); + int result = old == *expected; + *expected = old; + return result; + } + #ifdef __PYX_DEBUG_ATOMICS + #warning "Using GNU atomics" + #endif +#elif CYTHON_ATOMICS && defined(_MSC_VER) + #include + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type long + #define __pyx_atomic_ptr_type void* + #undef __pyx_nonatomic_int_type + #define __pyx_nonatomic_int_type long + #define __pyx_nonatomic_ptr_type void* + #pragma intrinsic (_InterlockedExchangeAdd, _InterlockedExchange, _InterlockedCompareExchange, _InterlockedCompareExchangePointer, _InterlockedExchangePointer) + #define __pyx_atomic_incr_relaxed(value) _InterlockedExchangeAdd(value, 1) + #define __pyx_atomic_incr_acq_rel(value) _InterlockedExchangeAdd(value, 1) + #define __pyx_atomic_decr_acq_rel(value) _InterlockedExchangeAdd(value, -1) + #define __pyx_atomic_sub(value, arg) _InterlockedExchangeAdd(value, -arg) + static CYTHON_INLINE int __pyx_atomic_int_cmp_exchange(__pyx_atomic_int_type* value, __pyx_nonatomic_int_type* expected, __pyx_nonatomic_int_type desired) { + __pyx_nonatomic_int_type old = _InterlockedCompareExchange(value, desired, *expected); + int result = old == *expected; + *expected = old; + return result; + } + #define __pyx_atomic_load(value) _InterlockedExchangeAdd(value, 0) + #define __pyx_atomic_store(value, new_value) _InterlockedExchange(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) *(void * volatile *)value + #define __pyx_atomic_pointer_load_acquire(value) _InterlockedCompareExchangePointer(value, 0, 0) + #define __pyx_atomic_pointer_exchange(value, new_value) _InterlockedExchangePointer(value, (__pyx_atomic_ptr_type)new_value) + static CYTHON_INLINE int __pyx_atomic_pointer_cmp_exchange(__pyx_atomic_ptr_type* value, __pyx_nonatomic_ptr_type* expected, __pyx_nonatomic_ptr_type desired) { + __pyx_atomic_ptr_type old = _InterlockedCompareExchangePointer(value, desired, *expected); + int result = old == *expected; + *expected = old; + return result; + } + #ifdef __PYX_DEBUG_ATOMICS + #pragma message ("Using MSVC atomics") + #endif +#else + #undef CYTHON_ATOMICS + #define CYTHON_ATOMICS 0 + #ifdef __PYX_DEBUG_ATOMICS + #warning "Not using atomics" + #endif +#endif + +/* CriticalSectionsDefinition.proto (used by CriticalSections) */ +#if !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __Pyx_PyCriticalSection void* +#define __Pyx_PyCriticalSection2 void* +#define __Pyx_PyCriticalSection_End(cs) +#define __Pyx_PyCriticalSection2_End(cs) +#else +#define __Pyx_PyCriticalSection PyCriticalSection +#define __Pyx_PyCriticalSection2 PyCriticalSection2 +#define __Pyx_PyCriticalSection_End PyCriticalSection_End +#define __Pyx_PyCriticalSection2_End PyCriticalSection2_End +#endif + +/* CriticalSections.proto (used by ParseKeywordsImpl) */ +#if !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __Pyx_PyCriticalSection_Begin(cs, arg) (void)(cs) +#define __Pyx_PyCriticalSection2_Begin(cs, arg1, arg2) (void)(cs) +#else +#define __Pyx_PyCriticalSection_Begin PyCriticalSection_Begin +#define __Pyx_PyCriticalSection2_Begin PyCriticalSection2_Begin +#endif +#if PY_VERSION_HEX < 0x030d0000 || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_BEGIN_CRITICAL_SECTION(o) { +#define __Pyx_END_CRITICAL_SECTION() } +#else +#define __Pyx_BEGIN_CRITICAL_SECTION Py_BEGIN_CRITICAL_SECTION +#define __Pyx_END_CRITICAL_SECTION Py_END_CRITICAL_SECTION +#endif + +/* IncludeStructmemberH.proto (used by FixUpExtensionType) */ +#include + +/* #### Code section: numeric_typedefs ### */ +/* #### Code section: complex_type_declarations ### */ +/* #### Code section: type_declarations ### */ + +/*--- Type declarations ---*/ +/* #### Code section: utility_code_proto ### */ + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, Py_ssize_t); + void (*DECREF)(void*, PyObject*, Py_ssize_t); + void (*GOTREF)(void*, PyObject*, Py_ssize_t); + void (*GIVEREF)(void*, PyObject*, Py_ssize_t); + void* (*SetupContext)(const char*, Py_ssize_t, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_XINCREF(r) do { if((r) == NULL); else {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) == NULL); else {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) == NULL); else {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) == NULL); else {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContextNogil() + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_Py_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; Py_XDECREF(tmp);\ + } while (0) +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* TupleAndListFromArray.proto (used by fastcall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n); +#endif +#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n); +#endif + +/* IncludeStringH.proto (used by BytesEquals) */ +#include + +/* BytesEquals.proto (used by UnicodeEquals) */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); + +/* UnicodeEquals.proto (used by fastcall) */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); + +/* fastcall.proto */ +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_ArgRef_VARARGS(args, i) __Pyx_PySequence_ITEM(args, i) +#elif CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_ArgRef_VARARGS(args, i) __Pyx_NewRef(__Pyx_PyTuple_GET_ITEM(args, i)) +#else + #define __Pyx_ArgRef_VARARGS(args, i) __Pyx_XNewRef(PyTuple_GetItem(args, i)) +#endif +#define __Pyx_NumKwargs_VARARGS(kwds) PyDict_Size(kwds) +#define __Pyx_KwValues_VARARGS(args, nargs) NULL +#define __Pyx_GetKwValue_VARARGS(kw, kwvalues, s) __Pyx_PyDict_GetItemStrWithError(kw, s) +#define __Pyx_KwargsAsDict_VARARGS(kw, kwvalues) PyDict_Copy(kw) +#if CYTHON_METH_FASTCALL + #define __Pyx_ArgRef_FASTCALL(args, i) __Pyx_NewRef(args[i]) + #define __Pyx_NumKwargs_FASTCALL(kwds) __Pyx_PyTuple_GET_SIZE(kwds) + #define __Pyx_KwValues_FASTCALL(args, nargs) ((args) + (nargs)) + static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 || CYTHON_COMPILING_IN_LIMITED_API + CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues); + #else + #define __Pyx_KwargsAsDict_FASTCALL(kw, kwvalues) _PyStack_AsDict(kwvalues, kw) + #endif +#else + #define __Pyx_ArgRef_FASTCALL __Pyx_ArgRef_VARARGS + #define __Pyx_NumKwargs_FASTCALL __Pyx_NumKwargs_VARARGS + #define __Pyx_KwValues_FASTCALL __Pyx_KwValues_VARARGS + #define __Pyx_GetKwValue_FASTCALL __Pyx_GetKwValue_VARARGS + #define __Pyx_KwargsAsDict_FASTCALL __Pyx_KwargsAsDict_VARARGS +#endif +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) PyTuple_GetSlice(args, start, stop) +#if CYTHON_METH_FASTCALL || (CYTHON_COMPILING_IN_CPYTHON && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) __Pyx_PyTuple_FromArray(args + start, stop - start) +#else +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) PyTuple_GetSlice(args, start, stop) +#endif + +/* py_dict_items.proto (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d); + +/* CallCFunction.proto (used by CallUnboundCMethod0) */ +#define __Pyx_CallCFunction(cfunc, self, args)\ + ((PyCFunction)(void(*)(void))(cfunc)->func)(self, args) +#define __Pyx_CallCFunctionWithKeywords(cfunc, self, args, kwargs)\ + ((PyCFunctionWithKeywords)(void(*)(void))(cfunc)->func)(self, args, kwargs) +#define __Pyx_CallCFunctionFast(cfunc, self, args, nargs)\ + ((__Pyx_PyCFunctionFast)(void(*)(void))(PyCFunction)(cfunc)->func)(self, args, nargs) +#define __Pyx_CallCFunctionFastWithKeywords(cfunc, self, args, nargs, kwnames)\ + ((__Pyx_PyCFunctionFastWithKeywords)(void(*)(void))(PyCFunction)(cfunc)->func)(self, args, nargs, kwnames) + +/* PyObjectCall.proto (used by PyObjectFastCall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* PyObjectCallMethO.proto (used by PyObjectFastCall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectFastCall.proto (used by PyObjectCallOneArg) */ +#define __Pyx_PyObject_FastCall(func, args, nargs) __Pyx_PyObject_FastCallDict(func, args, (size_t)(nargs), NULL) +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject * const*args, size_t nargs, PyObject *kwargs); + +/* PyObjectCallOneArg.proto (used by CallUnboundCMethod0) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* PyObjectGetAttrStr.proto (used by UnpackUnboundCMethod) */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* UnpackUnboundCMethod.proto (used by CallUnboundCMethod0) */ +typedef struct { + PyObject *type; + PyObject **method_name; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && CYTHON_ATOMICS + __pyx_atomic_int_type initialized; +#endif + PyCFunction func; + PyObject *method; + int flag; +} __Pyx_CachedCFunction; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +static CYTHON_INLINE int __Pyx_CachedCFunction_GetAndSetInitializing(__Pyx_CachedCFunction *cfunc) { +#if !CYTHON_ATOMICS + return 1; +#else + __pyx_nonatomic_int_type expected = 0; + if (__pyx_atomic_int_cmp_exchange(&cfunc->initialized, &expected, 1)) { + return 0; + } + return expected; +#endif +} +static CYTHON_INLINE void __Pyx_CachedCFunction_SetFinishedInitializing(__Pyx_CachedCFunction *cfunc) { +#if CYTHON_ATOMICS + __pyx_atomic_store(&cfunc->initialized, 2); +#endif +} +#else +#define __Pyx_CachedCFunction_GetAndSetInitializing(cfunc) 2 +#define __Pyx_CachedCFunction_SetFinishedInitializing(cfunc) +#endif + +/* CallUnboundCMethod0.proto */ +CYTHON_UNUSED +static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self); +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self); +#else +#define __Pyx_CallUnboundCMethod0(cfunc, self) __Pyx__CallUnboundCMethod0(cfunc, self) +#endif + +/* py_dict_values.proto (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Values(PyObject* d); + +/* OwnedDictNext.proto (used by ParseKeywordsImpl) */ +#if CYTHON_AVOID_BORROWED_REFS +static int __Pyx_PyDict_NextRef(PyObject *p, PyObject **ppos, PyObject **pkey, PyObject **pvalue); +#else +CYTHON_INLINE +static int __Pyx_PyDict_NextRef(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue); +#endif + +/* RaiseDoubleKeywords.proto (used by ParseKeywordsImpl) */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywordsImpl.export */ +static int __Pyx_ParseKeywordsTuple( + PyObject *kwds, + PyObject * const *kwvalues, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs +); +static int __Pyx_ParseKeywordDictToDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name +); +static int __Pyx_ParseKeywordDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs +); + +/* CallUnboundCMethod2.proto */ +CYTHON_UNUSED +static PyObject* __Pyx__CallUnboundCMethod2(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg1, PyObject* arg2); +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject *__Pyx_CallUnboundCMethod2(__Pyx_CachedCFunction *cfunc, PyObject *self, PyObject *arg1, PyObject *arg2); +#else +#define __Pyx_CallUnboundCMethod2(cfunc, self, arg1, arg2) __Pyx__CallUnboundCMethod2(cfunc, self, arg1, arg2) +#endif + +/* ParseKeywords.proto */ +static CYTHON_INLINE int __Pyx_ParseKeywords( + PyObject *kwds, PyObject *const *kwvalues, PyObject ** const argnames[], + PyObject *kwds2, PyObject *values[], + Py_ssize_t num_pos_args, Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs +); + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* PyErrExceptionMatches.proto (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* PyThreadStateGet.proto (used by PyErrFetchRestore) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#if PY_VERSION_HEX >= 0x030C00A6 +#define __Pyx_PyErr_Occurred() (__pyx_tstate->current_exception != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->current_exception ? (PyObject*) Py_TYPE(__pyx_tstate->current_exception) : (PyObject*) NULL) +#else +#define __Pyx_PyErr_Occurred() (__pyx_tstate->curexc_type != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->curexc_type) +#endif +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() (PyErr_Occurred() != NULL) +#define __Pyx_PyErr_CurrentExceptionType() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A6 +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* PyObjectGetAttrStrNoError.proto (used by GetBuiltinName) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); + +/* GetBuiltinName.proto (used by GetModuleGlobalName) */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* PyDictVersioning.proto (used by GetModuleGlobalName) */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __Pyx_XNewRef(__pyx_dict_cached_value);\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* GetModuleGlobalName.proto */ +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) do {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_mstate_global->__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +#define __Pyx_GetModuleGlobalNameUncached(var, name) do {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif + +/* PyObjectDelAttr.proto (used by PyObjectSetAttrStr) */ +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030d0000 +#define __Pyx_PyObject_DelAttr(o, n) PyObject_SetAttr(o, n, NULL) +#else +#define __Pyx_PyObject_DelAttr(o, n) PyObject_DelAttr(o, n) +#endif + +/* PyObjectSetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +#define __Pyx_PyObject_DelAttrStr(o,n) __Pyx_PyObject_SetAttrStr(o, n, NULL) +static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr_name, PyObject* value); +#else +#define __Pyx_PyObject_DelAttrStr(o,n) __Pyx_PyObject_DelAttr(o,n) +#define __Pyx_PyObject_SetAttrStr(o,n,v) PyObject_SetAttr(o,n,v) +#endif + +/* PyObjectFastCallMethod.proto */ +#if CYTHON_VECTORCALL && PY_VERSION_HEX >= 0x03090000 +#define __Pyx_PyObject_FastCallMethod(name, args, nargsf) PyObject_VectorcallMethod(name, args, nargsf, NULL) +#else +static PyObject *__Pyx_PyObject_FastCallMethod(PyObject *name, PyObject *const *args, size_t nargsf); +#endif + +/* RaiseException.export */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* RaiseTooManyValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +/* RaiseNeedMoreValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +/* IterFinish.proto */ +static CYTHON_INLINE int __Pyx_IterFinish(void); + +/* UnpackItemEndCheck.proto */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); + +/* HasAttr.proto (used by ImportImpl) */ +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 +#define __Pyx_HasAttr(o, n) PyObject_HasAttrWithError(o, n) +#else +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *, PyObject *); +#endif + +/* ImportImpl.export */ +static PyObject *__Pyx__Import(PyObject *name, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject *qualname, PyObject *moddict, int level); + +/* Import.proto */ +static CYTHON_INLINE PyObject *__Pyx_Import(PyObject *name, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject *qualname, int level); + +/* ImportFrom.proto */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); + +/* ListPack.proto */ +static PyObject *__Pyx_PyList_Pack(Py_ssize_t n, ...); + +/* Py3UpdateBases.proto */ +static PyObject* __Pyx_PEP560_update_bases(PyObject *bases); + +/* CalculateMetaclass.proto */ +static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases); + +/* dict_setdefault.proto (used by FetchCommonType) */ +static CYTHON_INLINE PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value); + +/* LimitedApiGetTypeDict.proto (used by SetItemOnTypeDict) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_GetTypeDict(PyTypeObject *tp); +#endif + +/* SetItemOnTypeDict.proto (used by FixUpExtensionType) */ +static int __Pyx__SetItemOnTypeDict(PyTypeObject *tp, PyObject *k, PyObject *v); +#define __Pyx_SetItemOnTypeDict(tp, k, v) __Pyx__SetItemOnTypeDict((PyTypeObject*)tp, k, v) + +/* FixUpExtensionType.proto (used by FetchCommonType) */ +static CYTHON_INLINE int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type); + +/* AddModuleRef.proto (used by FetchSharedCythonModule) */ +#if ((CYTHON_COMPILING_IN_CPYTHON_FREETHREADING ) ||\ + __PYX_LIMITED_VERSION_HEX < 0x030d0000) + static PyObject *__Pyx_PyImport_AddModuleRef(const char *name); +#else + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#endif + +/* FetchSharedCythonModule.proto (used by FetchCommonType) */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void); + +/* FetchCommonType.proto (used by CommonTypesMetaclass) */ +static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases); + +/* CommonTypesMetaclass.proto (used by CythonFunctionShared) */ +static int __pyx_CommonTypesMetaclass_init(PyObject *module); +#define __Pyx_CommonTypesMetaclass_USED + +/* CallTypeTraverse.proto (used by CythonFunctionShared) */ +#if !CYTHON_USE_TYPE_SPECS || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x03090000) +#define __Pyx_call_type_traverse(o, always_call, visit, arg) 0 +#else +static int __Pyx_call_type_traverse(PyObject *o, int always_call, visitproc visit, void *arg); +#endif + +/* PyMethodNew.proto (used by CythonFunctionShared) */ +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ); + +/* PyVectorcallFastCallDict.proto (used by CythonFunctionShared) */ +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw); +#endif + +/* CythonFunctionShared.proto (used by CythonFunction) */ +#define __Pyx_CyFunction_USED +#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 +#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 +#define __Pyx_CYFUNCTION_CCLASS 0x04 +#define __Pyx_CYFUNCTION_COROUTINE 0x08 +#define __Pyx_CyFunction_GetClosure(f)\ + (((__pyx_CyFunctionObject *) (f))->func_closure) +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_CyFunction_GetClassObj(f)\ + (((__pyx_CyFunctionObject *) (f))->func_classobj) +#else + #define __Pyx_CyFunction_GetClassObj(f)\ + ((PyObject*) ((PyCMethodObject *) (f))->mm_class) +#endif +#define __Pyx_CyFunction_SetClassObj(f, classobj)\ + __Pyx__CyFunction_SetClassObj((__pyx_CyFunctionObject *) (f), (classobj)) +#define __Pyx_CyFunction_Defaults(type, f)\ + ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) +#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ + ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) +typedef struct { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject_HEAD + PyObject *func; +#elif PY_VERSION_HEX < 0x030900B1 + PyCFunctionObject func; +#else + PyCMethodObject func; +#endif +#if CYTHON_COMPILING_IN_LIMITED_API && CYTHON_METH_FASTCALL + __pyx_vectorcallfunc func_vectorcall; +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_weakreflist; +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_dict; +#endif + PyObject *func_name; + PyObject *func_qualname; + PyObject *func_doc; + PyObject *func_globals; + PyObject *func_code; + PyObject *func_closure; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_classobj; +#endif + PyObject *defaults; + int flags; + PyObject *defaults_tuple; + PyObject *defaults_kwdict; + PyObject *(*defaults_getter)(PyObject *); + PyObject *func_annotations; + PyObject *func_is_coroutine; +} __pyx_CyFunctionObject; +#undef __Pyx_CyOrPyCFunction_Check +#define __Pyx_CyFunction_Check(obj) __Pyx_TypeCheck(obj, __pyx_mstate_global->__pyx_CyFunctionType) +#define __Pyx_CyOrPyCFunction_Check(obj) __Pyx_TypeCheck2(obj, __pyx_mstate_global->__pyx_CyFunctionType, &PyCFunction_Type) +#define __Pyx_CyFunction_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_mstate_global->__pyx_CyFunctionType) +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void (*cfunc)(void)); +#undef __Pyx_IsSameCFunction +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCyOrCFunction(func, cfunc) +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj); +static CYTHON_INLINE PyObject *__Pyx_CyFunction_InitDefaults(PyObject *func, + PyTypeObject *defaults_type); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, + PyObject *tuple); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, + PyObject *dict); +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, + PyObject *dict); +static int __pyx_CyFunction_init(PyObject *module); +#if CYTHON_METH_FASTCALL +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +#if CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall) +#else +#define __Pyx_CyFunction_func_vectorcall(f) (((PyCFunctionObject*)f)->vectorcall) +#endif +#endif + +/* CythonFunction.proto */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); + +/* SetNameInClass.proto */ +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 +#define __Pyx_SetNameInClass(ns, name, value)\ + (likely(PyDict_CheckExact(ns)) ? _PyDict_SetItem_KnownHash(ns, name, value, ((PyASCIIObject *) name)->hash) : PyObject_SetItem(ns, name, value)) +#elif CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_SetNameInClass(ns, name, value)\ + (likely(PyDict_CheckExact(ns)) ? PyDict_SetItem(ns, name, value) : PyObject_SetItem(ns, name, value)) +#else +#define __Pyx_SetNameInClass(ns, name, value) PyObject_SetItem(ns, name, value) +#endif + +/* PyObjectCall2Args.proto (used by Py3ClassCreate) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + +/* PyObjectLookupSpecial.proto (used by Py3ClassCreate) */ +#if CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS +#define __Pyx_PyObject_LookupSpecialNoError(obj, attr_name) __Pyx__PyObject_LookupSpecial(obj, attr_name, 0) +#define __Pyx_PyObject_LookupSpecial(obj, attr_name) __Pyx__PyObject_LookupSpecial(obj, attr_name, 1) +static CYTHON_INLINE PyObject* __Pyx__PyObject_LookupSpecial(PyObject* obj, PyObject* attr_name, int with_error); +#else +#define __Pyx_PyObject_LookupSpecialNoError(o,n) __Pyx_PyObject_GetAttrStrNoError(o,n) +#define __Pyx_PyObject_LookupSpecial(o,n) __Pyx_PyObject_GetAttrStr(o,n) +#endif + +/* Py3ClassCreate.proto */ +static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *qualname, + PyObject *mkw, PyObject *modname, PyObject *doc); +static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, + PyObject *mkw, int calculate_metaclass, int allow_py2_metaclass); + +/* CLineInTraceback.proto (used by AddTraceback) */ +#if CYTHON_CLINE_IN_TRACEBACK && CYTHON_CLINE_IN_TRACEBACK_RUNTIME +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#else +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#endif + +/* CodeObjectCache.proto (used by AddTraceback) */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject __Pyx_CachedCodeObjectType; +#else +typedef PyCodeObject __Pyx_CachedCodeObjectType; +#endif +typedef struct { + __Pyx_CachedCodeObjectType* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_atomic_int_type accessor_count; + #endif +}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static __Pyx_CachedCodeObjectType *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, __Pyx_CachedCodeObjectType* code_object); + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* FormatTypeName.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%U" +#define __Pyx_DECREF_TypeName(obj) Py_XDECREF(obj) +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 +#define __Pyx_PyType_GetFullyQualifiedName PyType_GetFullyQualifiedName +#else +static __Pyx_TypeName __Pyx_PyType_GetFullyQualifiedName(PyTypeObject* tp); +#endif +#else // !LIMITED_API +typedef const char *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%.200s" +#define __Pyx_PyType_GetFullyQualifiedName(tp) ((tp)->tp_name) +#define __Pyx_DECREF_TypeName(obj) +#endif + +/* GCCDiagnostics.proto (used by CIntToPy) */ +#if !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define __Pyx_HAS_GCC_DIAGNOSTIC +#endif + +/* PyObjectVectorCallKwBuilder.proto (used by CIntToPy) */ +CYTHON_UNUSED static int __Pyx_VectorcallBuilder_AddArg_Check(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n); +#if CYTHON_VECTORCALL +#if PY_VERSION_HEX >= 0x03090000 +#define __Pyx_Object_Vectorcall_CallFromBuilder PyObject_Vectorcall +#else +#define __Pyx_Object_Vectorcall_CallFromBuilder _PyObject_Vectorcall +#endif +#define __Pyx_MakeVectorcallBuilderKwds(n) PyTuple_New(n) +static int __Pyx_VectorcallBuilder_AddArg(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n); +static int __Pyx_VectorcallBuilder_AddArgStr(const char *key, PyObject *value, PyObject *builder, PyObject **args, int n); +#else +#define __Pyx_Object_Vectorcall_CallFromBuilder __Pyx_PyObject_FastCallDict +#define __Pyx_MakeVectorcallBuilderKwds(n) __Pyx_PyDict_NewPresized(n) +#define __Pyx_VectorcallBuilder_AddArg(key, value, builder, args, n) PyDict_SetItem(builder, key, value) +#define __Pyx_VectorcallBuilder_AddArgStr(key, value, builder, args, n) PyDict_SetItemString(builder, key, value) +#endif + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyLong_From_long(long value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyLong_As_long(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyLong_As_int(PyObject *); + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) __Pyx_IsAnySubtype2(Py_TYPE(obj), (PyTypeObject *)type1, (PyTypeObject *)type2) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) (PyObject_TypeCheck(obj, (PyTypeObject *)type1) || PyObject_TypeCheck(obj, (PyTypeObject *)type2)) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2) { + return PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2); +} +#endif +#define __Pyx_PyErr_ExceptionMatches2(err1, err2) __Pyx_PyErr_GivenExceptionMatches2(__Pyx_PyErr_CurrentExceptionType(), err1, err2) +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) +#ifdef PyExceptionInstance_Check + #define __Pyx_PyBaseException_Check(obj) PyExceptionInstance_Check(obj) +#else + #define __Pyx_PyBaseException_Check(obj) __Pyx_TypeCheck(obj, PyExc_BaseException) +#endif + +/* GetRuntimeVersion.proto */ +#if __PYX_LIMITED_VERSION_HEX < 0x030b0000 +static unsigned long __Pyx_cached_runtime_version = 0; +static void __Pyx_init_runtime_version(void); +#else +#define __Pyx_init_runtime_version() +#endif +static unsigned long __Pyx_get_runtime_version(void); + +/* CheckBinaryVersion.proto */ +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer); + +/* DecompressString.proto */ +static PyObject *__Pyx_DecompressString(const char *s, Py_ssize_t length, int algo); + +/* MultiPhaseInitModuleState.proto */ +#if CYTHON_PEP489_MULTI_PHASE_INIT && CYTHON_USE_MODULE_STATE +static PyObject *__Pyx_State_FindModule(void*); +static int __Pyx_State_AddModule(PyObject* module, void*); +static int __Pyx_State_RemoveModule(void*); +#elif CYTHON_USE_MODULE_STATE +#define __Pyx_State_FindModule PyState_FindModule +#define __Pyx_State_AddModule PyState_AddModule +#define __Pyx_State_RemoveModule PyState_RemoveModule +#endif + +/* #### Code section: module_declarations ### */ +/* CythonABIVersion.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API + #if CYTHON_METH_FASTCALL + #define __PYX_FASTCALL_ABI_SUFFIX "_fastcall" + #else + #define __PYX_FASTCALL_ABI_SUFFIX + #endif + #define __PYX_LIMITED_ABI_SUFFIX "limited" __PYX_FASTCALL_ABI_SUFFIX __PYX_AM_SEND_ABI_SUFFIX +#else + #define __PYX_LIMITED_ABI_SUFFIX +#endif +#if __PYX_HAS_PY_AM_SEND == 1 + #define __PYX_AM_SEND_ABI_SUFFIX +#elif __PYX_HAS_PY_AM_SEND == 2 + #define __PYX_AM_SEND_ABI_SUFFIX "amsendbackport" +#else + #define __PYX_AM_SEND_ABI_SUFFIX "noamsend" +#endif +#ifndef __PYX_MONITORING_ABI_SUFFIX + #define __PYX_MONITORING_ABI_SUFFIX +#endif +#if CYTHON_USE_TP_FINALIZE + #define __PYX_TP_FINALIZE_ABI_SUFFIX +#else + #define __PYX_TP_FINALIZE_ABI_SUFFIX "nofinalize" +#endif +#if CYTHON_USE_FREELISTS || !defined(__Pyx_AsyncGen_USED) + #define __PYX_FREELISTS_ABI_SUFFIX +#else + #define __PYX_FREELISTS_ABI_SUFFIX "nofreelists" +#endif +#define CYTHON_ABI __PYX_ABI_VERSION __PYX_LIMITED_ABI_SUFFIX __PYX_MONITORING_ABI_SUFFIX __PYX_TP_FINALIZE_ABI_SUFFIX __PYX_FREELISTS_ABI_SUFFIX __PYX_AM_SEND_ABI_SUFFIX +#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI +#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "." + + +/* Module declarations from "cython" */ + +/* Module declarations from "fontTools.pens.momentsPen" */ +/* #### Code section: typeinfo ### */ +/* #### Code section: before_global_var ### */ +#define __Pyx_MODULE_NAME "fontTools.pens.momentsPen" +extern int __pyx_module_is_main_fontTools__pens__momentsPen; +int __pyx_module_is_main_fontTools__pens__momentsPen = 0; + +/* Implementation of "fontTools.pens.momentsPen" */ +/* #### Code section: global_var ### */ +/* #### Code section: string_decls ### */ +/* #### Code section: decls ### */ +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_glyphset); /* proto */ +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_2_moveTo(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_p0); /* proto */ +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_4_closePath(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_6_endPath(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_8_lineTo(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_p1); /* proto */ +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_10_qCurveToOne(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_p1, PyObject *__pyx_v_p2); /* proto */ +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_12_curveToOne(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_p1, PyObject *__pyx_v_p2, PyObject *__pyx_v_p3); /* proto */ +/* #### Code section: late_includes ### */ +/* #### Code section: module_state ### */ +/* SmallCodeConfig */ +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif + +typedef struct { + PyObject *__pyx_d; + PyObject *__pyx_b; + PyObject *__pyx_cython_runtime; + PyObject *__pyx_empty_tuple; + PyObject *__pyx_empty_bytes; + PyObject *__pyx_empty_unicode; + __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_items; + __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_pop; + __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_values; + PyObject *__pyx_tuple[2]; + PyObject *__pyx_codeobj_tab[7]; + PyObject *__pyx_string_tab[210]; + PyObject *__pyx_number_tab[3]; +/* #### Code section: module_state_contents ### */ +/* CommonTypesMetaclass.module_state_decls */ +PyTypeObject *__pyx_CommonTypesMetaclassType; + +/* CachedMethodType.module_state_decls */ +#if CYTHON_COMPILING_IN_LIMITED_API +PyObject *__Pyx_CachedMethodType; +#endif + +/* CythonFunctionShared.module_state_decls */ +PyTypeObject *__pyx_CyFunctionType; + +/* CodeObjectCache.module_state_decls */ +struct __Pyx_CodeObjectCache __pyx_code_cache; + +/* #### Code section: module_state_end ### */ +} __pyx_mstatetype; + +#if CYTHON_USE_MODULE_STATE +#ifdef __cplusplus +namespace { +extern struct PyModuleDef __pyx_moduledef; +} /* anonymous namespace */ +#else +static struct PyModuleDef __pyx_moduledef; +#endif + +#define __pyx_mstate_global (__Pyx_PyModule_GetState(__Pyx_State_FindModule(&__pyx_moduledef))) + +#define __pyx_m (__Pyx_State_FindModule(&__pyx_moduledef)) +#else +static __pyx_mstatetype __pyx_mstate_global_static = +#ifdef __cplusplus + {}; +#else + {0}; +#endif +static __pyx_mstatetype * const __pyx_mstate_global = &__pyx_mstate_global_static; +#endif +/* #### Code section: constant_name_defines ### */ +#define __pyx_kp_u_ __pyx_string_tab[0] +#define __pyx_kp_u_Glyph_statistics_is_not_defined __pyx_string_tab[1] +#define __pyx_kp_u_Lib_fontTools_pens_momentsPen_py __pyx_string_tab[2] +#define __pyx_kp_u__2 __pyx_string_tab[3] +#define __pyx_n_u_BasePen __pyx_string_tab[4] +#define __pyx_n_u_COMPILED __pyx_string_tab[5] +#define __pyx_n_u_MomentsPen __pyx_string_tab[6] +#define __pyx_n_u_MomentsPen___init __pyx_string_tab[7] +#define __pyx_n_u_MomentsPen__closePath __pyx_string_tab[8] +#define __pyx_n_u_MomentsPen__curveToOne __pyx_string_tab[9] +#define __pyx_n_u_MomentsPen__endPath __pyx_string_tab[10] +#define __pyx_n_u_MomentsPen__lineTo __pyx_string_tab[11] +#define __pyx_n_u_MomentsPen__moveTo __pyx_string_tab[12] +#define __pyx_n_u_MomentsPen__qCurveToOne __pyx_string_tab[13] +#define __pyx_n_u_OpenContourError __pyx_string_tab[14] +#define __pyx_n_u_Pyx_PyDict_NextRef __pyx_string_tab[15] +#define __pyx_n_u_all __pyx_string_tab[16] +#define __pyx_n_u_area __pyx_string_tab[17] +#define __pyx_n_u_asyncio_coroutines __pyx_string_tab[18] +#define __pyx_n_u_cline_in_traceback __pyx_string_tab[19] +#define __pyx_n_u_closePath __pyx_string_tab[20] +#define __pyx_n_u_curveToOne __pyx_string_tab[21] +#define __pyx_n_u_doc __pyx_string_tab[22] +#define __pyx_n_u_endPath __pyx_string_tab[23] +#define __pyx_n_u_fontTools_misc_symfont __pyx_string_tab[24] +#define __pyx_n_u_fontTools_pens_basePen __pyx_string_tab[25] +#define __pyx_n_u_fontTools_pens_momentsPen __pyx_string_tab[26] +#define __pyx_n_u_func __pyx_string_tab[27] +#define __pyx_n_u_getCurrentPoint __pyx_string_tab[28] +#define __pyx_n_u_glyphset __pyx_string_tab[29] +#define __pyx_n_u_init __pyx_string_tab[30] +#define __pyx_n_u_is_coroutine __pyx_string_tab[31] +#define __pyx_n_u_items __pyx_string_tab[32] +#define __pyx_n_u_lineTo __pyx_string_tab[33] +#define __pyx_n_u_main __pyx_string_tab[34] +#define __pyx_n_u_metaclass __pyx_string_tab[35] +#define __pyx_n_u_module __pyx_string_tab[36] +#define __pyx_n_u_momentX __pyx_string_tab[37] +#define __pyx_n_u_momentXX __pyx_string_tab[38] +#define __pyx_n_u_momentXY __pyx_string_tab[39] +#define __pyx_n_u_momentY __pyx_string_tab[40] +#define __pyx_n_u_momentYY __pyx_string_tab[41] +#define __pyx_n_u_moveTo __pyx_string_tab[42] +#define __pyx_n_u_mro_entries __pyx_string_tab[43] +#define __pyx_n_u_name __pyx_string_tab[44] +#define __pyx_n_u_p0 __pyx_string_tab[45] +#define __pyx_n_u_p1 __pyx_string_tab[46] +#define __pyx_n_u_p2 __pyx_string_tab[47] +#define __pyx_n_u_p3 __pyx_string_tab[48] +#define __pyx_n_u_pop __pyx_string_tab[49] +#define __pyx_n_u_prepare __pyx_string_tab[50] +#define __pyx_n_u_printGreenPen __pyx_string_tab[51] +#define __pyx_n_u_qCurveToOne __pyx_string_tab[52] +#define __pyx_n_u_qualname __pyx_string_tab[53] +#define __pyx_n_u_r0 __pyx_string_tab[54] +#define __pyx_n_u_r1 __pyx_string_tab[55] +#define __pyx_n_u_r10 __pyx_string_tab[56] +#define __pyx_n_u_r100 __pyx_string_tab[57] +#define __pyx_n_u_r101 __pyx_string_tab[58] +#define __pyx_n_u_r102 __pyx_string_tab[59] +#define __pyx_n_u_r103 __pyx_string_tab[60] +#define __pyx_n_u_r104 __pyx_string_tab[61] +#define __pyx_n_u_r105 __pyx_string_tab[62] +#define __pyx_n_u_r106 __pyx_string_tab[63] +#define __pyx_n_u_r107 __pyx_string_tab[64] +#define __pyx_n_u_r108 __pyx_string_tab[65] +#define __pyx_n_u_r109 __pyx_string_tab[66] +#define __pyx_n_u_r11 __pyx_string_tab[67] +#define __pyx_n_u_r110 __pyx_string_tab[68] +#define __pyx_n_u_r111 __pyx_string_tab[69] +#define __pyx_n_u_r112 __pyx_string_tab[70] +#define __pyx_n_u_r113 __pyx_string_tab[71] +#define __pyx_n_u_r114 __pyx_string_tab[72] +#define __pyx_n_u_r115 __pyx_string_tab[73] +#define __pyx_n_u_r116 __pyx_string_tab[74] +#define __pyx_n_u_r117 __pyx_string_tab[75] +#define __pyx_n_u_r118 __pyx_string_tab[76] +#define __pyx_n_u_r119 __pyx_string_tab[77] +#define __pyx_n_u_r12 __pyx_string_tab[78] +#define __pyx_n_u_r120 __pyx_string_tab[79] +#define __pyx_n_u_r121 __pyx_string_tab[80] +#define __pyx_n_u_r122 __pyx_string_tab[81] +#define __pyx_n_u_r123 __pyx_string_tab[82] +#define __pyx_n_u_r124 __pyx_string_tab[83] +#define __pyx_n_u_r125 __pyx_string_tab[84] +#define __pyx_n_u_r126 __pyx_string_tab[85] +#define __pyx_n_u_r127 __pyx_string_tab[86] +#define __pyx_n_u_r128 __pyx_string_tab[87] +#define __pyx_n_u_r129 __pyx_string_tab[88] +#define __pyx_n_u_r13 __pyx_string_tab[89] +#define __pyx_n_u_r130 __pyx_string_tab[90] +#define __pyx_n_u_r131 __pyx_string_tab[91] +#define __pyx_n_u_r132 __pyx_string_tab[92] +#define __pyx_n_u_r14 __pyx_string_tab[93] +#define __pyx_n_u_r15 __pyx_string_tab[94] +#define __pyx_n_u_r16 __pyx_string_tab[95] +#define __pyx_n_u_r17 __pyx_string_tab[96] +#define __pyx_n_u_r18 __pyx_string_tab[97] +#define __pyx_n_u_r19 __pyx_string_tab[98] +#define __pyx_n_u_r2 __pyx_string_tab[99] +#define __pyx_n_u_r20 __pyx_string_tab[100] +#define __pyx_n_u_r21 __pyx_string_tab[101] +#define __pyx_n_u_r22 __pyx_string_tab[102] +#define __pyx_n_u_r23 __pyx_string_tab[103] +#define __pyx_n_u_r24 __pyx_string_tab[104] +#define __pyx_n_u_r25 __pyx_string_tab[105] +#define __pyx_n_u_r26 __pyx_string_tab[106] +#define __pyx_n_u_r27 __pyx_string_tab[107] +#define __pyx_n_u_r28 __pyx_string_tab[108] +#define __pyx_n_u_r29 __pyx_string_tab[109] +#define __pyx_n_u_r3 __pyx_string_tab[110] +#define __pyx_n_u_r30 __pyx_string_tab[111] +#define __pyx_n_u_r31 __pyx_string_tab[112] +#define __pyx_n_u_r32 __pyx_string_tab[113] +#define __pyx_n_u_r33 __pyx_string_tab[114] +#define __pyx_n_u_r34 __pyx_string_tab[115] +#define __pyx_n_u_r35 __pyx_string_tab[116] +#define __pyx_n_u_r36 __pyx_string_tab[117] +#define __pyx_n_u_r37 __pyx_string_tab[118] +#define __pyx_n_u_r38 __pyx_string_tab[119] +#define __pyx_n_u_r39 __pyx_string_tab[120] +#define __pyx_n_u_r4 __pyx_string_tab[121] +#define __pyx_n_u_r40 __pyx_string_tab[122] +#define __pyx_n_u_r41 __pyx_string_tab[123] +#define __pyx_n_u_r42 __pyx_string_tab[124] +#define __pyx_n_u_r43 __pyx_string_tab[125] +#define __pyx_n_u_r44 __pyx_string_tab[126] +#define __pyx_n_u_r45 __pyx_string_tab[127] +#define __pyx_n_u_r46 __pyx_string_tab[128] +#define __pyx_n_u_r47 __pyx_string_tab[129] +#define __pyx_n_u_r48 __pyx_string_tab[130] +#define __pyx_n_u_r49 __pyx_string_tab[131] +#define __pyx_n_u_r5 __pyx_string_tab[132] +#define __pyx_n_u_r50 __pyx_string_tab[133] +#define __pyx_n_u_r51 __pyx_string_tab[134] +#define __pyx_n_u_r52 __pyx_string_tab[135] +#define __pyx_n_u_r53 __pyx_string_tab[136] +#define __pyx_n_u_r54 __pyx_string_tab[137] +#define __pyx_n_u_r55 __pyx_string_tab[138] +#define __pyx_n_u_r56 __pyx_string_tab[139] +#define __pyx_n_u_r57 __pyx_string_tab[140] +#define __pyx_n_u_r58 __pyx_string_tab[141] +#define __pyx_n_u_r59 __pyx_string_tab[142] +#define __pyx_n_u_r6 __pyx_string_tab[143] +#define __pyx_n_u_r60 __pyx_string_tab[144] +#define __pyx_n_u_r61 __pyx_string_tab[145] +#define __pyx_n_u_r62 __pyx_string_tab[146] +#define __pyx_n_u_r63 __pyx_string_tab[147] +#define __pyx_n_u_r64 __pyx_string_tab[148] +#define __pyx_n_u_r65 __pyx_string_tab[149] +#define __pyx_n_u_r66 __pyx_string_tab[150] +#define __pyx_n_u_r67 __pyx_string_tab[151] +#define __pyx_n_u_r68 __pyx_string_tab[152] +#define __pyx_n_u_r69 __pyx_string_tab[153] +#define __pyx_n_u_r7 __pyx_string_tab[154] +#define __pyx_n_u_r70 __pyx_string_tab[155] +#define __pyx_n_u_r71 __pyx_string_tab[156] +#define __pyx_n_u_r72 __pyx_string_tab[157] +#define __pyx_n_u_r73 __pyx_string_tab[158] +#define __pyx_n_u_r74 __pyx_string_tab[159] +#define __pyx_n_u_r75 __pyx_string_tab[160] +#define __pyx_n_u_r76 __pyx_string_tab[161] +#define __pyx_n_u_r77 __pyx_string_tab[162] +#define __pyx_n_u_r78 __pyx_string_tab[163] +#define __pyx_n_u_r79 __pyx_string_tab[164] +#define __pyx_n_u_r8 __pyx_string_tab[165] +#define __pyx_n_u_r80 __pyx_string_tab[166] +#define __pyx_n_u_r81 __pyx_string_tab[167] +#define __pyx_n_u_r82 __pyx_string_tab[168] +#define __pyx_n_u_r83 __pyx_string_tab[169] +#define __pyx_n_u_r84 __pyx_string_tab[170] +#define __pyx_n_u_r85 __pyx_string_tab[171] +#define __pyx_n_u_r86 __pyx_string_tab[172] +#define __pyx_n_u_r87 __pyx_string_tab[173] +#define __pyx_n_u_r88 __pyx_string_tab[174] +#define __pyx_n_u_r89 __pyx_string_tab[175] +#define __pyx_n_u_r9 __pyx_string_tab[176] +#define __pyx_n_u_r90 __pyx_string_tab[177] +#define __pyx_n_u_r91 __pyx_string_tab[178] +#define __pyx_n_u_r92 __pyx_string_tab[179] +#define __pyx_n_u_r93 __pyx_string_tab[180] +#define __pyx_n_u_r94 __pyx_string_tab[181] +#define __pyx_n_u_r95 __pyx_string_tab[182] +#define __pyx_n_u_r96 __pyx_string_tab[183] +#define __pyx_n_u_r97 __pyx_string_tab[184] +#define __pyx_n_u_r98 __pyx_string_tab[185] +#define __pyx_n_u_r99 __pyx_string_tab[186] +#define __pyx_n_u_self __pyx_string_tab[187] +#define __pyx_n_u_set_name __pyx_string_tab[188] +#define __pyx_n_u_setdefault __pyx_string_tab[189] +#define __pyx_n_u_startPoint __pyx_string_tab[190] +#define __pyx_n_u_test __pyx_string_tab[191] +#define __pyx_n_u_values __pyx_string_tab[192] +#define __pyx_n_u_x __pyx_string_tab[193] +#define __pyx_n_u_x0 __pyx_string_tab[194] +#define __pyx_n_u_x1 __pyx_string_tab[195] +#define __pyx_n_u_x2 __pyx_string_tab[196] +#define __pyx_n_u_x3 __pyx_string_tab[197] +#define __pyx_n_u_y __pyx_string_tab[198] +#define __pyx_n_u_y0 __pyx_string_tab[199] +#define __pyx_n_u_y1 __pyx_string_tab[200] +#define __pyx_n_u_y2 __pyx_string_tab[201] +#define __pyx_n_u_y3 __pyx_string_tab[202] +#define __pyx_kp_b_iso88591_AT_E_a_E_E_E_Rr_S_S_S_Rr_Rr_Rr_R __pyx_string_tab[203] +#define __pyx_kp_b_iso88591_A_E_a_E_S_S_Rr_S_S_S_Rr_Rr_Rr_Rr __pyx_string_tab[204] +#define __pyx_kp_b_iso88591_A_O1 __pyx_string_tab[205] +#define __pyx_kp_b_iso88591_A_T_3c_Q_1 __pyx_string_tab[206] +#define __pyx_kp_b_iso88591_A_T_3c_Q_Q __pyx_string_tab[207] +#define __pyx_kp_b_iso88591_At_E_a_E_E_Rr_S_S_Rr_Rr_Rr_Rr_Rr __pyx_string_tab[208] +#define __pyx_kp_b_iso88591_q_y_q_HA_Kq_Kq_L_L_L __pyx_string_tab[209] +#define __pyx_int_0 __pyx_number_tab[0] +#define __pyx_int_1 __pyx_number_tab[1] +#define __pyx_int_2 __pyx_number_tab[2] +/* #### Code section: module_state_clear ### */ +#if CYTHON_USE_MODULE_STATE +static CYTHON_SMALL_CODE int __pyx_m_clear(PyObject *m) { + __pyx_mstatetype *clear_module_state = __Pyx_PyModule_GetState(m); + if (!clear_module_state) return 0; + Py_CLEAR(clear_module_state->__pyx_d); + Py_CLEAR(clear_module_state->__pyx_b); + Py_CLEAR(clear_module_state->__pyx_cython_runtime); + Py_CLEAR(clear_module_state->__pyx_empty_tuple); + Py_CLEAR(clear_module_state->__pyx_empty_bytes); + Py_CLEAR(clear_module_state->__pyx_empty_unicode); + #if CYTHON_PEP489_MULTI_PHASE_INIT + __Pyx_State_RemoveModule(NULL); + #endif + for (int i=0; i<2; ++i) { Py_CLEAR(clear_module_state->__pyx_tuple[i]); } + for (int i=0; i<7; ++i) { Py_CLEAR(clear_module_state->__pyx_codeobj_tab[i]); } + for (int i=0; i<210; ++i) { Py_CLEAR(clear_module_state->__pyx_string_tab[i]); } + for (int i=0; i<3; ++i) { Py_CLEAR(clear_module_state->__pyx_number_tab[i]); } +/* #### Code section: module_state_clear_contents ### */ +/* CommonTypesMetaclass.module_state_clear */ +Py_CLEAR(clear_module_state->__pyx_CommonTypesMetaclassType); + +/* CythonFunctionShared.module_state_clear */ +Py_CLEAR(clear_module_state->__pyx_CyFunctionType); + +/* #### Code section: module_state_clear_end ### */ +return 0; +} +#endif +/* #### Code section: module_state_traverse ### */ +#if CYTHON_USE_MODULE_STATE +static CYTHON_SMALL_CODE int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { + __pyx_mstatetype *traverse_module_state = __Pyx_PyModule_GetState(m); + if (!traverse_module_state) return 0; + Py_VISIT(traverse_module_state->__pyx_d); + Py_VISIT(traverse_module_state->__pyx_b); + Py_VISIT(traverse_module_state->__pyx_cython_runtime); + __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_tuple); + __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_bytes); + __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_unicode); + for (int i=0; i<2; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_tuple[i]); } + for (int i=0; i<7; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_codeobj_tab[i]); } + for (int i=0; i<210; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_string_tab[i]); } + for (int i=0; i<3; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_number_tab[i]); } +/* #### Code section: module_state_traverse_contents ### */ +/* CommonTypesMetaclass.module_state_traverse */ +Py_VISIT(traverse_module_state->__pyx_CommonTypesMetaclassType); + +/* CythonFunctionShared.module_state_traverse */ +Py_VISIT(traverse_module_state->__pyx_CyFunctionType); + +/* #### Code section: module_state_traverse_end ### */ +return 0; +} +#endif +/* #### Code section: module_code ### */ + +/* "fontTools/pens/momentsPen.py":16 + * class MomentsPen(BasePen): + * + * def __init__(self, glyphset=None): # <<<<<<<<<<<<<< + * BasePen.__init__(self, glyphset) + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_1__init__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen___init__, "MomentsPen.__init__(self, glyphset=None)"); +static PyMethodDef __pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_1__init__ = {"__init__", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_1__init__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen___init__}; +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_1__init__(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_glyphset = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_glyphset,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 16, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 16, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 16, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "__init__", 0) < (0)) __PYX_ERR(0, 16, __pyx_L3_error) + if (!values[1]) values[1] = __Pyx_NewRef(((PyObject *)Py_None)); + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("__init__", 0, 1, 2, i); __PYX_ERR(0, 16, __pyx_L3_error) } + } + } else { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 16, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 16, __pyx_L3_error) + break; + default: goto __pyx_L5_argtuple_error; + } + if (!values[1]) values[1] = __Pyx_NewRef(((PyObject *)Py_None)); + } + __pyx_v_self = values[0]; + __pyx_v_glyphset = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__init__", 0, 1, 2, __pyx_nargs); __PYX_ERR(0, 16, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen___init__(__pyx_self, __pyx_v_self, __pyx_v_glyphset); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_glyphset) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + size_t __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__init__", 0); + + /* "fontTools/pens/momentsPen.py":17 + * + * def __init__(self, glyphset=None): + * BasePen.__init__(self, glyphset) # <<<<<<<<<<<<<< + * + * self.area = 0 +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_BasePen); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_init); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_5 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_4); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_4, __pyx__function); + __pyx_t_5 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_v_self, __pyx_v_glyphset}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_4, __pyx_callargs+__pyx_t_5, (3-__pyx_t_5) | (__pyx_t_5*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/pens/momentsPen.py":19 + * BasePen.__init__(self, glyphset) + * + * self.area = 0 # <<<<<<<<<<<<<< + * self.momentX = 0 + * self.momentY = 0 +*/ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_area, __pyx_mstate_global->__pyx_int_0) < (0)) __PYX_ERR(0, 19, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":20 + * + * self.area = 0 + * self.momentX = 0 # <<<<<<<<<<<<<< + * self.momentY = 0 + * self.momentXX = 0 +*/ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentX, __pyx_mstate_global->__pyx_int_0) < (0)) __PYX_ERR(0, 20, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":21 + * self.area = 0 + * self.momentX = 0 + * self.momentY = 0 # <<<<<<<<<<<<<< + * self.momentXX = 0 + * self.momentXY = 0 +*/ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentY, __pyx_mstate_global->__pyx_int_0) < (0)) __PYX_ERR(0, 21, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":22 + * self.momentX = 0 + * self.momentY = 0 + * self.momentXX = 0 # <<<<<<<<<<<<<< + * self.momentXY = 0 + * self.momentYY = 0 +*/ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentXX, __pyx_mstate_global->__pyx_int_0) < (0)) __PYX_ERR(0, 22, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":23 + * self.momentY = 0 + * self.momentXX = 0 + * self.momentXY = 0 # <<<<<<<<<<<<<< + * self.momentYY = 0 + * +*/ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentXY, __pyx_mstate_global->__pyx_int_0) < (0)) __PYX_ERR(0, 23, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":24 + * self.momentXX = 0 + * self.momentXY = 0 + * self.momentYY = 0 # <<<<<<<<<<<<<< + * + * def _moveTo(self, p0): +*/ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentYY, __pyx_mstate_global->__pyx_int_0) < (0)) __PYX_ERR(0, 24, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":16 + * class MomentsPen(BasePen): + * + * def __init__(self, glyphset=None): # <<<<<<<<<<<<<< + * BasePen.__init__(self, glyphset) + * +*/ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/pens/momentsPen.py":26 + * self.momentYY = 0 + * + * def _moveTo(self, p0): # <<<<<<<<<<<<<< + * self._startPoint = p0 + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_3_moveTo(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_2_moveTo, "MomentsPen._moveTo(self, p0)"); +static PyMethodDef __pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_3_moveTo = {"_moveTo", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_3_moveTo, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_2_moveTo}; +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_3_moveTo(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_p0 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_moveTo (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_p0,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 26, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 26, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 26, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_moveTo", 0) < (0)) __PYX_ERR(0, 26, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_moveTo", 1, 2, 2, i); __PYX_ERR(0, 26, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 26, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 26, __pyx_L3_error) + } + __pyx_v_self = values[0]; + __pyx_v_p0 = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_moveTo", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 26, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._moveTo", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_2_moveTo(__pyx_self, __pyx_v_self, __pyx_v_p0); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_2_moveTo(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_p0) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_moveTo", 0); + + /* "fontTools/pens/momentsPen.py":27 + * + * def _moveTo(self, p0): + * self._startPoint = p0 # <<<<<<<<<<<<<< + * + * def _closePath(self): +*/ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_startPoint, __pyx_v_p0) < (0)) __PYX_ERR(0, 27, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":26 + * self.momentYY = 0 + * + * def _moveTo(self, p0): # <<<<<<<<<<<<<< + * self._startPoint = p0 + * +*/ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._moveTo", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/pens/momentsPen.py":29 + * self._startPoint = p0 + * + * def _closePath(self): # <<<<<<<<<<<<<< + * p0 = self._getCurrentPoint() + * if p0 != self._startPoint: +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_5_closePath(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_4_closePath, "MomentsPen._closePath(self)"); +static PyMethodDef __pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_5_closePath = {"_closePath", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_5_closePath, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_4_closePath}; +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_5_closePath(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_closePath (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 29, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 29, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_closePath", 0) < (0)) __PYX_ERR(0, 29, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_closePath", 1, 1, 1, i); __PYX_ERR(0, 29, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 29, __pyx_L3_error) + } + __pyx_v_self = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_closePath", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 29, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._closePath", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_4_closePath(__pyx_self, __pyx_v_self); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_4_closePath(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_v_p0 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + size_t __pyx_t_3; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_closePath", 0); + + /* "fontTools/pens/momentsPen.py":30 + * + * def _closePath(self): + * p0 = self._getCurrentPoint() # <<<<<<<<<<<<<< + * if p0 != self._startPoint: + * self._lineTo(self._startPoint) +*/ + __pyx_t_2 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_getCurrentPoint, __pyx_callargs+__pyx_t_3, (1-__pyx_t_3) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_v_p0 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/pens/momentsPen.py":31 + * def _closePath(self): + * p0 = self._getCurrentPoint() + * if p0 != self._startPoint: # <<<<<<<<<<<<<< + * self._lineTo(self._startPoint) + * +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_startPoint); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyObject_RichCompare(__pyx_v_p0, __pyx_t_1, Py_NE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__pyx_t_4) { + + /* "fontTools/pens/momentsPen.py":32 + * p0 = self._getCurrentPoint() + * if p0 != self._startPoint: + * self._lineTo(self._startPoint) # <<<<<<<<<<<<<< + * + * def _endPath(self): +*/ + __pyx_t_1 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_1); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_startPoint); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_3 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_t_5}; + __pyx_t_2 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_lineTo, __pyx_callargs+__pyx_t_3, (2-__pyx_t_3) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":31 + * def _closePath(self): + * p0 = self._getCurrentPoint() + * if p0 != self._startPoint: # <<<<<<<<<<<<<< + * self._lineTo(self._startPoint) + * +*/ + } + + /* "fontTools/pens/momentsPen.py":29 + * self._startPoint = p0 + * + * def _closePath(self): # <<<<<<<<<<<<<< + * p0 = self._getCurrentPoint() + * if p0 != self._startPoint: +*/ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._closePath", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_p0); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/pens/momentsPen.py":34 + * self._lineTo(self._startPoint) + * + * def _endPath(self): # <<<<<<<<<<<<<< + * p0 = self._getCurrentPoint() + * if p0 != self._startPoint: +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_7_endPath(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_6_endPath, "MomentsPen._endPath(self)"); +static PyMethodDef __pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_7_endPath = {"_endPath", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_7_endPath, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_6_endPath}; +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_7_endPath(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_endPath (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 34, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 34, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_endPath", 0) < (0)) __PYX_ERR(0, 34, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 1; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_endPath", 1, 1, 1, i); __PYX_ERR(0, 34, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 34, __pyx_L3_error) + } + __pyx_v_self = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_endPath", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 34, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._endPath", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_6_endPath(__pyx_self, __pyx_v_self); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_6_endPath(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_v_p0 = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + size_t __pyx_t_3; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_endPath", 0); + + /* "fontTools/pens/momentsPen.py":35 + * + * def _endPath(self): + * p0 = self._getCurrentPoint() # <<<<<<<<<<<<<< + * if p0 != self._startPoint: + * raise OpenContourError("Glyph statistics is not defined on open contours.") +*/ + __pyx_t_2 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_getCurrentPoint, __pyx_callargs+__pyx_t_3, (1-__pyx_t_3) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_v_p0 = __pyx_t_1; + __pyx_t_1 = 0; + + /* "fontTools/pens/momentsPen.py":36 + * def _endPath(self): + * p0 = self._getCurrentPoint() + * if p0 != self._startPoint: # <<<<<<<<<<<<<< + * raise OpenContourError("Glyph statistics is not defined on open contours.") + * +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_startPoint); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 36, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyObject_RichCompare(__pyx_v_p0, __pyx_t_1, Py_NE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 36, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 36, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(__pyx_t_4)) { + + /* "fontTools/pens/momentsPen.py":37 + * p0 = self._getCurrentPoint() + * if p0 != self._startPoint: + * raise OpenContourError("Glyph statistics is not defined on open contours.") # <<<<<<<<<<<<<< + * + * @cython.locals(r0=cython.double) +*/ + __pyx_t_1 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_OpenContourError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 37, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_3 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5); + assert(__pyx_t_1); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_5, __pyx__function); + __pyx_t_3 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_mstate_global->__pyx_kp_u_Glyph_statistics_is_not_defined}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_5, __pyx_callargs+__pyx_t_3, (2-__pyx_t_3) | (__pyx_t_3*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 37, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 37, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":36 + * def _endPath(self): + * p0 = self._getCurrentPoint() + * if p0 != self._startPoint: # <<<<<<<<<<<<<< + * raise OpenContourError("Glyph statistics is not defined on open contours.") + * +*/ + } + + /* "fontTools/pens/momentsPen.py":34 + * self._lineTo(self._startPoint) + * + * def _endPath(self): # <<<<<<<<<<<<<< + * p0 = self._getCurrentPoint() + * if p0 != self._startPoint: +*/ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._endPath", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_p0); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/pens/momentsPen.py":39 + * raise OpenContourError("Glyph statistics is not defined on open contours.") + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_9_lineTo(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_8_lineTo, "MomentsPen._lineTo(self, p1)"); +static PyMethodDef __pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_9_lineTo = {"_lineTo", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_9_lineTo, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_8_lineTo}; +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_9_lineTo(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_p1 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_lineTo (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_p1,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 39, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 39, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 39, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_lineTo", 0) < (0)) __PYX_ERR(0, 39, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_lineTo", 1, 2, 2, i); __PYX_ERR(0, 39, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 39, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 39, __pyx_L3_error) + } + __pyx_v_self = values[0]; + __pyx_v_p1 = values[1]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_lineTo", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 39, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._lineTo", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_8_lineTo(__pyx_self, __pyx_v_self, __pyx_v_p1); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_8_lineTo(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_p1) { + double __pyx_v_x1; + double __pyx_v_y1; + double __pyx_v_x0; + double __pyx_v_y0; + double __pyx_v_r12; + double __pyx_v_r11; + double __pyx_v_r10; + double __pyx_v_r9; + double __pyx_v_r8; + double __pyx_v_r7; + double __pyx_v_r6; + double __pyx_v_r5; + double __pyx_v_r4; + double __pyx_v_r3; + double __pyx_v_r2; + double __pyx_v_r1; + double __pyx_v_r0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + size_t __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *(*__pyx_t_6)(PyObject *); + double __pyx_t_7; + double __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_lineTo", 0); + + /* "fontTools/pens/momentsPen.py":55 + * @cython.locals(x1=cython.double, y1=cython.double) + * def _lineTo(self, p1): + * x0, y0 = self._getCurrentPoint() # <<<<<<<<<<<<<< + * x1, y1 = p1 + * +*/ + __pyx_t_2 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_getCurrentPoint, __pyx_callargs+__pyx_t_3, (1-__pyx_t_3) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 55, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 55, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_4); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 55, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 55, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_4); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 55, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 55, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_5 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 55, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_6 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_5); + index = 0; __pyx_t_2 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_4 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_4)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_5), 2) < (0)) __PYX_ERR(0, 55, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 55, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_t_7 = __Pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 55, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_8 = __Pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 55, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_x0 = __pyx_t_7; + __pyx_v_y0 = __pyx_t_8; + + /* "fontTools/pens/momentsPen.py":56 + * def _lineTo(self, p1): + * x0, y0 = self._getCurrentPoint() + * x1, y1 = p1 # <<<<<<<<<<<<<< + * + * r0 = x1 * y0 +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_p1))) || (PyList_CheckExact(__pyx_v_p1))) { + PyObject* sequence = __pyx_v_p1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 56, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_4); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_4); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_2 = PyObject_GetIter(__pyx_v_p1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); + index = 0; __pyx_t_1 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_4 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_4)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_2), 2) < (0)) __PYX_ERR(0, 56, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 56, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_t_8 = __Pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __Pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_x1 = __pyx_t_8; + __pyx_v_y1 = __pyx_t_7; + + /* "fontTools/pens/momentsPen.py":58 + * x1, y1 = p1 + * + * r0 = x1 * y0 # <<<<<<<<<<<<<< + * r1 = x1 * y1 + * r2 = x1**2 +*/ + __pyx_v_r0 = (__pyx_v_x1 * __pyx_v_y0); + + /* "fontTools/pens/momentsPen.py":59 + * + * r0 = x1 * y0 + * r1 = x1 * y1 # <<<<<<<<<<<<<< + * r2 = x1**2 + * r3 = r2 * y1 +*/ + __pyx_v_r1 = (__pyx_v_x1 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":60 + * r0 = x1 * y0 + * r1 = x1 * y1 + * r2 = x1**2 # <<<<<<<<<<<<<< + * r3 = r2 * y1 + * r4 = y0 - y1 +*/ + __pyx_v_r2 = pow(__pyx_v_x1, 2.0); + + /* "fontTools/pens/momentsPen.py":61 + * r1 = x1 * y1 + * r2 = x1**2 + * r3 = r2 * y1 # <<<<<<<<<<<<<< + * r4 = y0 - y1 + * r5 = r4 * x0 +*/ + __pyx_v_r3 = (__pyx_v_r2 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":62 + * r2 = x1**2 + * r3 = r2 * y1 + * r4 = y0 - y1 # <<<<<<<<<<<<<< + * r5 = r4 * x0 + * r6 = x0**2 +*/ + __pyx_v_r4 = (__pyx_v_y0 - __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":63 + * r3 = r2 * y1 + * r4 = y0 - y1 + * r5 = r4 * x0 # <<<<<<<<<<<<<< + * r6 = x0**2 + * r7 = 2 * y0 +*/ + __pyx_v_r5 = (__pyx_v_r4 * __pyx_v_x0); + + /* "fontTools/pens/momentsPen.py":64 + * r4 = y0 - y1 + * r5 = r4 * x0 + * r6 = x0**2 # <<<<<<<<<<<<<< + * r7 = 2 * y0 + * r8 = y0**2 +*/ + __pyx_v_r6 = pow(__pyx_v_x0, 2.0); + + /* "fontTools/pens/momentsPen.py":65 + * r5 = r4 * x0 + * r6 = x0**2 + * r7 = 2 * y0 # <<<<<<<<<<<<<< + * r8 = y0**2 + * r9 = y1**2 +*/ + __pyx_v_r7 = (2.0 * __pyx_v_y0); + + /* "fontTools/pens/momentsPen.py":66 + * r6 = x0**2 + * r7 = 2 * y0 + * r8 = y0**2 # <<<<<<<<<<<<<< + * r9 = y1**2 + * r10 = x1**3 +*/ + __pyx_v_r8 = pow(__pyx_v_y0, 2.0); + + /* "fontTools/pens/momentsPen.py":67 + * r7 = 2 * y0 + * r8 = y0**2 + * r9 = y1**2 # <<<<<<<<<<<<<< + * r10 = x1**3 + * r11 = y0**3 +*/ + __pyx_v_r9 = pow(__pyx_v_y1, 2.0); + + /* "fontTools/pens/momentsPen.py":68 + * r8 = y0**2 + * r9 = y1**2 + * r10 = x1**3 # <<<<<<<<<<<<<< + * r11 = y0**3 + * r12 = y1**3 +*/ + __pyx_v_r10 = pow(__pyx_v_x1, 3.0); + + /* "fontTools/pens/momentsPen.py":69 + * r9 = y1**2 + * r10 = x1**3 + * r11 = y0**3 # <<<<<<<<<<<<<< + * r12 = y1**3 + * +*/ + __pyx_v_r11 = pow(__pyx_v_y0, 3.0); + + /* "fontTools/pens/momentsPen.py":70 + * r10 = x1**3 + * r11 = y0**3 + * r12 = y1**3 # <<<<<<<<<<<<<< + * + * self.area += -r0 / 2 - r1 / 2 + x0 * (y0 + y1) / 2 +*/ + __pyx_v_r12 = pow(__pyx_v_y1, 3.0); + + /* "fontTools/pens/momentsPen.py":72 + * r12 = y1**3 + * + * self.area += -r0 / 2 - r1 / 2 + x0 * (y0 + y1) / 2 # <<<<<<<<<<<<<< + * self.momentX += -r2 * y0 / 6 - r3 / 3 - r5 * x1 / 6 + r6 * (r7 + y1) / 6 + * self.momentY += ( +*/ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_area); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 72, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = PyFloat_FromDouble(((((-__pyx_v_r0) / 2.0) - (__pyx_v_r1 / 2.0)) + ((__pyx_v_x0 * (__pyx_v_y0 + __pyx_v_y1)) / 2.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 72, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 72, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_area, __pyx_t_2) < (0)) __PYX_ERR(0, 72, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":73 + * + * self.area += -r0 / 2 - r1 / 2 + x0 * (y0 + y1) / 2 + * self.momentX += -r2 * y0 / 6 - r3 / 3 - r5 * x1 / 6 + r6 * (r7 + y1) / 6 # <<<<<<<<<<<<<< + * self.momentY += ( + * -r0 * y1 / 6 - r8 * x1 / 6 - r9 * x1 / 6 + x0 * (r8 + r9 + y0 * y1) / 6 +*/ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentX); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 73, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyFloat_FromDouble(((((((-__pyx_v_r2) * __pyx_v_y0) / 6.0) - (__pyx_v_r3 / 3.0)) - ((__pyx_v_r5 * __pyx_v_x1) / 6.0)) + ((__pyx_v_r6 * (__pyx_v_r7 + __pyx_v_y1)) / 6.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 73, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 73, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentX, __pyx_t_4) < (0)) __PYX_ERR(0, 73, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/pens/momentsPen.py":74 + * self.area += -r0 / 2 - r1 / 2 + x0 * (y0 + y1) / 2 + * self.momentX += -r2 * y0 / 6 - r3 / 3 - r5 * x1 / 6 + r6 * (r7 + y1) / 6 + * self.momentY += ( # <<<<<<<<<<<<<< + * -r0 * y1 / 6 - r8 * x1 / 6 - r9 * x1 / 6 + x0 * (r8 + r9 + y0 * y1) / 6 + * ) +*/ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentY); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 74, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + + /* "fontTools/pens/momentsPen.py":75 + * self.momentX += -r2 * y0 / 6 - r3 / 3 - r5 * x1 / 6 + r6 * (r7 + y1) / 6 + * self.momentY += ( + * -r0 * y1 / 6 - r8 * x1 / 6 - r9 * x1 / 6 + x0 * (r8 + r9 + y0 * y1) / 6 # <<<<<<<<<<<<<< + * ) + * self.momentXX += ( +*/ + __pyx_t_1 = PyFloat_FromDouble(((((((-__pyx_v_r0) * __pyx_v_y1) / 6.0) - ((__pyx_v_r8 * __pyx_v_x1) / 6.0)) - ((__pyx_v_r9 * __pyx_v_x1) / 6.0)) + ((__pyx_v_x0 * ((__pyx_v_r8 + __pyx_v_r9) + (__pyx_v_y0 * __pyx_v_y1))) / 6.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 75, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":74 + * self.area += -r0 / 2 - r1 / 2 + x0 * (y0 + y1) / 2 + * self.momentX += -r2 * y0 / 6 - r3 / 3 - r5 * x1 / 6 + r6 * (r7 + y1) / 6 + * self.momentY += ( # <<<<<<<<<<<<<< + * -r0 * y1 / 6 - r8 * x1 / 6 - r9 * x1 / 6 + x0 * (r8 + r9 + y0 * y1) / 6 + * ) +*/ + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 74, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentY, __pyx_t_2) < (0)) __PYX_ERR(0, 74, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":77 + * -r0 * y1 / 6 - r8 * x1 / 6 - r9 * x1 / 6 + x0 * (r8 + r9 + y0 * y1) / 6 + * ) + * self.momentXX += ( # <<<<<<<<<<<<<< + * -r10 * y0 / 12 + * - r10 * y1 / 4 +*/ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentXX); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/pens/momentsPen.py":82 + * - r2 * r5 / 12 + * - r4 * r6 * x1 / 12 + * + x0**3 * (3 * y0 + y1) / 12 # <<<<<<<<<<<<<< + * ) + * self.momentXY += ( +*/ + __pyx_t_1 = PyFloat_FromDouble((((((((-__pyx_v_r10) * __pyx_v_y0) / 12.0) - ((__pyx_v_r10 * __pyx_v_y1) / 4.0)) - ((__pyx_v_r2 * __pyx_v_r5) / 12.0)) - (((__pyx_v_r4 * __pyx_v_r6) * __pyx_v_x1) / 12.0)) + ((pow(__pyx_v_x0, 3.0) * ((3.0 * __pyx_v_y0) + __pyx_v_y1)) / 12.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 82, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":77 + * -r0 * y1 / 6 - r8 * x1 / 6 - r9 * x1 / 6 + x0 * (r8 + r9 + y0 * y1) / 6 + * ) + * self.momentXX += ( # <<<<<<<<<<<<<< + * -r10 * y0 / 12 + * - r10 * y1 / 4 +*/ + __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentXX, __pyx_t_4) < (0)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/pens/momentsPen.py":84 + * + x0**3 * (3 * y0 + y1) / 12 + * ) + * self.momentXY += ( # <<<<<<<<<<<<<< + * -r2 * r8 / 24 + * - r2 * r9 / 8 +*/ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentXY); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 84, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + + /* "fontTools/pens/momentsPen.py":89 + * - r3 * r7 / 24 + * + r6 * (r7 * y1 + 3 * r8 + r9) / 24 + * - x0 * x1 * (r8 - r9) / 12 # <<<<<<<<<<<<<< + * ) + * self.momentYY += ( +*/ + __pyx_t_1 = PyFloat_FromDouble((((((((-__pyx_v_r2) * __pyx_v_r8) / 24.0) - ((__pyx_v_r2 * __pyx_v_r9) / 8.0)) - ((__pyx_v_r3 * __pyx_v_r7) / 24.0)) + ((__pyx_v_r6 * (((__pyx_v_r7 * __pyx_v_y1) + (3.0 * __pyx_v_r8)) + __pyx_v_r9)) / 24.0)) - (((__pyx_v_x0 * __pyx_v_x1) * (__pyx_v_r8 - __pyx_v_r9)) / 12.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":84 + * + x0**3 * (3 * y0 + y1) / 12 + * ) + * self.momentXY += ( # <<<<<<<<<<<<<< + * -r2 * r8 / 24 + * - r2 * r9 / 8 +*/ + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 84, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentXY, __pyx_t_2) < (0)) __PYX_ERR(0, 84, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":91 + * - x0 * x1 * (r8 - r9) / 12 + * ) + * self.momentYY += ( # <<<<<<<<<<<<<< + * -r0 * r9 / 12 + * - r1 * r8 / 12 +*/ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentYY); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 91, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/pens/momentsPen.py":96 + * - r11 * x1 / 12 + * - r12 * x1 / 12 + * + x0 * (r11 + r12 + r8 * y1 + r9 * y0) / 12 # <<<<<<<<<<<<<< + * ) + * +*/ + __pyx_t_1 = PyFloat_FromDouble((((((((-__pyx_v_r0) * __pyx_v_r9) / 12.0) - ((__pyx_v_r1 * __pyx_v_r8) / 12.0)) - ((__pyx_v_r11 * __pyx_v_x1) / 12.0)) - ((__pyx_v_r12 * __pyx_v_x1) / 12.0)) + ((__pyx_v_x0 * (((__pyx_v_r11 + __pyx_v_r12) + (__pyx_v_r8 * __pyx_v_y1)) + (__pyx_v_r9 * __pyx_v_y0))) / 12.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 96, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":91 + * - x0 * x1 * (r8 - r9) / 12 + * ) + * self.momentYY += ( # <<<<<<<<<<<<<< + * -r0 * r9 / 12 + * - r1 * r8 / 12 +*/ + __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 91, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentYY, __pyx_t_4) < (0)) __PYX_ERR(0, 91, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/pens/momentsPen.py":39 + * raise OpenContourError("Glyph statistics is not defined on open contours.") + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) +*/ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._lineTo", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/pens/momentsPen.py":99 + * ) + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_11_qCurveToOne(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_10_qCurveToOne, "MomentsPen._qCurveToOne(self, p1, p2)"); +static PyMethodDef __pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_11_qCurveToOne = {"_qCurveToOne", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_11_qCurveToOne, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_10_qCurveToOne}; +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_11_qCurveToOne(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_p1 = 0; + PyObject *__pyx_v_p2 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[3] = {0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_qCurveToOne (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_p1,&__pyx_mstate_global->__pyx_n_u_p2,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 99, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 99, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 99, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 99, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_qCurveToOne", 0) < (0)) __PYX_ERR(0, 99, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 3; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_qCurveToOne", 1, 3, 3, i); __PYX_ERR(0, 99, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 3)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 99, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 99, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 99, __pyx_L3_error) + } + __pyx_v_self = values[0]; + __pyx_v_p1 = values[1]; + __pyx_v_p2 = values[2]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_qCurveToOne", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 99, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._qCurveToOne", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_10_qCurveToOne(__pyx_self, __pyx_v_self, __pyx_v_p1, __pyx_v_p2); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_10_qCurveToOne(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_p1, PyObject *__pyx_v_p2) { + double __pyx_v_x2; + double __pyx_v_y2; + double __pyx_v_x1; + double __pyx_v_y1; + double __pyx_v_x0; + double __pyx_v_y0; + double __pyx_v_r53; + double __pyx_v_r52; + double __pyx_v_r51; + double __pyx_v_r50; + double __pyx_v_r49; + double __pyx_v_r48; + double __pyx_v_r47; + double __pyx_v_r46; + double __pyx_v_r45; + double __pyx_v_r44; + double __pyx_v_r43; + double __pyx_v_r42; + double __pyx_v_r41; + double __pyx_v_r40; + double __pyx_v_r39; + double __pyx_v_r38; + double __pyx_v_r37; + double __pyx_v_r36; + double __pyx_v_r35; + double __pyx_v_r34; + double __pyx_v_r33; + double __pyx_v_r32; + double __pyx_v_r31; + double __pyx_v_r30; + double __pyx_v_r29; + double __pyx_v_r28; + double __pyx_v_r27; + double __pyx_v_r26; + double __pyx_v_r25; + double __pyx_v_r24; + double __pyx_v_r23; + double __pyx_v_r22; + double __pyx_v_r21; + double __pyx_v_r20; + double __pyx_v_r19; + double __pyx_v_r18; + double __pyx_v_r17; + double __pyx_v_r16; + double __pyx_v_r15; + double __pyx_v_r14; + double __pyx_v_r13; + double __pyx_v_r12; + double __pyx_v_r11; + double __pyx_v_r10; + double __pyx_v_r9; + double __pyx_v_r8; + double __pyx_v_r7; + double __pyx_v_r6; + double __pyx_v_r5; + double __pyx_v_r4; + double __pyx_v_r3; + double __pyx_v_r2; + double __pyx_v_r1; + double __pyx_v_r0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + size_t __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *(*__pyx_t_6)(PyObject *); + double __pyx_t_7; + double __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_qCurveToOne", 0); + + /* "fontTools/pens/momentsPen.py":157 + * @cython.locals(x2=cython.double, y2=cython.double) + * def _qCurveToOne(self, p1, p2): + * x0, y0 = self._getCurrentPoint() # <<<<<<<<<<<<<< + * x1, y1 = p1 + * x2, y2 = p2 +*/ + __pyx_t_2 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_getCurrentPoint, __pyx_callargs+__pyx_t_3, (1-__pyx_t_3) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 157, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 157, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_4); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 157, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 157, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_4); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 157, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 157, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_5 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 157, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_6 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_5); + index = 0; __pyx_t_2 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_4 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_4)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_5), 2) < (0)) __PYX_ERR(0, 157, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 157, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_t_7 = __Pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 157, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_8 = __Pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 157, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_x0 = __pyx_t_7; + __pyx_v_y0 = __pyx_t_8; + + /* "fontTools/pens/momentsPen.py":158 + * def _qCurveToOne(self, p1, p2): + * x0, y0 = self._getCurrentPoint() + * x1, y1 = p1 # <<<<<<<<<<<<<< + * x2, y2 = p2 + * +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_p1))) || (PyList_CheckExact(__pyx_v_p1))) { + PyObject* sequence = __pyx_v_p1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 158, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_4); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 158, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 158, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_4); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 158, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 158, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_2 = PyObject_GetIter(__pyx_v_p1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 158, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); + index = 0; __pyx_t_1 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_4 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_4)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_2), 2) < (0)) __PYX_ERR(0, 158, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 158, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_t_8 = __Pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 158, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __Pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 158, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_x1 = __pyx_t_8; + __pyx_v_y1 = __pyx_t_7; + + /* "fontTools/pens/momentsPen.py":159 + * x0, y0 = self._getCurrentPoint() + * x1, y1 = p1 + * x2, y2 = p2 # <<<<<<<<<<<<<< + * + * r0 = 2 * y1 +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_p2))) || (PyList_CheckExact(__pyx_v_p2))) { + PyObject* sequence = __pyx_v_p2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 159, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_4); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_4); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_2 = PyObject_GetIter(__pyx_v_p2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); + index = 0; __pyx_t_4 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_4)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + index = 1; __pyx_t_1 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_2), 2) < (0)) __PYX_ERR(0, 159, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 159, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_t_7 = __Pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_8 = __Pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 159, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_x2 = __pyx_t_7; + __pyx_v_y2 = __pyx_t_8; + + /* "fontTools/pens/momentsPen.py":161 + * x2, y2 = p2 + * + * r0 = 2 * y1 # <<<<<<<<<<<<<< + * r1 = r0 * x2 + * r2 = x2 * y2 +*/ + __pyx_v_r0 = (2.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":162 + * + * r0 = 2 * y1 + * r1 = r0 * x2 # <<<<<<<<<<<<<< + * r2 = x2 * y2 + * r3 = 3 * r2 +*/ + __pyx_v_r1 = (__pyx_v_r0 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":163 + * r0 = 2 * y1 + * r1 = r0 * x2 + * r2 = x2 * y2 # <<<<<<<<<<<<<< + * r3 = 3 * r2 + * r4 = 2 * x1 +*/ + __pyx_v_r2 = (__pyx_v_x2 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":164 + * r1 = r0 * x2 + * r2 = x2 * y2 + * r3 = 3 * r2 # <<<<<<<<<<<<<< + * r4 = 2 * x1 + * r5 = 3 * y0 +*/ + __pyx_v_r3 = (3.0 * __pyx_v_r2); + + /* "fontTools/pens/momentsPen.py":165 + * r2 = x2 * y2 + * r3 = 3 * r2 + * r4 = 2 * x1 # <<<<<<<<<<<<<< + * r5 = 3 * y0 + * r6 = x1**2 +*/ + __pyx_v_r4 = (2.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":166 + * r3 = 3 * r2 + * r4 = 2 * x1 + * r5 = 3 * y0 # <<<<<<<<<<<<<< + * r6 = x1**2 + * r7 = x2**2 +*/ + __pyx_v_r5 = (3.0 * __pyx_v_y0); + + /* "fontTools/pens/momentsPen.py":167 + * r4 = 2 * x1 + * r5 = 3 * y0 + * r6 = x1**2 # <<<<<<<<<<<<<< + * r7 = x2**2 + * r8 = 4 * y1 +*/ + __pyx_v_r6 = pow(__pyx_v_x1, 2.0); + + /* "fontTools/pens/momentsPen.py":168 + * r5 = 3 * y0 + * r6 = x1**2 + * r7 = x2**2 # <<<<<<<<<<<<<< + * r8 = 4 * y1 + * r9 = 10 * y2 +*/ + __pyx_v_r7 = pow(__pyx_v_x2, 2.0); + + /* "fontTools/pens/momentsPen.py":169 + * r6 = x1**2 + * r7 = x2**2 + * r8 = 4 * y1 # <<<<<<<<<<<<<< + * r9 = 10 * y2 + * r10 = 2 * y2 +*/ + __pyx_v_r8 = (4.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":170 + * r7 = x2**2 + * r8 = 4 * y1 + * r9 = 10 * y2 # <<<<<<<<<<<<<< + * r10 = 2 * y2 + * r11 = r4 * x2 +*/ + __pyx_v_r9 = (10.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":171 + * r8 = 4 * y1 + * r9 = 10 * y2 + * r10 = 2 * y2 # <<<<<<<<<<<<<< + * r11 = r4 * x2 + * r12 = x0**2 +*/ + __pyx_v_r10 = (2.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":172 + * r9 = 10 * y2 + * r10 = 2 * y2 + * r11 = r4 * x2 # <<<<<<<<<<<<<< + * r12 = x0**2 + * r13 = 10 * y0 +*/ + __pyx_v_r11 = (__pyx_v_r4 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":173 + * r10 = 2 * y2 + * r11 = r4 * x2 + * r12 = x0**2 # <<<<<<<<<<<<<< + * r13 = 10 * y0 + * r14 = r4 * y2 +*/ + __pyx_v_r12 = pow(__pyx_v_x0, 2.0); + + /* "fontTools/pens/momentsPen.py":174 + * r11 = r4 * x2 + * r12 = x0**2 + * r13 = 10 * y0 # <<<<<<<<<<<<<< + * r14 = r4 * y2 + * r15 = x2 * y0 +*/ + __pyx_v_r13 = (10.0 * __pyx_v_y0); + + /* "fontTools/pens/momentsPen.py":175 + * r12 = x0**2 + * r13 = 10 * y0 + * r14 = r4 * y2 # <<<<<<<<<<<<<< + * r15 = x2 * y0 + * r16 = 4 * x1 +*/ + __pyx_v_r14 = (__pyx_v_r4 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":176 + * r13 = 10 * y0 + * r14 = r4 * y2 + * r15 = x2 * y0 # <<<<<<<<<<<<<< + * r16 = 4 * x1 + * r17 = r0 * x1 + r2 +*/ + __pyx_v_r15 = (__pyx_v_x2 * __pyx_v_y0); + + /* "fontTools/pens/momentsPen.py":177 + * r14 = r4 * y2 + * r15 = x2 * y0 + * r16 = 4 * x1 # <<<<<<<<<<<<<< + * r17 = r0 * x1 + r2 + * r18 = r2 * r8 +*/ + __pyx_v_r16 = (4.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":178 + * r15 = x2 * y0 + * r16 = 4 * x1 + * r17 = r0 * x1 + r2 # <<<<<<<<<<<<<< + * r18 = r2 * r8 + * r19 = y1**2 +*/ + __pyx_v_r17 = ((__pyx_v_r0 * __pyx_v_x1) + __pyx_v_r2); + + /* "fontTools/pens/momentsPen.py":179 + * r16 = 4 * x1 + * r17 = r0 * x1 + r2 + * r18 = r2 * r8 # <<<<<<<<<<<<<< + * r19 = y1**2 + * r20 = 2 * r19 +*/ + __pyx_v_r18 = (__pyx_v_r2 * __pyx_v_r8); + + /* "fontTools/pens/momentsPen.py":180 + * r17 = r0 * x1 + r2 + * r18 = r2 * r8 + * r19 = y1**2 # <<<<<<<<<<<<<< + * r20 = 2 * r19 + * r21 = y2**2 +*/ + __pyx_v_r19 = pow(__pyx_v_y1, 2.0); + + /* "fontTools/pens/momentsPen.py":181 + * r18 = r2 * r8 + * r19 = y1**2 + * r20 = 2 * r19 # <<<<<<<<<<<<<< + * r21 = y2**2 + * r22 = r21 * x2 +*/ + __pyx_v_r20 = (2.0 * __pyx_v_r19); + + /* "fontTools/pens/momentsPen.py":182 + * r19 = y1**2 + * r20 = 2 * r19 + * r21 = y2**2 # <<<<<<<<<<<<<< + * r22 = r21 * x2 + * r23 = 5 * r22 +*/ + __pyx_v_r21 = pow(__pyx_v_y2, 2.0); + + /* "fontTools/pens/momentsPen.py":183 + * r20 = 2 * r19 + * r21 = y2**2 + * r22 = r21 * x2 # <<<<<<<<<<<<<< + * r23 = 5 * r22 + * r24 = y0**2 +*/ + __pyx_v_r22 = (__pyx_v_r21 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":184 + * r21 = y2**2 + * r22 = r21 * x2 + * r23 = 5 * r22 # <<<<<<<<<<<<<< + * r24 = y0**2 + * r25 = y0 * y2 +*/ + __pyx_v_r23 = (5.0 * __pyx_v_r22); + + /* "fontTools/pens/momentsPen.py":185 + * r22 = r21 * x2 + * r23 = 5 * r22 + * r24 = y0**2 # <<<<<<<<<<<<<< + * r25 = y0 * y2 + * r26 = 5 * r24 +*/ + __pyx_v_r24 = pow(__pyx_v_y0, 2.0); + + /* "fontTools/pens/momentsPen.py":186 + * r23 = 5 * r22 + * r24 = y0**2 + * r25 = y0 * y2 # <<<<<<<<<<<<<< + * r26 = 5 * r24 + * r27 = x1**3 +*/ + __pyx_v_r25 = (__pyx_v_y0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":187 + * r24 = y0**2 + * r25 = y0 * y2 + * r26 = 5 * r24 # <<<<<<<<<<<<<< + * r27 = x1**3 + * r28 = x2**3 +*/ + __pyx_v_r26 = (5.0 * __pyx_v_r24); + + /* "fontTools/pens/momentsPen.py":188 + * r25 = y0 * y2 + * r26 = 5 * r24 + * r27 = x1**3 # <<<<<<<<<<<<<< + * r28 = x2**3 + * r29 = 30 * y1 +*/ + __pyx_v_r27 = pow(__pyx_v_x1, 3.0); + + /* "fontTools/pens/momentsPen.py":189 + * r26 = 5 * r24 + * r27 = x1**3 + * r28 = x2**3 # <<<<<<<<<<<<<< + * r29 = 30 * y1 + * r30 = 6 * y1 +*/ + __pyx_v_r28 = pow(__pyx_v_x2, 3.0); + + /* "fontTools/pens/momentsPen.py":190 + * r27 = x1**3 + * r28 = x2**3 + * r29 = 30 * y1 # <<<<<<<<<<<<<< + * r30 = 6 * y1 + * r31 = 10 * r7 * x1 +*/ + __pyx_v_r29 = (30.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":191 + * r28 = x2**3 + * r29 = 30 * y1 + * r30 = 6 * y1 # <<<<<<<<<<<<<< + * r31 = 10 * r7 * x1 + * r32 = 5 * y2 +*/ + __pyx_v_r30 = (6.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":192 + * r29 = 30 * y1 + * r30 = 6 * y1 + * r31 = 10 * r7 * x1 # <<<<<<<<<<<<<< + * r32 = 5 * y2 + * r33 = 12 * r6 +*/ + __pyx_v_r31 = ((10.0 * __pyx_v_r7) * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":193 + * r30 = 6 * y1 + * r31 = 10 * r7 * x1 + * r32 = 5 * y2 # <<<<<<<<<<<<<< + * r33 = 12 * r6 + * r34 = 30 * x1 +*/ + __pyx_v_r32 = (5.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":194 + * r31 = 10 * r7 * x1 + * r32 = 5 * y2 + * r33 = 12 * r6 # <<<<<<<<<<<<<< + * r34 = 30 * x1 + * r35 = x1 * y1 +*/ + __pyx_v_r33 = (12.0 * __pyx_v_r6); + + /* "fontTools/pens/momentsPen.py":195 + * r32 = 5 * y2 + * r33 = 12 * r6 + * r34 = 30 * x1 # <<<<<<<<<<<<<< + * r35 = x1 * y1 + * r36 = r3 + 20 * r35 +*/ + __pyx_v_r34 = (30.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":196 + * r33 = 12 * r6 + * r34 = 30 * x1 + * r35 = x1 * y1 # <<<<<<<<<<<<<< + * r36 = r3 + 20 * r35 + * r37 = 12 * x1 +*/ + __pyx_v_r35 = (__pyx_v_x1 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":197 + * r34 = 30 * x1 + * r35 = x1 * y1 + * r36 = r3 + 20 * r35 # <<<<<<<<<<<<<< + * r37 = 12 * x1 + * r38 = 20 * r6 +*/ + __pyx_v_r36 = (__pyx_v_r3 + (20.0 * __pyx_v_r35)); + + /* "fontTools/pens/momentsPen.py":198 + * r35 = x1 * y1 + * r36 = r3 + 20 * r35 + * r37 = 12 * x1 # <<<<<<<<<<<<<< + * r38 = 20 * r6 + * r39 = 8 * r6 * y1 +*/ + __pyx_v_r37 = (12.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":199 + * r36 = r3 + 20 * r35 + * r37 = 12 * x1 + * r38 = 20 * r6 # <<<<<<<<<<<<<< + * r39 = 8 * r6 * y1 + * r40 = r32 * r7 +*/ + __pyx_v_r38 = (20.0 * __pyx_v_r6); + + /* "fontTools/pens/momentsPen.py":200 + * r37 = 12 * x1 + * r38 = 20 * r6 + * r39 = 8 * r6 * y1 # <<<<<<<<<<<<<< + * r40 = r32 * r7 + * r41 = 60 * y1 +*/ + __pyx_v_r39 = ((8.0 * __pyx_v_r6) * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":201 + * r38 = 20 * r6 + * r39 = 8 * r6 * y1 + * r40 = r32 * r7 # <<<<<<<<<<<<<< + * r41 = 60 * y1 + * r42 = 20 * r19 +*/ + __pyx_v_r40 = (__pyx_v_r32 * __pyx_v_r7); + + /* "fontTools/pens/momentsPen.py":202 + * r39 = 8 * r6 * y1 + * r40 = r32 * r7 + * r41 = 60 * y1 # <<<<<<<<<<<<<< + * r42 = 20 * r19 + * r43 = 4 * r19 +*/ + __pyx_v_r41 = (60.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":203 + * r40 = r32 * r7 + * r41 = 60 * y1 + * r42 = 20 * r19 # <<<<<<<<<<<<<< + * r43 = 4 * r19 + * r44 = 15 * r21 +*/ + __pyx_v_r42 = (20.0 * __pyx_v_r19); + + /* "fontTools/pens/momentsPen.py":204 + * r41 = 60 * y1 + * r42 = 20 * r19 + * r43 = 4 * r19 # <<<<<<<<<<<<<< + * r44 = 15 * r21 + * r45 = 12 * x2 +*/ + __pyx_v_r43 = (4.0 * __pyx_v_r19); + + /* "fontTools/pens/momentsPen.py":205 + * r42 = 20 * r19 + * r43 = 4 * r19 + * r44 = 15 * r21 # <<<<<<<<<<<<<< + * r45 = 12 * x2 + * r46 = 12 * y2 +*/ + __pyx_v_r44 = (15.0 * __pyx_v_r21); + + /* "fontTools/pens/momentsPen.py":206 + * r43 = 4 * r19 + * r44 = 15 * r21 + * r45 = 12 * x2 # <<<<<<<<<<<<<< + * r46 = 12 * y2 + * r47 = 6 * x1 +*/ + __pyx_v_r45 = (12.0 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":207 + * r44 = 15 * r21 + * r45 = 12 * x2 + * r46 = 12 * y2 # <<<<<<<<<<<<<< + * r47 = 6 * x1 + * r48 = 8 * r19 * x1 + r23 +*/ + __pyx_v_r46 = (12.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":208 + * r45 = 12 * x2 + * r46 = 12 * y2 + * r47 = 6 * x1 # <<<<<<<<<<<<<< + * r48 = 8 * r19 * x1 + r23 + * r49 = 8 * y1**3 +*/ + __pyx_v_r47 = (6.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":209 + * r46 = 12 * y2 + * r47 = 6 * x1 + * r48 = 8 * r19 * x1 + r23 # <<<<<<<<<<<<<< + * r49 = 8 * y1**3 + * r50 = y2**3 +*/ + __pyx_v_r48 = (((8.0 * __pyx_v_r19) * __pyx_v_x1) + __pyx_v_r23); + + /* "fontTools/pens/momentsPen.py":210 + * r47 = 6 * x1 + * r48 = 8 * r19 * x1 + r23 + * r49 = 8 * y1**3 # <<<<<<<<<<<<<< + * r50 = y2**3 + * r51 = y0**3 +*/ + __pyx_v_r49 = (8.0 * pow(__pyx_v_y1, 3.0)); + + /* "fontTools/pens/momentsPen.py":211 + * r48 = 8 * r19 * x1 + r23 + * r49 = 8 * y1**3 + * r50 = y2**3 # <<<<<<<<<<<<<< + * r51 = y0**3 + * r52 = 10 * y1 +*/ + __pyx_v_r50 = pow(__pyx_v_y2, 3.0); + + /* "fontTools/pens/momentsPen.py":212 + * r49 = 8 * y1**3 + * r50 = y2**3 + * r51 = y0**3 # <<<<<<<<<<<<<< + * r52 = 10 * y1 + * r53 = 12 * y1 +*/ + __pyx_v_r51 = pow(__pyx_v_y0, 3.0); + + /* "fontTools/pens/momentsPen.py":213 + * r50 = y2**3 + * r51 = y0**3 + * r52 = 10 * y1 # <<<<<<<<<<<<<< + * r53 = 12 * y1 + * +*/ + __pyx_v_r52 = (10.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":214 + * r51 = y0**3 + * r52 = 10 * y1 + * r53 = 12 * y1 # <<<<<<<<<<<<<< + * + * self.area += ( +*/ + __pyx_v_r53 = (12.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":216 + * r53 = 12 * y1 + * + * self.area += ( # <<<<<<<<<<<<<< + * -r1 / 6 + * - r3 / 6 +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_area); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 216, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":221 + * + x0 * (r0 + r5 + y2) / 6 + * + x1 * y2 / 3 + * - y0 * (r4 + x2) / 6 # <<<<<<<<<<<<<< + * ) + * self.momentX += ( +*/ + __pyx_t_4 = PyFloat_FromDouble(((((((-__pyx_v_r1) / 6.0) - (__pyx_v_r3 / 6.0)) + ((__pyx_v_x0 * ((__pyx_v_r0 + __pyx_v_r5) + __pyx_v_y2)) / 6.0)) + ((__pyx_v_x1 * __pyx_v_y2) / 3.0)) - ((__pyx_v_y0 * (__pyx_v_r4 + __pyx_v_x2)) / 6.0))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 221, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + + /* "fontTools/pens/momentsPen.py":216 + * r53 = 12 * y1 + * + * self.area += ( # <<<<<<<<<<<<<< + * -r1 / 6 + * - r3 / 6 +*/ + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 216, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_area, __pyx_t_2) < (0)) __PYX_ERR(0, 216, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":223 + * - y0 * (r4 + x2) / 6 + * ) + * self.momentX += ( # <<<<<<<<<<<<<< + * -r11 * (-r10 + y1) / 30 + * + r12 * (r13 + r8 + y2) / 30 +*/ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentX); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 223, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/pens/momentsPen.py":230 + * - r7 * r9 / 30 + * + x0 * (r14 - r15 - r16 * y0 + r17) / 30 + * - y0 * (r11 + 2 * r6 + r7) / 30 # <<<<<<<<<<<<<< + * ) + * self.momentY += ( +*/ + __pyx_t_4 = PyFloat_FromDouble((((((((((-__pyx_v_r11) * ((-__pyx_v_r10) + __pyx_v_y1)) / 30.0) + ((__pyx_v_r12 * ((__pyx_v_r13 + __pyx_v_r8) + __pyx_v_y2)) / 30.0)) + ((__pyx_v_r6 * __pyx_v_y2) / 15.0)) - ((__pyx_v_r7 * __pyx_v_r8) / 30.0)) - ((__pyx_v_r7 * __pyx_v_r9) / 30.0)) + ((__pyx_v_x0 * (((__pyx_v_r14 - __pyx_v_r15) - (__pyx_v_r16 * __pyx_v_y0)) + __pyx_v_r17)) / 30.0)) - ((__pyx_v_y0 * ((__pyx_v_r11 + (2.0 * __pyx_v_r6)) + __pyx_v_r7)) / 30.0))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 230, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + + /* "fontTools/pens/momentsPen.py":223 + * - y0 * (r4 + x2) / 6 + * ) + * self.momentX += ( # <<<<<<<<<<<<<< + * -r11 * (-r10 + y1) / 30 + * + r12 * (r13 + r8 + y2) / 30 +*/ + __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 223, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentX, __pyx_t_1) < (0)) __PYX_ERR(0, 223, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/pens/momentsPen.py":232 + * - y0 * (r11 + 2 * r6 + r7) / 30 + * ) + * self.momentY += ( # <<<<<<<<<<<<<< + * -r18 / 30 + * - r20 * x2 / 30 +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentY); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":239 + * + x0 * (r0 * y2 + r20 + r21 + r25 + r26 + r8 * y0) / 30 + * + x1 * y2 * (r10 + y1) / 15 + * - y0 * (r1 + r17) / 30 # <<<<<<<<<<<<<< + * ) + * self.momentXX += ( +*/ + __pyx_t_4 = PyFloat_FromDouble(((((((((-__pyx_v_r18) / 30.0) - ((__pyx_v_r20 * __pyx_v_x2) / 30.0)) - (__pyx_v_r23 / 30.0)) - ((__pyx_v_r24 * (__pyx_v_r16 + __pyx_v_x2)) / 30.0)) + ((__pyx_v_x0 * ((((((__pyx_v_r0 * __pyx_v_y2) + __pyx_v_r20) + __pyx_v_r21) + __pyx_v_r25) + __pyx_v_r26) + (__pyx_v_r8 * __pyx_v_y0))) / 30.0)) + (((__pyx_v_x1 * __pyx_v_y2) * (__pyx_v_r10 + __pyx_v_y1)) / 15.0)) - ((__pyx_v_y0 * (__pyx_v_r1 + __pyx_v_r17)) / 30.0))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + + /* "fontTools/pens/momentsPen.py":232 + * - y0 * (r11 + 2 * r6 + r7) / 30 + * ) + * self.momentY += ( # <<<<<<<<<<<<<< + * -r18 / 30 + * - r20 * x2 / 30 +*/ + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentY, __pyx_t_2) < (0)) __PYX_ERR(0, 232, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":241 + * - y0 * (r1 + r17) / 30 + * ) + * self.momentXX += ( # <<<<<<<<<<<<<< + * r12 * (r1 - 5 * r15 - r34 * y0 + r36 + r9 * x1) / 420 + * + 2 * r27 * y2 / 105 +*/ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentXX); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 241, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/pens/momentsPen.py":261 + * ) + * / 420 + * - y0 * (8 * r27 + 5 * r28 + r31 + r33 * x2) / 420 # <<<<<<<<<<<<<< + * ) + * self.momentXY += ( +*/ + __pyx_t_4 = PyFloat_FromDouble(((((((((((__pyx_v_r12 * ((((__pyx_v_r1 - (5.0 * __pyx_v_r15)) - (__pyx_v_r34 * __pyx_v_y0)) + __pyx_v_r36) + (__pyx_v_r9 * __pyx_v_x1))) / 420.0) + (((2.0 * __pyx_v_r27) * __pyx_v_y2) / 105.0)) - ((__pyx_v_r28 * __pyx_v_r29) / 420.0)) - ((__pyx_v_r28 * __pyx_v_y2) / 4.0)) - ((__pyx_v_r31 * (__pyx_v_r0 - (3.0 * __pyx_v_y2))) / 420.0)) - (((__pyx_v_r6 * __pyx_v_x2) * (__pyx_v_r0 - __pyx_v_r32)) / 105.0)) + ((pow(__pyx_v_x0, 3.0) * ((__pyx_v_r30 + (21.0 * __pyx_v_y0)) + __pyx_v_y2)) / 84.0)) - ((__pyx_v_x0 * ((((((((__pyx_v_r0 * __pyx_v_r7) + (__pyx_v_r15 * __pyx_v_r37)) - (__pyx_v_r2 * __pyx_v_r37)) - (__pyx_v_r33 * __pyx_v_y2)) + (__pyx_v_r38 * __pyx_v_y0)) - __pyx_v_r39) - __pyx_v_r40) + (__pyx_v_r5 * __pyx_v_r7))) / 420.0)) - ((__pyx_v_y0 * ((((8.0 * __pyx_v_r27) + (5.0 * __pyx_v_r28)) + __pyx_v_r31) + (__pyx_v_r33 * __pyx_v_x2))) / 420.0))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 261, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + + /* "fontTools/pens/momentsPen.py":241 + * - y0 * (r1 + r17) / 30 + * ) + * self.momentXX += ( # <<<<<<<<<<<<<< + * r12 * (r1 - 5 * r15 - r34 * y0 + r36 + r9 * x1) / 420 + * + 2 * r27 * y2 / 105 +*/ + __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 241, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentXX, __pyx_t_1) < (0)) __PYX_ERR(0, 241, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/pens/momentsPen.py":263 + * - y0 * (8 * r27 + 5 * r28 + r31 + r33 * x2) / 420 + * ) + * self.momentXY += ( # <<<<<<<<<<<<<< + * r12 * (r13 * y2 + 3 * r21 + 105 * r24 + r41 * y0 + r42 + r46 * y1) / 840 + * - r16 * x2 * (r43 - r44) / 840 +*/ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentXY); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 263, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":283 + * ) + * / 420 + * - y0 * (r16 * r2 + r30 * r7 + r35 * r45 + r39 + r40) / 420 # <<<<<<<<<<<<<< + * ) + * self.momentYY += ( +*/ + __pyx_t_4 = PyFloat_FromDouble(((((((((((__pyx_v_r12 * ((((((__pyx_v_r13 * __pyx_v_y2) + (3.0 * __pyx_v_r21)) + (105.0 * __pyx_v_r24)) + (__pyx_v_r41 * __pyx_v_y0)) + __pyx_v_r42) + (__pyx_v_r46 * __pyx_v_y1))) / 840.0) - (((__pyx_v_r16 * __pyx_v_x2) * (__pyx_v_r43 - __pyx_v_r44)) / 840.0)) - ((__pyx_v_r21 * __pyx_v_r7) / 8.0)) - ((__pyx_v_r24 * ((__pyx_v_r38 + (__pyx_v_r45 * __pyx_v_x1)) + (3.0 * __pyx_v_r7))) / 840.0)) - (((__pyx_v_r41 * __pyx_v_r7) * __pyx_v_y2) / 840.0)) - ((__pyx_v_r42 * __pyx_v_r7) / 840.0)) + (((__pyx_v_r6 * __pyx_v_y2) * (__pyx_v_r32 + __pyx_v_r8)) / 210.0)) + ((__pyx_v_x0 * (((((((((-__pyx_v_r15) * __pyx_v_r8) + (__pyx_v_r16 * __pyx_v_r25)) + __pyx_v_r18) + (__pyx_v_r21 * __pyx_v_r47)) - (__pyx_v_r24 * __pyx_v_r34)) - (__pyx_v_r26 * __pyx_v_x2)) + (__pyx_v_r35 * __pyx_v_r46)) + __pyx_v_r48)) / 420.0)) - ((__pyx_v_y0 * (((((__pyx_v_r16 * __pyx_v_r2) + (__pyx_v_r30 * __pyx_v_r7)) + (__pyx_v_r35 * __pyx_v_r45)) + __pyx_v_r39) + __pyx_v_r40)) / 420.0))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 283, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + + /* "fontTools/pens/momentsPen.py":263 + * - y0 * (8 * r27 + 5 * r28 + r31 + r33 * x2) / 420 + * ) + * self.momentXY += ( # <<<<<<<<<<<<<< + * r12 * (r13 * y2 + 3 * r21 + 105 * r24 + r41 * y0 + r42 + r46 * y1) / 840 + * - r16 * x2 * (r43 - r44) / 840 +*/ + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 263, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentXY, __pyx_t_2) < (0)) __PYX_ERR(0, 263, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":285 + * - y0 * (r16 * r2 + r30 * r7 + r35 * r45 + r39 + r40) / 420 + * ) + * self.momentYY += ( # <<<<<<<<<<<<<< + * -r2 * r42 / 420 + * - r22 * r29 / 420 +*/ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentYY); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 285, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/pens/momentsPen.py":307 + * / 420 + * + x1 * y2 * (r43 + r44 + r9 * y1) / 210 + * - y0 * (r19 * r45 + r2 * r53 - r21 * r4 + r48) / 420 # <<<<<<<<<<<<<< + * ) + * +*/ + __pyx_t_4 = PyFloat_FromDouble((((((((((((-__pyx_v_r2) * __pyx_v_r42) / 420.0) - ((__pyx_v_r22 * __pyx_v_r29) / 420.0)) - ((__pyx_v_r24 * ((__pyx_v_r14 + __pyx_v_r36) + (__pyx_v_r52 * __pyx_v_x2))) / 420.0)) - ((__pyx_v_r49 * __pyx_v_x2) / 420.0)) - ((__pyx_v_r50 * __pyx_v_x2) / 12.0)) - ((__pyx_v_r51 * (__pyx_v_r47 + __pyx_v_x2)) / 84.0)) + ((__pyx_v_x0 * ((((((((((__pyx_v_r19 * __pyx_v_r46) + (__pyx_v_r21 * __pyx_v_r5)) + (__pyx_v_r21 * __pyx_v_r52)) + (__pyx_v_r24 * __pyx_v_r29)) + (__pyx_v_r25 * __pyx_v_r53)) + (__pyx_v_r26 * __pyx_v_y2)) + (__pyx_v_r42 * __pyx_v_y0)) + __pyx_v_r49) + (5.0 * __pyx_v_r50)) + (35.0 * __pyx_v_r51))) / 420.0)) + (((__pyx_v_x1 * __pyx_v_y2) * ((__pyx_v_r43 + __pyx_v_r44) + (__pyx_v_r9 * __pyx_v_y1))) / 210.0)) - ((__pyx_v_y0 * ((((__pyx_v_r19 * __pyx_v_r45) + (__pyx_v_r2 * __pyx_v_r53)) - (__pyx_v_r21 * __pyx_v_r4)) + __pyx_v_r48)) / 420.0))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 307, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + + /* "fontTools/pens/momentsPen.py":285 + * - y0 * (r16 * r2 + r30 * r7 + r35 * r45 + r39 + r40) / 420 + * ) + * self.momentYY += ( # <<<<<<<<<<<<<< + * -r2 * r42 / 420 + * - r22 * r29 / 420 +*/ + __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 285, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentYY, __pyx_t_1) < (0)) __PYX_ERR(0, 285, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "fontTools/pens/momentsPen.py":99 + * ) + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) +*/ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._qCurveToOne", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "fontTools/pens/momentsPen.py":310 + * ) + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_13_curveToOne(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_12_curveToOne, "MomentsPen._curveToOne(self, p1, p2, p3)"); +static PyMethodDef __pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_13_curveToOne = {"_curveToOne", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_13_curveToOne, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_9fontTools_4pens_10momentsPen_10MomentsPen_12_curveToOne}; +static PyObject *__pyx_pw_9fontTools_4pens_10momentsPen_10MomentsPen_13_curveToOne(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_p1 = 0; + PyObject *__pyx_v_p2 = 0; + PyObject *__pyx_v_p3 = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_curveToOne (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_p1,&__pyx_mstate_global->__pyx_n_u_p2,&__pyx_mstate_global->__pyx_n_u_p3,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len) < 0) __PYX_ERR(0, 310, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 310, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 310, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 310, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 310, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "_curveToOne", 0) < (0)) __PYX_ERR(0, 310, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("_curveToOne", 1, 4, 4, i); __PYX_ERR(0, 310, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 310, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 310, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 310, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 310, __pyx_L3_error) + } + __pyx_v_self = values[0]; + __pyx_v_p1 = values[1]; + __pyx_v_p2 = values[2]; + __pyx_v_p3 = values[3]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_curveToOne", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 310, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._curveToOne", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_12_curveToOne(__pyx_self, __pyx_v_self, __pyx_v_p1, __pyx_v_p2, __pyx_v_p3); + + /* function exit code */ + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_9fontTools_4pens_10momentsPen_10MomentsPen_12_curveToOne(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_p1, PyObject *__pyx_v_p2, PyObject *__pyx_v_p3) { + double __pyx_v_x3; + double __pyx_v_y3; + double __pyx_v_x2; + double __pyx_v_y2; + double __pyx_v_x1; + double __pyx_v_y1; + double __pyx_v_x0; + double __pyx_v_y0; + double __pyx_v_r132; + double __pyx_v_r131; + double __pyx_v_r130; + double __pyx_v_r129; + double __pyx_v_r128; + double __pyx_v_r127; + double __pyx_v_r126; + double __pyx_v_r125; + double __pyx_v_r124; + double __pyx_v_r123; + double __pyx_v_r122; + double __pyx_v_r121; + double __pyx_v_r120; + double __pyx_v_r119; + double __pyx_v_r118; + double __pyx_v_r117; + double __pyx_v_r116; + double __pyx_v_r115; + double __pyx_v_r114; + double __pyx_v_r113; + double __pyx_v_r112; + double __pyx_v_r111; + double __pyx_v_r110; + double __pyx_v_r109; + double __pyx_v_r108; + double __pyx_v_r107; + double __pyx_v_r106; + double __pyx_v_r105; + double __pyx_v_r104; + double __pyx_v_r103; + double __pyx_v_r102; + double __pyx_v_r101; + double __pyx_v_r100; + double __pyx_v_r99; + double __pyx_v_r98; + double __pyx_v_r97; + double __pyx_v_r96; + double __pyx_v_r95; + double __pyx_v_r94; + double __pyx_v_r93; + double __pyx_v_r92; + double __pyx_v_r91; + double __pyx_v_r90; + double __pyx_v_r89; + double __pyx_v_r88; + double __pyx_v_r87; + double __pyx_v_r86; + double __pyx_v_r85; + double __pyx_v_r84; + double __pyx_v_r83; + double __pyx_v_r82; + double __pyx_v_r81; + double __pyx_v_r80; + double __pyx_v_r79; + double __pyx_v_r78; + double __pyx_v_r77; + double __pyx_v_r76; + double __pyx_v_r75; + double __pyx_v_r74; + double __pyx_v_r73; + double __pyx_v_r72; + double __pyx_v_r71; + double __pyx_v_r70; + double __pyx_v_r69; + double __pyx_v_r68; + double __pyx_v_r67; + double __pyx_v_r66; + double __pyx_v_r65; + double __pyx_v_r64; + double __pyx_v_r63; + double __pyx_v_r62; + double __pyx_v_r61; + double __pyx_v_r60; + double __pyx_v_r59; + double __pyx_v_r58; + double __pyx_v_r57; + double __pyx_v_r56; + double __pyx_v_r55; + double __pyx_v_r54; + double __pyx_v_r53; + double __pyx_v_r52; + double __pyx_v_r51; + double __pyx_v_r50; + double __pyx_v_r49; + double __pyx_v_r48; + double __pyx_v_r47; + double __pyx_v_r46; + double __pyx_v_r45; + double __pyx_v_r44; + double __pyx_v_r43; + double __pyx_v_r42; + double __pyx_v_r41; + double __pyx_v_r40; + double __pyx_v_r39; + double __pyx_v_r38; + double __pyx_v_r37; + double __pyx_v_r36; + double __pyx_v_r35; + double __pyx_v_r34; + double __pyx_v_r33; + double __pyx_v_r32; + double __pyx_v_r31; + double __pyx_v_r30; + double __pyx_v_r29; + double __pyx_v_r28; + double __pyx_v_r27; + double __pyx_v_r26; + double __pyx_v_r25; + double __pyx_v_r24; + double __pyx_v_r23; + double __pyx_v_r22; + double __pyx_v_r21; + double __pyx_v_r20; + double __pyx_v_r19; + double __pyx_v_r18; + double __pyx_v_r17; + double __pyx_v_r16; + double __pyx_v_r15; + double __pyx_v_r14; + double __pyx_v_r13; + double __pyx_v_r12; + double __pyx_v_r11; + double __pyx_v_r10; + double __pyx_v_r9; + double __pyx_v_r8; + double __pyx_v_r7; + double __pyx_v_r6; + double __pyx_v_r5; + double __pyx_v_r4; + double __pyx_v_r3; + double __pyx_v_r2; + double __pyx_v_r1; + double __pyx_v_r0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + size_t __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *(*__pyx_t_6)(PyObject *); + double __pyx_t_7; + double __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_curveToOne", 0); + + /* "fontTools/pens/momentsPen.py":448 + * @cython.locals(x3=cython.double, y3=cython.double) + * def _curveToOne(self, p1, p2, p3): + * x0, y0 = self._getCurrentPoint() # <<<<<<<<<<<<<< + * x1, y1 = p1 + * x2, y2 = p2 +*/ + __pyx_t_2 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_2, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_getCurrentPoint, __pyx_callargs+__pyx_t_3, (1-__pyx_t_3) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 448, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 448, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_4); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 448, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 448, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_4); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 448, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 448, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_5 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 448, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_6 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_5); + index = 0; __pyx_t_2 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_4 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_4)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_5), 2) < (0)) __PYX_ERR(0, 448, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 448, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_t_7 = __Pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 448, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_8 = __Pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 448, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_x0 = __pyx_t_7; + __pyx_v_y0 = __pyx_t_8; + + /* "fontTools/pens/momentsPen.py":449 + * def _curveToOne(self, p1, p2, p3): + * x0, y0 = self._getCurrentPoint() + * x1, y1 = p1 # <<<<<<<<<<<<<< + * x2, y2 = p2 + * x3, y3 = p3 +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_p1))) || (PyList_CheckExact(__pyx_v_p1))) { + PyObject* sequence = __pyx_v_p1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 449, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_4); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 449, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 449, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_4); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 449, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 449, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_2 = PyObject_GetIter(__pyx_v_p1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 449, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); + index = 0; __pyx_t_1 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_4 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_4)) goto __pyx_L5_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_2), 2) < (0)) __PYX_ERR(0, 449, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + goto __pyx_L6_unpacking_done; + __pyx_L5_unpacking_failed:; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 449, __pyx_L1_error) + __pyx_L6_unpacking_done:; + } + __pyx_t_8 = __Pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 449, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __Pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 449, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_x1 = __pyx_t_8; + __pyx_v_y1 = __pyx_t_7; + + /* "fontTools/pens/momentsPen.py":450 + * x0, y0 = self._getCurrentPoint() + * x1, y1 = p1 + * x2, y2 = p2 # <<<<<<<<<<<<<< + * x3, y3 = p3 + * +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_p2))) || (PyList_CheckExact(__pyx_v_p2))) { + PyObject* sequence = __pyx_v_p2; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 450, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_4); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_1); + } else { + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_4); + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + } + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_2 = PyObject_GetIter(__pyx_v_p2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); + index = 0; __pyx_t_4 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_4)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + index = 1; __pyx_t_1 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_1)) goto __pyx_L7_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_2), 2) < (0)) __PYX_ERR(0, 450, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + goto __pyx_L8_unpacking_done; + __pyx_L7_unpacking_failed:; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 450, __pyx_L1_error) + __pyx_L8_unpacking_done:; + } + __pyx_t_7 = __Pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_8 = __Pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 450, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_x2 = __pyx_t_7; + __pyx_v_y2 = __pyx_t_8; + + /* "fontTools/pens/momentsPen.py":451 + * x1, y1 = p1 + * x2, y2 = p2 + * x3, y3 = p3 # <<<<<<<<<<<<<< + * + * r0 = 6 * y2 +*/ + if ((likely(PyTuple_CheckExact(__pyx_v_p3))) || (PyList_CheckExact(__pyx_v_p3))) { + PyObject* sequence = __pyx_v_p3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 451, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_4); + } else { + __pyx_t_1 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 451, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 451, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_4); + } + #else + __pyx_t_1 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 451, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 451, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_2 = PyObject_GetIter(__pyx_v_p3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 451, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); + index = 0; __pyx_t_1 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_1)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_4 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_4)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_2), 2) < (0)) __PYX_ERR(0, 451, __pyx_L1_error) + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + goto __pyx_L10_unpacking_done; + __pyx_L9_unpacking_failed:; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 451, __pyx_L1_error) + __pyx_L10_unpacking_done:; + } + __pyx_t_8 = __Pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_8 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 451, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = __Pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 451, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_x3 = __pyx_t_8; + __pyx_v_y3 = __pyx_t_7; + + /* "fontTools/pens/momentsPen.py":453 + * x3, y3 = p3 + * + * r0 = 6 * y2 # <<<<<<<<<<<<<< + * r1 = r0 * x3 + * r2 = 10 * y3 +*/ + __pyx_v_r0 = (6.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":454 + * + * r0 = 6 * y2 + * r1 = r0 * x3 # <<<<<<<<<<<<<< + * r2 = 10 * y3 + * r3 = r2 * x3 +*/ + __pyx_v_r1 = (__pyx_v_r0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":455 + * r0 = 6 * y2 + * r1 = r0 * x3 + * r2 = 10 * y3 # <<<<<<<<<<<<<< + * r3 = r2 * x3 + * r4 = 3 * y1 +*/ + __pyx_v_r2 = (10.0 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":456 + * r1 = r0 * x3 + * r2 = 10 * y3 + * r3 = r2 * x3 # <<<<<<<<<<<<<< + * r4 = 3 * y1 + * r5 = 6 * x1 +*/ + __pyx_v_r3 = (__pyx_v_r2 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":457 + * r2 = 10 * y3 + * r3 = r2 * x3 + * r4 = 3 * y1 # <<<<<<<<<<<<<< + * r5 = 6 * x1 + * r6 = 3 * x2 +*/ + __pyx_v_r4 = (3.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":458 + * r3 = r2 * x3 + * r4 = 3 * y1 + * r5 = 6 * x1 # <<<<<<<<<<<<<< + * r6 = 3 * x2 + * r7 = 6 * y1 +*/ + __pyx_v_r5 = (6.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":459 + * r4 = 3 * y1 + * r5 = 6 * x1 + * r6 = 3 * x2 # <<<<<<<<<<<<<< + * r7 = 6 * y1 + * r8 = 3 * y2 +*/ + __pyx_v_r6 = (3.0 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":460 + * r5 = 6 * x1 + * r6 = 3 * x2 + * r7 = 6 * y1 # <<<<<<<<<<<<<< + * r8 = 3 * y2 + * r9 = x2**2 +*/ + __pyx_v_r7 = (6.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":461 + * r6 = 3 * x2 + * r7 = 6 * y1 + * r8 = 3 * y2 # <<<<<<<<<<<<<< + * r9 = x2**2 + * r10 = 45 * r9 +*/ + __pyx_v_r8 = (3.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":462 + * r7 = 6 * y1 + * r8 = 3 * y2 + * r9 = x2**2 # <<<<<<<<<<<<<< + * r10 = 45 * r9 + * r11 = r10 * y3 +*/ + __pyx_v_r9 = pow(__pyx_v_x2, 2.0); + + /* "fontTools/pens/momentsPen.py":463 + * r8 = 3 * y2 + * r9 = x2**2 + * r10 = 45 * r9 # <<<<<<<<<<<<<< + * r11 = r10 * y3 + * r12 = x3**2 +*/ + __pyx_v_r10 = (45.0 * __pyx_v_r9); + + /* "fontTools/pens/momentsPen.py":464 + * r9 = x2**2 + * r10 = 45 * r9 + * r11 = r10 * y3 # <<<<<<<<<<<<<< + * r12 = x3**2 + * r13 = r12 * y2 +*/ + __pyx_v_r11 = (__pyx_v_r10 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":465 + * r10 = 45 * r9 + * r11 = r10 * y3 + * r12 = x3**2 # <<<<<<<<<<<<<< + * r13 = r12 * y2 + * r14 = r12 * y3 +*/ + __pyx_v_r12 = pow(__pyx_v_x3, 2.0); + + /* "fontTools/pens/momentsPen.py":466 + * r11 = r10 * y3 + * r12 = x3**2 + * r13 = r12 * y2 # <<<<<<<<<<<<<< + * r14 = r12 * y3 + * r15 = 7 * y3 +*/ + __pyx_v_r13 = (__pyx_v_r12 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":467 + * r12 = x3**2 + * r13 = r12 * y2 + * r14 = r12 * y3 # <<<<<<<<<<<<<< + * r15 = 7 * y3 + * r16 = 15 * x3 +*/ + __pyx_v_r14 = (__pyx_v_r12 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":468 + * r13 = r12 * y2 + * r14 = r12 * y3 + * r15 = 7 * y3 # <<<<<<<<<<<<<< + * r16 = 15 * x3 + * r17 = r16 * x2 +*/ + __pyx_v_r15 = (7.0 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":469 + * r14 = r12 * y3 + * r15 = 7 * y3 + * r16 = 15 * x3 # <<<<<<<<<<<<<< + * r17 = r16 * x2 + * r18 = x1**2 +*/ + __pyx_v_r16 = (15.0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":470 + * r15 = 7 * y3 + * r16 = 15 * x3 + * r17 = r16 * x2 # <<<<<<<<<<<<<< + * r18 = x1**2 + * r19 = 9 * r18 +*/ + __pyx_v_r17 = (__pyx_v_r16 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":471 + * r16 = 15 * x3 + * r17 = r16 * x2 + * r18 = x1**2 # <<<<<<<<<<<<<< + * r19 = 9 * r18 + * r20 = x0**2 +*/ + __pyx_v_r18 = pow(__pyx_v_x1, 2.0); + + /* "fontTools/pens/momentsPen.py":472 + * r17 = r16 * x2 + * r18 = x1**2 + * r19 = 9 * r18 # <<<<<<<<<<<<<< + * r20 = x0**2 + * r21 = 21 * y1 +*/ + __pyx_v_r19 = (9.0 * __pyx_v_r18); + + /* "fontTools/pens/momentsPen.py":473 + * r18 = x1**2 + * r19 = 9 * r18 + * r20 = x0**2 # <<<<<<<<<<<<<< + * r21 = 21 * y1 + * r22 = 9 * r9 +*/ + __pyx_v_r20 = pow(__pyx_v_x0, 2.0); + + /* "fontTools/pens/momentsPen.py":474 + * r19 = 9 * r18 + * r20 = x0**2 + * r21 = 21 * y1 # <<<<<<<<<<<<<< + * r22 = 9 * r9 + * r23 = r7 * x3 +*/ + __pyx_v_r21 = (21.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":475 + * r20 = x0**2 + * r21 = 21 * y1 + * r22 = 9 * r9 # <<<<<<<<<<<<<< + * r23 = r7 * x3 + * r24 = 9 * y2 +*/ + __pyx_v_r22 = (9.0 * __pyx_v_r9); + + /* "fontTools/pens/momentsPen.py":476 + * r21 = 21 * y1 + * r22 = 9 * r9 + * r23 = r7 * x3 # <<<<<<<<<<<<<< + * r24 = 9 * y2 + * r25 = r24 * x2 + r3 +*/ + __pyx_v_r23 = (__pyx_v_r7 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":477 + * r22 = 9 * r9 + * r23 = r7 * x3 + * r24 = 9 * y2 # <<<<<<<<<<<<<< + * r25 = r24 * x2 + r3 + * r26 = 9 * x2 +*/ + __pyx_v_r24 = (9.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":478 + * r23 = r7 * x3 + * r24 = 9 * y2 + * r25 = r24 * x2 + r3 # <<<<<<<<<<<<<< + * r26 = 9 * x2 + * r27 = x2 * y3 +*/ + __pyx_v_r25 = ((__pyx_v_r24 * __pyx_v_x2) + __pyx_v_r3); + + /* "fontTools/pens/momentsPen.py":479 + * r24 = 9 * y2 + * r25 = r24 * x2 + r3 + * r26 = 9 * x2 # <<<<<<<<<<<<<< + * r27 = x2 * y3 + * r28 = -r26 * y1 + 15 * r27 +*/ + __pyx_v_r26 = (9.0 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":480 + * r25 = r24 * x2 + r3 + * r26 = 9 * x2 + * r27 = x2 * y3 # <<<<<<<<<<<<<< + * r28 = -r26 * y1 + 15 * r27 + * r29 = 3 * x1 +*/ + __pyx_v_r27 = (__pyx_v_x2 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":481 + * r26 = 9 * x2 + * r27 = x2 * y3 + * r28 = -r26 * y1 + 15 * r27 # <<<<<<<<<<<<<< + * r29 = 3 * x1 + * r30 = 45 * x1 +*/ + __pyx_v_r28 = (((-__pyx_v_r26) * __pyx_v_y1) + (15.0 * __pyx_v_r27)); + + /* "fontTools/pens/momentsPen.py":482 + * r27 = x2 * y3 + * r28 = -r26 * y1 + 15 * r27 + * r29 = 3 * x1 # <<<<<<<<<<<<<< + * r30 = 45 * x1 + * r31 = 12 * x3 +*/ + __pyx_v_r29 = (3.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":483 + * r28 = -r26 * y1 + 15 * r27 + * r29 = 3 * x1 + * r30 = 45 * x1 # <<<<<<<<<<<<<< + * r31 = 12 * x3 + * r32 = 45 * r18 +*/ + __pyx_v_r30 = (45.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":484 + * r29 = 3 * x1 + * r30 = 45 * x1 + * r31 = 12 * x3 # <<<<<<<<<<<<<< + * r32 = 45 * r18 + * r33 = 5 * r12 +*/ + __pyx_v_r31 = (12.0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":485 + * r30 = 45 * x1 + * r31 = 12 * x3 + * r32 = 45 * r18 # <<<<<<<<<<<<<< + * r33 = 5 * r12 + * r34 = r8 * x3 +*/ + __pyx_v_r32 = (45.0 * __pyx_v_r18); + + /* "fontTools/pens/momentsPen.py":486 + * r31 = 12 * x3 + * r32 = 45 * r18 + * r33 = 5 * r12 # <<<<<<<<<<<<<< + * r34 = r8 * x3 + * r35 = 105 * y0 +*/ + __pyx_v_r33 = (5.0 * __pyx_v_r12); + + /* "fontTools/pens/momentsPen.py":487 + * r32 = 45 * r18 + * r33 = 5 * r12 + * r34 = r8 * x3 # <<<<<<<<<<<<<< + * r35 = 105 * y0 + * r36 = 30 * y0 +*/ + __pyx_v_r34 = (__pyx_v_r8 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":488 + * r33 = 5 * r12 + * r34 = r8 * x3 + * r35 = 105 * y0 # <<<<<<<<<<<<<< + * r36 = 30 * y0 + * r37 = r36 * x2 +*/ + __pyx_v_r35 = (105.0 * __pyx_v_y0); + + /* "fontTools/pens/momentsPen.py":489 + * r34 = r8 * x3 + * r35 = 105 * y0 + * r36 = 30 * y0 # <<<<<<<<<<<<<< + * r37 = r36 * x2 + * r38 = 5 * x3 +*/ + __pyx_v_r36 = (30.0 * __pyx_v_y0); + + /* "fontTools/pens/momentsPen.py":490 + * r35 = 105 * y0 + * r36 = 30 * y0 + * r37 = r36 * x2 # <<<<<<<<<<<<<< + * r38 = 5 * x3 + * r39 = 15 * y3 +*/ + __pyx_v_r37 = (__pyx_v_r36 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":491 + * r36 = 30 * y0 + * r37 = r36 * x2 + * r38 = 5 * x3 # <<<<<<<<<<<<<< + * r39 = 15 * y3 + * r40 = 5 * y3 +*/ + __pyx_v_r38 = (5.0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":492 + * r37 = r36 * x2 + * r38 = 5 * x3 + * r39 = 15 * y3 # <<<<<<<<<<<<<< + * r40 = 5 * y3 + * r41 = r40 * x3 +*/ + __pyx_v_r39 = (15.0 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":493 + * r38 = 5 * x3 + * r39 = 15 * y3 + * r40 = 5 * y3 # <<<<<<<<<<<<<< + * r41 = r40 * x3 + * r42 = x2 * y2 +*/ + __pyx_v_r40 = (5.0 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":494 + * r39 = 15 * y3 + * r40 = 5 * y3 + * r41 = r40 * x3 # <<<<<<<<<<<<<< + * r42 = x2 * y2 + * r43 = 18 * r42 +*/ + __pyx_v_r41 = (__pyx_v_r40 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":495 + * r40 = 5 * y3 + * r41 = r40 * x3 + * r42 = x2 * y2 # <<<<<<<<<<<<<< + * r43 = 18 * r42 + * r44 = 45 * y1 +*/ + __pyx_v_r42 = (__pyx_v_x2 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":496 + * r41 = r40 * x3 + * r42 = x2 * y2 + * r43 = 18 * r42 # <<<<<<<<<<<<<< + * r44 = 45 * y1 + * r45 = r41 + r43 + r44 * x1 +*/ + __pyx_v_r43 = (18.0 * __pyx_v_r42); + + /* "fontTools/pens/momentsPen.py":497 + * r42 = x2 * y2 + * r43 = 18 * r42 + * r44 = 45 * y1 # <<<<<<<<<<<<<< + * r45 = r41 + r43 + r44 * x1 + * r46 = y2 * y3 +*/ + __pyx_v_r44 = (45.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":498 + * r43 = 18 * r42 + * r44 = 45 * y1 + * r45 = r41 + r43 + r44 * x1 # <<<<<<<<<<<<<< + * r46 = y2 * y3 + * r47 = r46 * x3 +*/ + __pyx_v_r45 = ((__pyx_v_r41 + __pyx_v_r43) + (__pyx_v_r44 * __pyx_v_x1)); + + /* "fontTools/pens/momentsPen.py":499 + * r44 = 45 * y1 + * r45 = r41 + r43 + r44 * x1 + * r46 = y2 * y3 # <<<<<<<<<<<<<< + * r47 = r46 * x3 + * r48 = y2**2 +*/ + __pyx_v_r46 = (__pyx_v_y2 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":500 + * r45 = r41 + r43 + r44 * x1 + * r46 = y2 * y3 + * r47 = r46 * x3 # <<<<<<<<<<<<<< + * r48 = y2**2 + * r49 = 45 * r48 +*/ + __pyx_v_r47 = (__pyx_v_r46 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":501 + * r46 = y2 * y3 + * r47 = r46 * x3 + * r48 = y2**2 # <<<<<<<<<<<<<< + * r49 = 45 * r48 + * r50 = r49 * x3 +*/ + __pyx_v_r48 = pow(__pyx_v_y2, 2.0); + + /* "fontTools/pens/momentsPen.py":502 + * r47 = r46 * x3 + * r48 = y2**2 + * r49 = 45 * r48 # <<<<<<<<<<<<<< + * r50 = r49 * x3 + * r51 = y3**2 +*/ + __pyx_v_r49 = (45.0 * __pyx_v_r48); + + /* "fontTools/pens/momentsPen.py":503 + * r48 = y2**2 + * r49 = 45 * r48 + * r50 = r49 * x3 # <<<<<<<<<<<<<< + * r51 = y3**2 + * r52 = r51 * x3 +*/ + __pyx_v_r50 = (__pyx_v_r49 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":504 + * r49 = 45 * r48 + * r50 = r49 * x3 + * r51 = y3**2 # <<<<<<<<<<<<<< + * r52 = r51 * x3 + * r53 = y1**2 +*/ + __pyx_v_r51 = pow(__pyx_v_y3, 2.0); + + /* "fontTools/pens/momentsPen.py":505 + * r50 = r49 * x3 + * r51 = y3**2 + * r52 = r51 * x3 # <<<<<<<<<<<<<< + * r53 = y1**2 + * r54 = 9 * r53 +*/ + __pyx_v_r52 = (__pyx_v_r51 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":506 + * r51 = y3**2 + * r52 = r51 * x3 + * r53 = y1**2 # <<<<<<<<<<<<<< + * r54 = 9 * r53 + * r55 = y0**2 +*/ + __pyx_v_r53 = pow(__pyx_v_y1, 2.0); + + /* "fontTools/pens/momentsPen.py":507 + * r52 = r51 * x3 + * r53 = y1**2 + * r54 = 9 * r53 # <<<<<<<<<<<<<< + * r55 = y0**2 + * r56 = 21 * x1 +*/ + __pyx_v_r54 = (9.0 * __pyx_v_r53); + + /* "fontTools/pens/momentsPen.py":508 + * r53 = y1**2 + * r54 = 9 * r53 + * r55 = y0**2 # <<<<<<<<<<<<<< + * r56 = 21 * x1 + * r57 = 6 * x2 +*/ + __pyx_v_r55 = pow(__pyx_v_y0, 2.0); + + /* "fontTools/pens/momentsPen.py":509 + * r54 = 9 * r53 + * r55 = y0**2 + * r56 = 21 * x1 # <<<<<<<<<<<<<< + * r57 = 6 * x2 + * r58 = r16 * y2 +*/ + __pyx_v_r56 = (21.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":510 + * r55 = y0**2 + * r56 = 21 * x1 + * r57 = 6 * x2 # <<<<<<<<<<<<<< + * r58 = r16 * y2 + * r59 = r39 * y2 +*/ + __pyx_v_r57 = (6.0 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":511 + * r56 = 21 * x1 + * r57 = 6 * x2 + * r58 = r16 * y2 # <<<<<<<<<<<<<< + * r59 = r39 * y2 + * r60 = 9 * r48 +*/ + __pyx_v_r58 = (__pyx_v_r16 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":512 + * r57 = 6 * x2 + * r58 = r16 * y2 + * r59 = r39 * y2 # <<<<<<<<<<<<<< + * r60 = 9 * r48 + * r61 = r6 * y3 +*/ + __pyx_v_r59 = (__pyx_v_r39 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":513 + * r58 = r16 * y2 + * r59 = r39 * y2 + * r60 = 9 * r48 # <<<<<<<<<<<<<< + * r61 = r6 * y3 + * r62 = 3 * y3 +*/ + __pyx_v_r60 = (9.0 * __pyx_v_r48); + + /* "fontTools/pens/momentsPen.py":514 + * r59 = r39 * y2 + * r60 = 9 * r48 + * r61 = r6 * y3 # <<<<<<<<<<<<<< + * r62 = 3 * y3 + * r63 = r36 * y2 +*/ + __pyx_v_r61 = (__pyx_v_r6 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":515 + * r60 = 9 * r48 + * r61 = r6 * y3 + * r62 = 3 * y3 # <<<<<<<<<<<<<< + * r63 = r36 * y2 + * r64 = y1 * y3 +*/ + __pyx_v_r62 = (3.0 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":516 + * r61 = r6 * y3 + * r62 = 3 * y3 + * r63 = r36 * y2 # <<<<<<<<<<<<<< + * r64 = y1 * y3 + * r65 = 45 * r53 +*/ + __pyx_v_r63 = (__pyx_v_r36 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":517 + * r62 = 3 * y3 + * r63 = r36 * y2 + * r64 = y1 * y3 # <<<<<<<<<<<<<< + * r65 = 45 * r53 + * r66 = 5 * r51 +*/ + __pyx_v_r64 = (__pyx_v_y1 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":518 + * r63 = r36 * y2 + * r64 = y1 * y3 + * r65 = 45 * r53 # <<<<<<<<<<<<<< + * r66 = 5 * r51 + * r67 = x2**3 +*/ + __pyx_v_r65 = (45.0 * __pyx_v_r53); + + /* "fontTools/pens/momentsPen.py":519 + * r64 = y1 * y3 + * r65 = 45 * r53 + * r66 = 5 * r51 # <<<<<<<<<<<<<< + * r67 = x2**3 + * r68 = x3**3 +*/ + __pyx_v_r66 = (5.0 * __pyx_v_r51); + + /* "fontTools/pens/momentsPen.py":520 + * r65 = 45 * r53 + * r66 = 5 * r51 + * r67 = x2**3 # <<<<<<<<<<<<<< + * r68 = x3**3 + * r69 = 630 * y2 +*/ + __pyx_v_r67 = pow(__pyx_v_x2, 3.0); + + /* "fontTools/pens/momentsPen.py":521 + * r66 = 5 * r51 + * r67 = x2**3 + * r68 = x3**3 # <<<<<<<<<<<<<< + * r69 = 630 * y2 + * r70 = 126 * x3 +*/ + __pyx_v_r68 = pow(__pyx_v_x3, 3.0); + + /* "fontTools/pens/momentsPen.py":522 + * r67 = x2**3 + * r68 = x3**3 + * r69 = 630 * y2 # <<<<<<<<<<<<<< + * r70 = 126 * x3 + * r71 = x1**3 +*/ + __pyx_v_r69 = (630.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":523 + * r68 = x3**3 + * r69 = 630 * y2 + * r70 = 126 * x3 # <<<<<<<<<<<<<< + * r71 = x1**3 + * r72 = 126 * x2 +*/ + __pyx_v_r70 = (126.0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":524 + * r69 = 630 * y2 + * r70 = 126 * x3 + * r71 = x1**3 # <<<<<<<<<<<<<< + * r72 = 126 * x2 + * r73 = 63 * r9 +*/ + __pyx_v_r71 = pow(__pyx_v_x1, 3.0); + + /* "fontTools/pens/momentsPen.py":525 + * r70 = 126 * x3 + * r71 = x1**3 + * r72 = 126 * x2 # <<<<<<<<<<<<<< + * r73 = 63 * r9 + * r74 = r73 * x3 +*/ + __pyx_v_r72 = (126.0 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":526 + * r71 = x1**3 + * r72 = 126 * x2 + * r73 = 63 * r9 # <<<<<<<<<<<<<< + * r74 = r73 * x3 + * r75 = r15 * x3 + 15 * r42 +*/ + __pyx_v_r73 = (63.0 * __pyx_v_r9); + + /* "fontTools/pens/momentsPen.py":527 + * r72 = 126 * x2 + * r73 = 63 * r9 + * r74 = r73 * x3 # <<<<<<<<<<<<<< + * r75 = r15 * x3 + 15 * r42 + * r76 = 630 * x1 +*/ + __pyx_v_r74 = (__pyx_v_r73 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":528 + * r73 = 63 * r9 + * r74 = r73 * x3 + * r75 = r15 * x3 + 15 * r42 # <<<<<<<<<<<<<< + * r76 = 630 * x1 + * r77 = 14 * x3 +*/ + __pyx_v_r75 = ((__pyx_v_r15 * __pyx_v_x3) + (15.0 * __pyx_v_r42)); + + /* "fontTools/pens/momentsPen.py":529 + * r74 = r73 * x3 + * r75 = r15 * x3 + 15 * r42 + * r76 = 630 * x1 # <<<<<<<<<<<<<< + * r77 = 14 * x3 + * r78 = 21 * r27 +*/ + __pyx_v_r76 = (630.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":530 + * r75 = r15 * x3 + 15 * r42 + * r76 = 630 * x1 + * r77 = 14 * x3 # <<<<<<<<<<<<<< + * r78 = 21 * r27 + * r79 = 42 * x1 +*/ + __pyx_v_r77 = (14.0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":531 + * r76 = 630 * x1 + * r77 = 14 * x3 + * r78 = 21 * r27 # <<<<<<<<<<<<<< + * r79 = 42 * x1 + * r80 = 42 * x2 +*/ + __pyx_v_r78 = (21.0 * __pyx_v_r27); + + /* "fontTools/pens/momentsPen.py":532 + * r77 = 14 * x3 + * r78 = 21 * r27 + * r79 = 42 * x1 # <<<<<<<<<<<<<< + * r80 = 42 * x2 + * r81 = x1 * y2 +*/ + __pyx_v_r79 = (42.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":533 + * r78 = 21 * r27 + * r79 = 42 * x1 + * r80 = 42 * x2 # <<<<<<<<<<<<<< + * r81 = x1 * y2 + * r82 = 63 * r42 +*/ + __pyx_v_r80 = (42.0 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":534 + * r79 = 42 * x1 + * r80 = 42 * x2 + * r81 = x1 * y2 # <<<<<<<<<<<<<< + * r82 = 63 * r42 + * r83 = x1 * y1 +*/ + __pyx_v_r81 = (__pyx_v_x1 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":535 + * r80 = 42 * x2 + * r81 = x1 * y2 + * r82 = 63 * r42 # <<<<<<<<<<<<<< + * r83 = x1 * y1 + * r84 = r41 + r82 + 378 * r83 +*/ + __pyx_v_r82 = (63.0 * __pyx_v_r42); + + /* "fontTools/pens/momentsPen.py":536 + * r81 = x1 * y2 + * r82 = 63 * r42 + * r83 = x1 * y1 # <<<<<<<<<<<<<< + * r84 = r41 + r82 + 378 * r83 + * r85 = x2 * x3 +*/ + __pyx_v_r83 = (__pyx_v_x1 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":537 + * r82 = 63 * r42 + * r83 = x1 * y1 + * r84 = r41 + r82 + 378 * r83 # <<<<<<<<<<<<<< + * r85 = x2 * x3 + * r86 = r85 * y1 +*/ + __pyx_v_r84 = ((__pyx_v_r41 + __pyx_v_r82) + (378.0 * __pyx_v_r83)); + + /* "fontTools/pens/momentsPen.py":538 + * r83 = x1 * y1 + * r84 = r41 + r82 + 378 * r83 + * r85 = x2 * x3 # <<<<<<<<<<<<<< + * r86 = r85 * y1 + * r87 = r27 * x3 +*/ + __pyx_v_r85 = (__pyx_v_x2 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":539 + * r84 = r41 + r82 + 378 * r83 + * r85 = x2 * x3 + * r86 = r85 * y1 # <<<<<<<<<<<<<< + * r87 = r27 * x3 + * r88 = 27 * r9 +*/ + __pyx_v_r86 = (__pyx_v_r85 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":540 + * r85 = x2 * x3 + * r86 = r85 * y1 + * r87 = r27 * x3 # <<<<<<<<<<<<<< + * r88 = 27 * r9 + * r89 = r88 * y2 +*/ + __pyx_v_r87 = (__pyx_v_r27 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":541 + * r86 = r85 * y1 + * r87 = r27 * x3 + * r88 = 27 * r9 # <<<<<<<<<<<<<< + * r89 = r88 * y2 + * r90 = 42 * r14 +*/ + __pyx_v_r88 = (27.0 * __pyx_v_r9); + + /* "fontTools/pens/momentsPen.py":542 + * r87 = r27 * x3 + * r88 = 27 * r9 + * r89 = r88 * y2 # <<<<<<<<<<<<<< + * r90 = 42 * r14 + * r91 = 90 * x1 +*/ + __pyx_v_r89 = (__pyx_v_r88 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":543 + * r88 = 27 * r9 + * r89 = r88 * y2 + * r90 = 42 * r14 # <<<<<<<<<<<<<< + * r91 = 90 * x1 + * r92 = 189 * r18 +*/ + __pyx_v_r90 = (42.0 * __pyx_v_r14); + + /* "fontTools/pens/momentsPen.py":544 + * r89 = r88 * y2 + * r90 = 42 * r14 + * r91 = 90 * x1 # <<<<<<<<<<<<<< + * r92 = 189 * r18 + * r93 = 378 * r18 +*/ + __pyx_v_r91 = (90.0 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":545 + * r90 = 42 * r14 + * r91 = 90 * x1 + * r92 = 189 * r18 # <<<<<<<<<<<<<< + * r93 = 378 * r18 + * r94 = r12 * y1 +*/ + __pyx_v_r92 = (189.0 * __pyx_v_r18); + + /* "fontTools/pens/momentsPen.py":546 + * r91 = 90 * x1 + * r92 = 189 * r18 + * r93 = 378 * r18 # <<<<<<<<<<<<<< + * r94 = r12 * y1 + * r95 = 252 * x1 * x2 +*/ + __pyx_v_r93 = (378.0 * __pyx_v_r18); + + /* "fontTools/pens/momentsPen.py":547 + * r92 = 189 * r18 + * r93 = 378 * r18 + * r94 = r12 * y1 # <<<<<<<<<<<<<< + * r95 = 252 * x1 * x2 + * r96 = r79 * x3 +*/ + __pyx_v_r94 = (__pyx_v_r12 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":548 + * r93 = 378 * r18 + * r94 = r12 * y1 + * r95 = 252 * x1 * x2 # <<<<<<<<<<<<<< + * r96 = r79 * x3 + * r97 = 30 * r85 +*/ + __pyx_v_r95 = ((252.0 * __pyx_v_x1) * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":549 + * r94 = r12 * y1 + * r95 = 252 * x1 * x2 + * r96 = r79 * x3 # <<<<<<<<<<<<<< + * r97 = 30 * r85 + * r98 = r83 * x3 +*/ + __pyx_v_r96 = (__pyx_v_r79 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":550 + * r95 = 252 * x1 * x2 + * r96 = r79 * x3 + * r97 = 30 * r85 # <<<<<<<<<<<<<< + * r98 = r83 * x3 + * r99 = 30 * x3 +*/ + __pyx_v_r97 = (30.0 * __pyx_v_r85); + + /* "fontTools/pens/momentsPen.py":551 + * r96 = r79 * x3 + * r97 = 30 * r85 + * r98 = r83 * x3 # <<<<<<<<<<<<<< + * r99 = 30 * x3 + * r100 = 42 * x3 +*/ + __pyx_v_r98 = (__pyx_v_r83 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":552 + * r97 = 30 * r85 + * r98 = r83 * x3 + * r99 = 30 * x3 # <<<<<<<<<<<<<< + * r100 = 42 * x3 + * r101 = r42 * x1 +*/ + __pyx_v_r99 = (30.0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":553 + * r98 = r83 * x3 + * r99 = 30 * x3 + * r100 = 42 * x3 # <<<<<<<<<<<<<< + * r101 = r42 * x1 + * r102 = r10 * y2 + 14 * r14 + 126 * r18 * y1 + r81 * r99 +*/ + __pyx_v_r100 = (42.0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":554 + * r99 = 30 * x3 + * r100 = 42 * x3 + * r101 = r42 * x1 # <<<<<<<<<<<<<< + * r102 = r10 * y2 + 14 * r14 + 126 * r18 * y1 + r81 * r99 + * r103 = 378 * r48 +*/ + __pyx_v_r101 = (__pyx_v_r42 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":555 + * r100 = 42 * x3 + * r101 = r42 * x1 + * r102 = r10 * y2 + 14 * r14 + 126 * r18 * y1 + r81 * r99 # <<<<<<<<<<<<<< + * r103 = 378 * r48 + * r104 = 18 * y1 +*/ + __pyx_v_r102 = ((((__pyx_v_r10 * __pyx_v_y2) + (14.0 * __pyx_v_r14)) + ((126.0 * __pyx_v_r18) * __pyx_v_y1)) + (__pyx_v_r81 * __pyx_v_r99)); + + /* "fontTools/pens/momentsPen.py":556 + * r101 = r42 * x1 + * r102 = r10 * y2 + 14 * r14 + 126 * r18 * y1 + r81 * r99 + * r103 = 378 * r48 # <<<<<<<<<<<<<< + * r104 = 18 * y1 + * r105 = r104 * y2 +*/ + __pyx_v_r103 = (378.0 * __pyx_v_r48); + + /* "fontTools/pens/momentsPen.py":557 + * r102 = r10 * y2 + 14 * r14 + 126 * r18 * y1 + r81 * r99 + * r103 = 378 * r48 + * r104 = 18 * y1 # <<<<<<<<<<<<<< + * r105 = r104 * y2 + * r106 = y0 * y1 +*/ + __pyx_v_r104 = (18.0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":558 + * r103 = 378 * r48 + * r104 = 18 * y1 + * r105 = r104 * y2 # <<<<<<<<<<<<<< + * r106 = y0 * y1 + * r107 = 252 * y2 +*/ + __pyx_v_r105 = (__pyx_v_r104 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":559 + * r104 = 18 * y1 + * r105 = r104 * y2 + * r106 = y0 * y1 # <<<<<<<<<<<<<< + * r107 = 252 * y2 + * r108 = r107 * y0 +*/ + __pyx_v_r106 = (__pyx_v_y0 * __pyx_v_y1); + + /* "fontTools/pens/momentsPen.py":560 + * r105 = r104 * y2 + * r106 = y0 * y1 + * r107 = 252 * y2 # <<<<<<<<<<<<<< + * r108 = r107 * y0 + * r109 = y0 * y3 +*/ + __pyx_v_r107 = (252.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":561 + * r106 = y0 * y1 + * r107 = 252 * y2 + * r108 = r107 * y0 # <<<<<<<<<<<<<< + * r109 = y0 * y3 + * r110 = 42 * r64 +*/ + __pyx_v_r108 = (__pyx_v_r107 * __pyx_v_y0); + + /* "fontTools/pens/momentsPen.py":562 + * r107 = 252 * y2 + * r108 = r107 * y0 + * r109 = y0 * y3 # <<<<<<<<<<<<<< + * r110 = 42 * r64 + * r111 = 378 * r53 +*/ + __pyx_v_r109 = (__pyx_v_y0 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":563 + * r108 = r107 * y0 + * r109 = y0 * y3 + * r110 = 42 * r64 # <<<<<<<<<<<<<< + * r111 = 378 * r53 + * r112 = 63 * r48 +*/ + __pyx_v_r110 = (42.0 * __pyx_v_r64); + + /* "fontTools/pens/momentsPen.py":564 + * r109 = y0 * y3 + * r110 = 42 * r64 + * r111 = 378 * r53 # <<<<<<<<<<<<<< + * r112 = 63 * r48 + * r113 = 27 * x2 +*/ + __pyx_v_r111 = (378.0 * __pyx_v_r53); + + /* "fontTools/pens/momentsPen.py":565 + * r110 = 42 * r64 + * r111 = 378 * r53 + * r112 = 63 * r48 # <<<<<<<<<<<<<< + * r113 = 27 * x2 + * r114 = r27 * y2 +*/ + __pyx_v_r112 = (63.0 * __pyx_v_r48); + + /* "fontTools/pens/momentsPen.py":566 + * r111 = 378 * r53 + * r112 = 63 * r48 + * r113 = 27 * x2 # <<<<<<<<<<<<<< + * r114 = r27 * y2 + * r115 = r113 * r48 + 42 * r52 +*/ + __pyx_v_r113 = (27.0 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":567 + * r112 = 63 * r48 + * r113 = 27 * x2 + * r114 = r27 * y2 # <<<<<<<<<<<<<< + * r115 = r113 * r48 + 42 * r52 + * r116 = x3 * y3 +*/ + __pyx_v_r114 = (__pyx_v_r27 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":568 + * r113 = 27 * x2 + * r114 = r27 * y2 + * r115 = r113 * r48 + 42 * r52 # <<<<<<<<<<<<<< + * r116 = x3 * y3 + * r117 = 54 * r42 +*/ + __pyx_v_r115 = ((__pyx_v_r113 * __pyx_v_r48) + (42.0 * __pyx_v_r52)); + + /* "fontTools/pens/momentsPen.py":569 + * r114 = r27 * y2 + * r115 = r113 * r48 + 42 * r52 + * r116 = x3 * y3 # <<<<<<<<<<<<<< + * r117 = 54 * r42 + * r118 = r51 * x1 +*/ + __pyx_v_r116 = (__pyx_v_x3 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":570 + * r115 = r113 * r48 + 42 * r52 + * r116 = x3 * y3 + * r117 = 54 * r42 # <<<<<<<<<<<<<< + * r118 = r51 * x1 + * r119 = r51 * x2 +*/ + __pyx_v_r117 = (54.0 * __pyx_v_r42); + + /* "fontTools/pens/momentsPen.py":571 + * r116 = x3 * y3 + * r117 = 54 * r42 + * r118 = r51 * x1 # <<<<<<<<<<<<<< + * r119 = r51 * x2 + * r120 = r48 * x1 +*/ + __pyx_v_r118 = (__pyx_v_r51 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":572 + * r117 = 54 * r42 + * r118 = r51 * x1 + * r119 = r51 * x2 # <<<<<<<<<<<<<< + * r120 = r48 * x1 + * r121 = 21 * x3 +*/ + __pyx_v_r119 = (__pyx_v_r51 * __pyx_v_x2); + + /* "fontTools/pens/momentsPen.py":573 + * r118 = r51 * x1 + * r119 = r51 * x2 + * r120 = r48 * x1 # <<<<<<<<<<<<<< + * r121 = 21 * x3 + * r122 = r64 * x1 +*/ + __pyx_v_r120 = (__pyx_v_r48 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":574 + * r119 = r51 * x2 + * r120 = r48 * x1 + * r121 = 21 * x3 # <<<<<<<<<<<<<< + * r122 = r64 * x1 + * r123 = r81 * y3 +*/ + __pyx_v_r121 = (21.0 * __pyx_v_x3); + + /* "fontTools/pens/momentsPen.py":575 + * r120 = r48 * x1 + * r121 = 21 * x3 + * r122 = r64 * x1 # <<<<<<<<<<<<<< + * r123 = r81 * y3 + * r124 = 30 * r27 * y1 + r49 * x2 + 14 * r52 + 126 * r53 * x1 +*/ + __pyx_v_r122 = (__pyx_v_r64 * __pyx_v_x1); + + /* "fontTools/pens/momentsPen.py":576 + * r121 = 21 * x3 + * r122 = r64 * x1 + * r123 = r81 * y3 # <<<<<<<<<<<<<< + * r124 = 30 * r27 * y1 + r49 * x2 + 14 * r52 + 126 * r53 * x1 + * r125 = y2**3 +*/ + __pyx_v_r123 = (__pyx_v_r81 * __pyx_v_y3); + + /* "fontTools/pens/momentsPen.py":577 + * r122 = r64 * x1 + * r123 = r81 * y3 + * r124 = 30 * r27 * y1 + r49 * x2 + 14 * r52 + 126 * r53 * x1 # <<<<<<<<<<<<<< + * r125 = y2**3 + * r126 = y3**3 +*/ + __pyx_v_r124 = (((((30.0 * __pyx_v_r27) * __pyx_v_y1) + (__pyx_v_r49 * __pyx_v_x2)) + (14.0 * __pyx_v_r52)) + ((126.0 * __pyx_v_r53) * __pyx_v_x1)); + + /* "fontTools/pens/momentsPen.py":578 + * r123 = r81 * y3 + * r124 = 30 * r27 * y1 + r49 * x2 + 14 * r52 + 126 * r53 * x1 + * r125 = y2**3 # <<<<<<<<<<<<<< + * r126 = y3**3 + * r127 = y1**3 +*/ + __pyx_v_r125 = pow(__pyx_v_y2, 3.0); + + /* "fontTools/pens/momentsPen.py":579 + * r124 = 30 * r27 * y1 + r49 * x2 + 14 * r52 + 126 * r53 * x1 + * r125 = y2**3 + * r126 = y3**3 # <<<<<<<<<<<<<< + * r127 = y1**3 + * r128 = y0**3 +*/ + __pyx_v_r126 = pow(__pyx_v_y3, 3.0); + + /* "fontTools/pens/momentsPen.py":580 + * r125 = y2**3 + * r126 = y3**3 + * r127 = y1**3 # <<<<<<<<<<<<<< + * r128 = y0**3 + * r129 = r51 * y2 +*/ + __pyx_v_r127 = pow(__pyx_v_y1, 3.0); + + /* "fontTools/pens/momentsPen.py":581 + * r126 = y3**3 + * r127 = y1**3 + * r128 = y0**3 # <<<<<<<<<<<<<< + * r129 = r51 * y2 + * r130 = r112 * y3 + r21 * r51 +*/ + __pyx_v_r128 = pow(__pyx_v_y0, 3.0); + + /* "fontTools/pens/momentsPen.py":582 + * r127 = y1**3 + * r128 = y0**3 + * r129 = r51 * y2 # <<<<<<<<<<<<<< + * r130 = r112 * y3 + r21 * r51 + * r131 = 189 * r53 +*/ + __pyx_v_r129 = (__pyx_v_r51 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":583 + * r128 = y0**3 + * r129 = r51 * y2 + * r130 = r112 * y3 + r21 * r51 # <<<<<<<<<<<<<< + * r131 = 189 * r53 + * r132 = 90 * y2 +*/ + __pyx_v_r130 = ((__pyx_v_r112 * __pyx_v_y3) + (__pyx_v_r21 * __pyx_v_r51)); + + /* "fontTools/pens/momentsPen.py":584 + * r129 = r51 * y2 + * r130 = r112 * y3 + r21 * r51 + * r131 = 189 * r53 # <<<<<<<<<<<<<< + * r132 = 90 * y2 + * +*/ + __pyx_v_r131 = (189.0 * __pyx_v_r53); + + /* "fontTools/pens/momentsPen.py":585 + * r130 = r112 * y3 + r21 * r51 + * r131 = 189 * r53 + * r132 = 90 * y2 # <<<<<<<<<<<<<< + * + * self.area += ( +*/ + __pyx_v_r132 = (90.0 * __pyx_v_y2); + + /* "fontTools/pens/momentsPen.py":587 + * r132 = 90 * y2 + * + * self.area += ( # <<<<<<<<<<<<<< + * -r1 / 20 + * - r3 / 20 +*/ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_area); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 587, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + + /* "fontTools/pens/momentsPen.py":594 + * + 3 * x1 * (y2 + y3) / 20 + * + 3 * x2 * y3 / 10 + * - y0 * (r5 + r6 + x3) / 20 # <<<<<<<<<<<<<< + * ) + * self.momentX += ( +*/ + __pyx_t_1 = PyFloat_FromDouble(((((((((-__pyx_v_r1) / 20.0) - (__pyx_v_r3 / 20.0)) - ((__pyx_v_r4 * (__pyx_v_x2 + __pyx_v_x3)) / 20.0)) + ((__pyx_v_x0 * (((__pyx_v_r7 + __pyx_v_r8) + (10.0 * __pyx_v_y0)) + __pyx_v_y3)) / 20.0)) + (((3.0 * __pyx_v_x1) * (__pyx_v_y2 + __pyx_v_y3)) / 20.0)) + (((3.0 * __pyx_v_x2) * __pyx_v_y3) / 10.0)) - ((__pyx_v_y0 * ((__pyx_v_r5 + __pyx_v_r6) + __pyx_v_x3)) / 20.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 594, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":587 + * r132 = 90 * y2 + * + * self.area += ( # <<<<<<<<<<<<<< + * -r1 / 20 + * - r3 / 20 +*/ + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 587, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_area, __pyx_t_2) < (0)) __PYX_ERR(0, 587, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":596 + * - y0 * (r5 + r6 + x3) / 20 + * ) + * self.momentX += ( # <<<<<<<<<<<<<< + * r11 / 840 + * - r13 / 8 +*/ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentX); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 596, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/pens/momentsPen.py":618 + * ) + * / 840 + * - y0 * (r17 + r30 * x2 + r31 * x1 + r32 + r33 + 18 * r9) / 840 # <<<<<<<<<<<<<< + * ) + * self.momentY += ( +*/ + __pyx_t_1 = PyFloat_FromDouble(((((((((((__pyx_v_r11 / 840.0) - (__pyx_v_r13 / 8.0)) - (__pyx_v_r14 / 3.0)) - ((__pyx_v_r17 * ((-__pyx_v_r15) + __pyx_v_r8)) / 840.0)) + ((__pyx_v_r19 * (__pyx_v_r8 + (2.0 * __pyx_v_y3))) / 840.0)) + ((__pyx_v_r20 * (((__pyx_v_r0 + __pyx_v_r21) + (56.0 * __pyx_v_y0)) + __pyx_v_y3)) / 168.0)) + ((__pyx_v_r29 * (((-__pyx_v_r23) + __pyx_v_r25) + __pyx_v_r28)) / 840.0)) - ((__pyx_v_r4 * (((10.0 * __pyx_v_r12) + __pyx_v_r17) + __pyx_v_r22)) / 840.0)) + ((__pyx_v_x0 * (((((((((12.0 * __pyx_v_r27) + (__pyx_v_r30 * __pyx_v_y2)) + __pyx_v_r34) - (__pyx_v_r35 * __pyx_v_x1)) - __pyx_v_r37) - (__pyx_v_r38 * __pyx_v_y0)) + (__pyx_v_r39 * __pyx_v_x1)) - (__pyx_v_r4 * __pyx_v_x3)) + __pyx_v_r45)) / 840.0)) - ((__pyx_v_y0 * (((((__pyx_v_r17 + (__pyx_v_r30 * __pyx_v_x2)) + (__pyx_v_r31 * __pyx_v_x1)) + __pyx_v_r32) + __pyx_v_r33) + (18.0 * __pyx_v_r9))) / 840.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 618, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":596 + * - y0 * (r5 + r6 + x3) / 20 + * ) + * self.momentX += ( # <<<<<<<<<<<<<< + * r11 / 840 + * - r13 / 8 +*/ + __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 596, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentX, __pyx_t_4) < (0)) __PYX_ERR(0, 596, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/pens/momentsPen.py":620 + * - y0 * (r17 + r30 * x2 + r31 * x1 + r32 + r33 + 18 * r9) / 840 + * ) + * self.momentY += ( # <<<<<<<<<<<<<< + * -r4 * (r25 + r58) / 840 + * - r47 / 8 +*/ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentY); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 620, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + + /* "fontTools/pens/momentsPen.py":643 + * + x1 * (r24 * y1 + 10 * r51 + r59 + r60 + r7 * y3) / 280 + * + x2 * y3 * (r15 + r8) / 56 + * - y0 * (r16 * y1 + r31 * y2 + r44 * x2 + r45 + r61 - r62 * x1) / 840 # <<<<<<<<<<<<<< + * ) + * self.momentXX += ( +*/ + __pyx_t_1 = PyFloat_FromDouble(((((((((((((-__pyx_v_r4) * (__pyx_v_r25 + __pyx_v_r58)) / 840.0) - (__pyx_v_r47 / 8.0)) - (__pyx_v_r50 / 840.0)) - (__pyx_v_r52 / 6.0)) - ((__pyx_v_r54 * (__pyx_v_r6 + (2.0 * __pyx_v_x3))) / 840.0)) - ((__pyx_v_r55 * ((__pyx_v_r56 + __pyx_v_r57) + __pyx_v_x3)) / 168.0)) + ((__pyx_v_x0 * ((((((((((__pyx_v_r35 * __pyx_v_y1) + (__pyx_v_r40 * __pyx_v_y0)) + (__pyx_v_r44 * __pyx_v_y2)) + (18.0 * __pyx_v_r48)) + (140.0 * __pyx_v_r55)) + __pyx_v_r59) + __pyx_v_r63) + (12.0 * __pyx_v_r64)) + __pyx_v_r65) + __pyx_v_r66)) / 840.0)) + ((__pyx_v_x1 * (((((__pyx_v_r24 * __pyx_v_y1) + (10.0 * __pyx_v_r51)) + __pyx_v_r59) + __pyx_v_r60) + (__pyx_v_r7 * __pyx_v_y3))) / 280.0)) + (((__pyx_v_x2 * __pyx_v_y3) * (__pyx_v_r15 + __pyx_v_r8)) / 56.0)) - ((__pyx_v_y0 * ((((((__pyx_v_r16 * __pyx_v_y1) + (__pyx_v_r31 * __pyx_v_y2)) + (__pyx_v_r44 * __pyx_v_x2)) + __pyx_v_r45) + __pyx_v_r61) - (__pyx_v_r62 * __pyx_v_x1))) / 840.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 643, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":620 + * - y0 * (r17 + r30 * x2 + r31 * x1 + r32 + r33 + 18 * r9) / 840 + * ) + * self.momentY += ( # <<<<<<<<<<<<<< + * -r4 * (r25 + r58) / 840 + * - r47 / 8 +*/ + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 620, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentY, __pyx_t_2) < (0)) __PYX_ERR(0, 620, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":645 + * - y0 * (r16 * y1 + r31 * y2 + r44 * x2 + r45 + r61 - r62 * x1) / 840 + * ) + * self.momentXX += ( # <<<<<<<<<<<<<< + * -r12 * r72 * (-r40 + r8) / 9240 + * + 3 * r18 * (r28 + r34 - r38 * y1 + r75) / 3080 +*/ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentXX); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 645, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/pens/momentsPen.py":703 + * ) + * / 9240 + * - y0 # <<<<<<<<<<<<<< + * * ( + * r12 * r56 +*/ + __pyx_t_1 = PyFloat_FromDouble(((((((((((((((((-__pyx_v_r12) * __pyx_v_r72) * ((-__pyx_v_r40) + __pyx_v_r8)) / 9240.0) + (((3.0 * __pyx_v_r18) * (((__pyx_v_r28 + __pyx_v_r34) - (__pyx_v_r38 * __pyx_v_y1)) + __pyx_v_r75)) / 3080.0)) + ((__pyx_v_r20 * (((((((((__pyx_v_r24 * __pyx_v_x3) - (__pyx_v_r72 * __pyx_v_y0)) - (__pyx_v_r76 * __pyx_v_y0)) - (__pyx_v_r77 * __pyx_v_y0)) + __pyx_v_r78) + (__pyx_v_r79 * __pyx_v_y3)) + (__pyx_v_r80 * __pyx_v_y1)) + (210.0 * __pyx_v_r81)) + __pyx_v_r84)) / 9240.0)) - ((__pyx_v_r29 * ((((((((__pyx_v_r12 * __pyx_v_r21) + (14.0 * __pyx_v_r13)) + (__pyx_v_r44 * __pyx_v_r9)) - (__pyx_v_r73 * __pyx_v_y3)) + (54.0 * __pyx_v_r86)) - (84.0 * __pyx_v_r87)) - __pyx_v_r89) - __pyx_v_r90)) / 9240.0)) - ((__pyx_v_r4 * (((((70.0 * __pyx_v_r12) * __pyx_v_x2) + (27.0 * __pyx_v_r67)) + (42.0 * __pyx_v_r68)) + __pyx_v_r74)) / 9240.0)) + (((3.0 * __pyx_v_r67) * __pyx_v_y3) / 220.0)) - ((__pyx_v_r68 * __pyx_v_r69) / 9240.0)) - ((__pyx_v_r68 * __pyx_v_y3) / 4.0)) - (((__pyx_v_r70 * __pyx_v_r9) * ((-__pyx_v_r62) + __pyx_v_y2)) / 9240.0)) + (((3.0 * __pyx_v_r71) * (__pyx_v_r24 + __pyx_v_r40)) / 3080.0)) + ((pow(__pyx_v_x0, 3.0) * (((__pyx_v_r24 + __pyx_v_r44) + (165.0 * __pyx_v_y0)) + __pyx_v_y3)) / 660.0)) + ((__pyx_v_x0 * (((((((((((((((((((__pyx_v_r100 * __pyx_v_r27) + (162.0 * __pyx_v_r101)) + __pyx_v_r102) + __pyx_v_r11) + ((63.0 * __pyx_v_r18) * __pyx_v_y3)) + (__pyx_v_r27 * __pyx_v_r91)) - (__pyx_v_r33 * __pyx_v_y0)) - (__pyx_v_r37 * __pyx_v_x3)) + (__pyx_v_r43 * __pyx_v_x3)) - (__pyx_v_r73 * __pyx_v_y0)) - (__pyx_v_r88 * __pyx_v_y1)) + (__pyx_v_r92 * __pyx_v_y2)) - (__pyx_v_r93 * __pyx_v_y0)) - (9.0 * __pyx_v_r94)) - (__pyx_v_r95 * __pyx_v_y0)) - (__pyx_v_r96 * __pyx_v_y0)) - (__pyx_v_r97 * __pyx_v_y1)) - (18.0 * __pyx_v_r98)) + ((__pyx_v_r99 * __pyx_v_x1) * __pyx_v_y3))) / 9240.0)) - ((__pyx_v_y0 * ((((((((((__pyx_v_r12 * __pyx_v_r56) + (__pyx_v_r12 * __pyx_v_r80)) + (__pyx_v_r32 * __pyx_v_x3)) + (45.0 * __pyx_v_r67)) + (14.0 * __pyx_v_r68)) + (126.0 * __pyx_v_r71)) + __pyx_v_r74) + (__pyx_v_r85 * __pyx_v_r91)) + ((135.0 * __pyx_v_r9) * __pyx_v_x1)) + (__pyx_v_r92 * __pyx_v_x2))) / 9240.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 703, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":645 + * - y0 * (r16 * y1 + r31 * y2 + r44 * x2 + r45 + r61 - r62 * x1) / 840 + * ) + * self.momentXX += ( # <<<<<<<<<<<<<< + * -r12 * r72 * (-r40 + r8) / 9240 + * + 3 * r18 * (r28 + r34 - r38 * y1 + r75) / 3080 +*/ + __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 645, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentXX, __pyx_t_4) < (0)) __PYX_ERR(0, 645, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/pens/momentsPen.py":718 + * / 9240 + * ) + * self.momentXY += ( # <<<<<<<<<<<<<< + * -r103 * r12 / 18480 + * - r12 * r51 / 8 +*/ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentXY); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 718, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + + /* "fontTools/pens/momentsPen.py":780 + * ) + * / 3080 + * - y0 # <<<<<<<<<<<<<< + * * ( + * 54 * r101 +*/ + __pyx_t_1 = PyFloat_FromDouble((((((((((((((((-__pyx_v_r103) * __pyx_v_r12) / 18480.0) - ((__pyx_v_r12 * __pyx_v_r51) / 8.0)) - (((3.0 * __pyx_v_r14) * __pyx_v_y2) / 44.0)) + (((3.0 * __pyx_v_r18) * ((((__pyx_v_r105 + (__pyx_v_r2 * __pyx_v_y1)) + (18.0 * __pyx_v_r46)) + (15.0 * __pyx_v_r48)) + (7.0 * __pyx_v_r51))) / 6160.0)) + ((__pyx_v_r20 * ((((((((((1260.0 * __pyx_v_r106) + (__pyx_v_r107 * __pyx_v_y1)) + __pyx_v_r108) + (28.0 * __pyx_v_r109)) + __pyx_v_r110) + __pyx_v_r111) + __pyx_v_r112) + (30.0 * __pyx_v_r46)) + (2310.0 * __pyx_v_r55)) + __pyx_v_r66)) / 18480.0)) - ((__pyx_v_r54 * (((7.0 * __pyx_v_r12) + (18.0 * __pyx_v_r85)) + (15.0 * __pyx_v_r9))) / 18480.0)) - ((__pyx_v_r55 * (((((__pyx_v_r33 + __pyx_v_r73) + __pyx_v_r93) + __pyx_v_r95) + __pyx_v_r96) + __pyx_v_r97)) / 18480.0)) - ((__pyx_v_r7 * (((((42.0 * __pyx_v_r13) + (__pyx_v_r82 * __pyx_v_x3)) + (28.0 * __pyx_v_r87)) + __pyx_v_r89) + __pyx_v_r90)) / 18480.0)) - (((3.0 * __pyx_v_r85) * (__pyx_v_r48 - __pyx_v_r66)) / 220.0)) + ((((3.0 * __pyx_v_r9) * __pyx_v_y3) * (__pyx_v_r62 + (2.0 * __pyx_v_y2))) / 440.0)) + ((__pyx_v_x0 * (((((((((((((((((((((((-__pyx_v_r1) * __pyx_v_y0) - ((84.0 * __pyx_v_r106) * __pyx_v_x2)) + (__pyx_v_r109 * __pyx_v_r56)) + (54.0 * __pyx_v_r114)) + (__pyx_v_r117 * __pyx_v_y1)) + (15.0 * __pyx_v_r118)) + (21.0 * __pyx_v_r119)) + (81.0 * __pyx_v_r120)) + (__pyx_v_r121 * __pyx_v_r46)) + (54.0 * __pyx_v_r122)) + (60.0 * __pyx_v_r123)) + __pyx_v_r124) - ((__pyx_v_r21 * __pyx_v_x3) * __pyx_v_y0)) + (__pyx_v_r23 * __pyx_v_y3)) - (__pyx_v_r54 * __pyx_v_x3)) - (__pyx_v_r55 * __pyx_v_r72)) - (__pyx_v_r55 * __pyx_v_r76)) - (__pyx_v_r55 * __pyx_v_r77)) + ((__pyx_v_r57 * __pyx_v_y0) * __pyx_v_y3)) + (__pyx_v_r60 * __pyx_v_x3)) + ((84.0 * __pyx_v_r81) * __pyx_v_y0)) + ((189.0 * __pyx_v_r81) * __pyx_v_y1))) / 9240.0)) + ((__pyx_v_x1 * ((((((((__pyx_v_r104 * __pyx_v_r27) - (__pyx_v_r105 * __pyx_v_x3)) - (__pyx_v_r113 * __pyx_v_r53)) + (63.0 * __pyx_v_r114)) + __pyx_v_r115) - (__pyx_v_r16 * __pyx_v_r53)) + (28.0 * __pyx_v_r47)) + (__pyx_v_r51 * __pyx_v_r80))) / 3080.0)) - ((__pyx_v_y0 * (((((((((((((54.0 * __pyx_v_r101) + __pyx_v_r102) + (__pyx_v_r116 * __pyx_v_r5)) + (__pyx_v_r117 * __pyx_v_x3)) + (21.0 * __pyx_v_r13)) - (__pyx_v_r19 * __pyx_v_y3)) + (__pyx_v_r22 * __pyx_v_y3)) + (__pyx_v_r78 * __pyx_v_x3)) + ((189.0 * __pyx_v_r83) * __pyx_v_x2)) + (60.0 * __pyx_v_r86)) + ((81.0 * __pyx_v_r9) * __pyx_v_y1)) + (15.0 * __pyx_v_r94)) + (54.0 * __pyx_v_r98))) / 9240.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 780, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":718 + * / 9240 + * ) + * self.momentXY += ( # <<<<<<<<<<<<<< + * -r103 * r12 / 18480 + * - r12 * r51 / 8 +*/ + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 718, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentXY, __pyx_t_2) < (0)) __PYX_ERR(0, 718, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":798 + * / 9240 + * ) + * self.momentYY += ( # <<<<<<<<<<<<<< + * -r103 * r116 / 9240 + * - r125 * r70 / 9240 +*/ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentYY); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 798, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "fontTools/pens/momentsPen.py":846 + * / 3080 + * + 3 * x2 * y3 * (r48 + r66 + r8 * y3) / 220 + * - y0 # <<<<<<<<<<<<<< + * * ( + * r100 * r46 +*/ + __pyx_t_1 = PyFloat_FromDouble((((((((((((((((-__pyx_v_r103) * __pyx_v_r116) / 9240.0) - ((__pyx_v_r125 * __pyx_v_r70) / 9240.0)) - ((__pyx_v_r126 * __pyx_v_x3) / 12.0)) - (((3.0 * __pyx_v_r127) * (__pyx_v_r26 + __pyx_v_r38)) / 3080.0)) - ((__pyx_v_r128 * ((__pyx_v_r26 + __pyx_v_r30) + __pyx_v_x3)) / 660.0)) - ((__pyx_v_r4 * ((((__pyx_v_r112 * __pyx_v_x3) + __pyx_v_r115) - (14.0 * __pyx_v_r119)) + (84.0 * __pyx_v_r47))) / 9240.0)) - ((__pyx_v_r52 * __pyx_v_r69) / 9240.0)) - ((__pyx_v_r54 * ((__pyx_v_r58 + __pyx_v_r61) + __pyx_v_r75)) / 9240.0)) - ((__pyx_v_r55 * ((((((__pyx_v_r100 * __pyx_v_y1) + (__pyx_v_r121 * __pyx_v_y2)) + (__pyx_v_r26 * __pyx_v_y3)) + (__pyx_v_r79 * __pyx_v_y2)) + __pyx_v_r84) + ((210.0 * __pyx_v_x2) * __pyx_v_y1))) / 9240.0)) + ((__pyx_v_x0 * (((((((((((((((((((__pyx_v_r108 * __pyx_v_y1) + (__pyx_v_r110 * __pyx_v_y0)) + (__pyx_v_r111 * __pyx_v_y0)) + (__pyx_v_r112 * __pyx_v_y0)) + (45.0 * __pyx_v_r125)) + (14.0 * __pyx_v_r126)) + (126.0 * __pyx_v_r127)) + (770.0 * __pyx_v_r128)) + (42.0 * __pyx_v_r129)) + __pyx_v_r130) + (__pyx_v_r131 * __pyx_v_y2)) + (__pyx_v_r132 * __pyx_v_r64)) + ((135.0 * __pyx_v_r48) * __pyx_v_y1)) + ((630.0 * __pyx_v_r55) * __pyx_v_y1)) + ((126.0 * __pyx_v_r55) * __pyx_v_y2)) + ((14.0 * __pyx_v_r55) * __pyx_v_y3)) + (__pyx_v_r63 * __pyx_v_y3)) + (__pyx_v_r65 * __pyx_v_y3)) + (__pyx_v_r66 * __pyx_v_y0))) / 9240.0)) + ((__pyx_v_x1 * ((((((((27.0 * __pyx_v_r125) + (42.0 * __pyx_v_r126)) + (70.0 * __pyx_v_r129)) + __pyx_v_r130) + (__pyx_v_r39 * __pyx_v_r53)) + (__pyx_v_r44 * __pyx_v_r48)) + ((27.0 * __pyx_v_r53) * __pyx_v_y2)) + ((54.0 * __pyx_v_r64) * __pyx_v_y2))) / 3080.0)) + ((((3.0 * __pyx_v_x2) * __pyx_v_y3) * ((__pyx_v_r48 + __pyx_v_r66) + (__pyx_v_r8 * __pyx_v_y3))) / 220.0)) - ((__pyx_v_y0 * (((((((((((((__pyx_v_r100 * __pyx_v_r46) + (18.0 * __pyx_v_r114)) - (9.0 * __pyx_v_r118)) - (27.0 * __pyx_v_r120)) - (18.0 * __pyx_v_r122)) - (30.0 * __pyx_v_r123)) + __pyx_v_r124) + (__pyx_v_r131 * __pyx_v_x2)) + ((__pyx_v_r132 * __pyx_v_x3) * __pyx_v_y1)) + ((162.0 * __pyx_v_r42) * __pyx_v_y1)) + __pyx_v_r50) + ((63.0 * __pyx_v_r53) * __pyx_v_x3)) + (__pyx_v_r64 * __pyx_v_r99))) / 9240.0))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 846, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "fontTools/pens/momentsPen.py":798 + * / 9240 + * ) + * self.momentYY += ( # <<<<<<<<<<<<<< + * -r103 * r116 / 9240 + * - r125 * r70 / 9240 +*/ + __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 798, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_momentYY, __pyx_t_4) < (0)) __PYX_ERR(0, 798, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/pens/momentsPen.py":310 + * ) + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) +*/ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("fontTools.pens.momentsPen.MomentsPen._curveToOne", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +/* #### Code section: module_exttypes ### */ + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; +/* #### Code section: initfunc_declarations ### */ +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_CreateCodeObjects(__pyx_mstatetype *__pyx_mstate); /*proto*/ +/* #### Code section: init_module ### */ + +static int __Pyx_modinit_global_init_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_import_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_import_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec_momentsPen(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec_momentsPen}, + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + {Py_mod_gil, Py_MOD_GIL_USED}, + #endif + #if PY_VERSION_HEX >= 0x030C0000 && CYTHON_USE_MODULE_STATE + {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED}, + #endif + {0, NULL} +}; +#endif + +#ifdef __cplusplus +namespace { + struct PyModuleDef __pyx_moduledef = + #else + static struct PyModuleDef __pyx_moduledef = + #endif + { + PyModuleDef_HEAD_INIT, + "momentsPen", + 0, /* m_doc */ + #if CYTHON_USE_MODULE_STATE + sizeof(__pyx_mstatetype), /* m_size */ + #else + (CYTHON_PEP489_MULTI_PHASE_INIT) ? 0 : -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + #if CYTHON_USE_MODULE_STATE + __pyx_m_traverse, /* m_traverse */ + __pyx_m_clear, /* m_clear */ + NULL /* m_free */ + #else + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ + #endif + }; + #ifdef __cplusplus +} /* anonymous namespace */ +#endif + +/* PyModInitFuncType */ +#ifndef CYTHON_NO_PYINIT_EXPORT + #define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#else + #ifdef __cplusplus + #define __Pyx_PyMODINIT_FUNC extern "C" PyObject * + #else + #define __Pyx_PyMODINIT_FUNC PyObject * + #endif +#endif + +__Pyx_PyMODINIT_FUNC PyInit_momentsPen(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit_momentsPen(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +/* ModuleCreationPEP489 */ +#if CYTHON_COMPILING_IN_LIMITED_API && (__PYX_LIMITED_VERSION_HEX < 0x03090000\ + || ((defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS)) && __PYX_LIMITED_VERSION_HEX < 0x030A0000)) +static PY_INT64_T __Pyx_GetCurrentInterpreterId(void) { + { + PyObject *module = PyImport_ImportModule("_interpreters"); // 3.13+ I think + if (!module) { + PyErr_Clear(); // just try the 3.8-3.12 version + module = PyImport_ImportModule("_xxsubinterpreters"); + if (!module) goto bad; + } + PyObject *current = PyObject_CallMethod(module, "get_current", NULL); + Py_DECREF(module); + if (!current) goto bad; + if (PyTuple_Check(current)) { + PyObject *new_current = PySequence_GetItem(current, 0); + Py_DECREF(current); + current = new_current; + if (!new_current) goto bad; + } + long long as_c_int = PyLong_AsLongLong(current); + Py_DECREF(current); + return as_c_int; + } + bad: + PySys_WriteStderr("__Pyx_GetCurrentInterpreterId failed. Try setting the C define CYTHON_PEP489_MULTI_PHASE_INIT=0\n"); + return -1; +} +#endif +#if !CYTHON_USE_MODULE_STATE +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + static PY_INT64_T main_interpreter_id = -1; +#if CYTHON_COMPILING_IN_GRAAL && defined(GRAALPY_VERSION_NUM) && GRAALPY_VERSION_NUM > 0x19000000 + PY_INT64_T current_id = GraalPyInterpreterState_GetIDFromThreadState(PyThreadState_Get()); +#elif CYTHON_COMPILING_IN_GRAAL + PY_INT64_T current_id = PyInterpreterState_GetIDFromThreadState(PyThreadState_Get()); +#elif CYTHON_COMPILING_IN_LIMITED_API && (__PYX_LIMITED_VERSION_HEX < 0x03090000\ + || ((defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS)) && __PYX_LIMITED_VERSION_HEX < 0x030A0000)) + PY_INT64_T current_id = __Pyx_GetCurrentInterpreterId(); +#elif CYTHON_COMPILING_IN_LIMITED_API + PY_INT64_T current_id = PyInterpreterState_GetID(PyInterpreterState_Get()); +#else + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); +#endif + if (unlikely(current_id == -1)) { + return -1; + } + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return 0; + } else if (unlikely(main_interpreter_id != current_id)) { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +#endif +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) +{ + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + CYTHON_UNUSED_VAR(def); + #if !CYTHON_USE_MODULE_STATE + if (__Pyx_check_single_interpreter()) + return NULL; + #endif + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec_momentsPen(PyObject *__pyx_pyinit_module) +#endif +{ + int stringtab_initialized = 0; + #if CYTHON_USE_MODULE_STATE + int pystate_addmodule_run = 0; + #endif + __pyx_mstatetype *__pyx_mstate = NULL; + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + Py_ssize_t __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_t_9; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + PyObject *__pyx_t_13 = NULL; + PyObject *__pyx_t_14 = NULL; + size_t __pyx_t_15; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module 'momentsPen' has already been imported. Re-initialisation is not supported."); + return -1; + } + #else + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_t_1 = __pyx_pyinit_module; + Py_INCREF(__pyx_t_1); + #else + __pyx_t_1 = PyModule_Create(&__pyx_moduledef); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #if CYTHON_USE_MODULE_STATE + { + int add_module_result = __Pyx_State_AddModule(__pyx_t_1, &__pyx_moduledef); + __pyx_t_1 = 0; /* transfer ownership from __pyx_t_1 to "momentsPen" pseudovariable */ + if (unlikely((add_module_result < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + pystate_addmodule_run = 1; + } + #else + __pyx_m = __pyx_t_1; + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + PyUnstable_Module_SetGIL(__pyx_m, Py_MOD_GIL_USED); + #endif + __pyx_mstate = __pyx_mstate_global; + CYTHON_UNUSED_VAR(__pyx_t_1); + __pyx_mstate->__pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_mstate->__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_mstate->__pyx_d); + __pyx_mstate->__pyx_b = __Pyx_PyImport_AddModuleRef(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_mstate->__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_cython_runtime = __Pyx_PyImport_AddModuleRef("cython_runtime"); if (unlikely(!__pyx_mstate->__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_mstate->__pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /* ImportRefnannyAPI */ + #if CYTHON_REFNANNY + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); + if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); + } + #endif + +__Pyx_RefNannySetupContext("PyInit_momentsPen", 0); + __Pyx_init_runtime_version(); + if (__Pyx_check_binary_version(__PYX_LIMITED_VERSION_HEX, __Pyx_get_runtime_version(), CYTHON_COMPILING_IN_LIMITED_API) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_mstate->__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_mstate->__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_mstate->__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Library function declarations ---*/ + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitConstants(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + stringtab_initialized = 1; + if (__Pyx_InitGlobals() < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (__pyx_module_is_main_fontTools__pens__momentsPen) { + if (PyObject_SetAttr(__pyx_m, __pyx_mstate_global->__pyx_n_u_name, __pyx_mstate_global->__pyx_n_u_main) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + } + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "fontTools.pens.momentsPen")) { + if (unlikely((PyDict_SetItemString(modules, "fontTools.pens.momentsPen", __pyx_m) < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (__Pyx_CreateCodeObjects(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(__pyx_mstate); + (void)__Pyx_modinit_variable_export_code(__pyx_mstate); + (void)__Pyx_modinit_function_export_code(__pyx_mstate); + (void)__Pyx_modinit_type_init_code(__pyx_mstate); + (void)__Pyx_modinit_type_import_code(__pyx_mstate); + (void)__Pyx_modinit_variable_import_code(__pyx_mstate); + (void)__Pyx_modinit_function_import_code(__pyx_mstate); + /*--- Execution code ---*/ + + /* "fontTools/pens/momentsPen.py":1 + * from fontTools.pens.basePen import BasePen, OpenContourError # <<<<<<<<<<<<<< + * + * try: +*/ + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_BasePen,__pyx_mstate_global->__pyx_n_u_OpenContourError}; + __pyx_t_1 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_fontTools_pens_basePen, __pyx_imported_names, 2, NULL, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + } + __pyx_t_2 = __pyx_t_1; + __Pyx_GOTREF(__pyx_t_2); + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_BasePen,__pyx_mstate_global->__pyx_n_u_OpenContourError}; + for (__pyx_t_3=0; __pyx_t_3 < 2; __pyx_t_3++) { + __pyx_t_4 = __Pyx_ImportFrom(__pyx_t_2, __pyx_imported_names[__pyx_t_3]); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_imported_names[__pyx_t_3], __pyx_t_4) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":3 + * from fontTools.pens.basePen import BasePen, OpenContourError + * + * try: # <<<<<<<<<<<<<< + * import cython + * except (AttributeError, ImportError): +*/ + { + (void)__pyx_t_1; (void)__pyx_t_5; (void)__pyx_t_6; /* mark used */ + /*try:*/ { + + /* "fontTools/pens/momentsPen.py":4 + * + * try: + * import cython # <<<<<<<<<<<<<< + * except (AttributeError, ImportError): + * # if cython not installed, use mock module with no-op decorators and types +*/ + } + } + + /* "fontTools/pens/momentsPen.py":8 + * # if cython not installed, use mock module with no-op decorators and types + * from fontTools.misc import cython + * COMPILED = cython.compiled # <<<<<<<<<<<<<< + * + * +*/ + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_COMPILED, Py_True) < (0)) __PYX_ERR(0, 8, __pyx_L1_error) + + /* "fontTools/pens/momentsPen.py":11 + * + * + * __all__ = ["MomentsPen"] # <<<<<<<<<<<<<< + * + * +*/ + __pyx_t_2 = __Pyx_PyList_Pack(1, __pyx_mstate_global->__pyx_n_u_MomentsPen); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 11, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_all, __pyx_t_2) < (0)) __PYX_ERR(0, 11, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":14 + * + * + * class MomentsPen(BasePen): # <<<<<<<<<<<<<< + * + * def __init__(self, glyphset=None): +*/ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_BasePen); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = PyTuple_Pack(1, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PEP560_update_bases(__pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_7 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_Py3MetaclassPrepare(__pyx_t_7, __pyx_t_2, __pyx_mstate_global->__pyx_n_u_MomentsPen, __pyx_mstate_global->__pyx_n_u_MomentsPen, (PyObject *) NULL, __pyx_mstate_global->__pyx_n_u_fontTools_pens_momentsPen, (PyObject *) NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + if (__pyx_t_2 != __pyx_t_4) { + if (unlikely((PyDict_SetItemString(__pyx_t_8, "__orig_bases__", __pyx_t_4) < 0))) __PYX_ERR(0, 14, __pyx_L1_error) + } + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/pens/momentsPen.py":16 + * class MomentsPen(BasePen): + * + * def __init__(self, glyphset=None): # <<<<<<<<<<<<<< + * BasePen.__init__(self, glyphset) + * +*/ + __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_1__init__, 0, __pyx_mstate_global->__pyx_n_u_MomentsPen___init, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_pens_momentsPen, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[0])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 16, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_4); + #endif + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_mstate_global->__pyx_tuple[0]); + if (__Pyx_SetNameInClass(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_init, __pyx_t_4) < (0)) __PYX_ERR(0, 16, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/pens/momentsPen.py":26 + * self.momentYY = 0 + * + * def _moveTo(self, p0): # <<<<<<<<<<<<<< + * self._startPoint = p0 + * +*/ + __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_3_moveTo, 0, __pyx_mstate_global->__pyx_n_u_MomentsPen__moveTo, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_pens_momentsPen, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[1])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 26, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_4); + #endif + if (__Pyx_SetNameInClass(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_moveTo, __pyx_t_4) < (0)) __PYX_ERR(0, 26, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/pens/momentsPen.py":29 + * self._startPoint = p0 + * + * def _closePath(self): # <<<<<<<<<<<<<< + * p0 = self._getCurrentPoint() + * if p0 != self._startPoint: +*/ + __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_5_closePath, 0, __pyx_mstate_global->__pyx_n_u_MomentsPen__closePath, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_pens_momentsPen, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[2])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 29, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_4); + #endif + if (__Pyx_SetNameInClass(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_closePath, __pyx_t_4) < (0)) __PYX_ERR(0, 29, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/pens/momentsPen.py":34 + * self._lineTo(self._startPoint) + * + * def _endPath(self): # <<<<<<<<<<<<<< + * p0 = self._getCurrentPoint() + * if p0 != self._startPoint: +*/ + __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_7_endPath, 0, __pyx_mstate_global->__pyx_n_u_MomentsPen__endPath, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_pens_momentsPen, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[3])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_4); + #endif + if (__Pyx_SetNameInClass(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_endPath, __pyx_t_4) < (0)) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/pens/momentsPen.py":39 + * raise OpenContourError("Glyph statistics is not defined on open contours.") + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) +*/ + __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_9_lineTo, 0, __pyx_mstate_global->__pyx_n_u_MomentsPen__lineTo, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_pens_momentsPen, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[4])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 39, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_4); + #endif + if (__Pyx_SetNameInClass(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_lineTo, __pyx_t_4) < (0)) __PYX_ERR(0, 39, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/pens/momentsPen.py":99 + * ) + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) +*/ + __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_11_qCurveToOne, 0, __pyx_mstate_global->__pyx_n_u_MomentsPen__qCurveToOne, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_pens_momentsPen, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[5])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_4); + #endif + if (__Pyx_SetNameInClass(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_qCurveToOne, __pyx_t_4) < (0)) __PYX_ERR(0, 99, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/pens/momentsPen.py":310 + * ) + * + * @cython.locals(r0=cython.double) # <<<<<<<<<<<<<< + * @cython.locals(r1=cython.double) + * @cython.locals(r2=cython.double) +*/ + __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_9fontTools_4pens_10momentsPen_10MomentsPen_13_curveToOne, 0, __pyx_mstate_global->__pyx_n_u_MomentsPen__curveToOne, NULL, __pyx_mstate_global->__pyx_n_u_fontTools_pens_momentsPen, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[6])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 310, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_4); + #endif + if (__Pyx_SetNameInClass(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_curveToOne, __pyx_t_4) < (0)) __PYX_ERR(0, 310, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/pens/momentsPen.py":14 + * + * + * class MomentsPen(BasePen): # <<<<<<<<<<<<<< + * + * def __init__(self, glyphset=None): +*/ + __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_MomentsPen, __pyx_t_2, __pyx_t_8, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_4); + #endif + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_MomentsPen, __pyx_t_4) < (0)) __PYX_ERR(0, 14, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":866 + * + * + * if __name__ == "__main__": # <<<<<<<<<<<<<< + * from fontTools.misc.symfont import x, y, printGreenPen + * +*/ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 866, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_9 = (__Pyx_PyUnicode_Equals(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_main, Py_EQ)); if (unlikely((__pyx_t_9 < 0))) __PYX_ERR(0, 866, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (__pyx_t_9) { + + /* "fontTools/pens/momentsPen.py":867 + * + * if __name__ == "__main__": + * from fontTools.misc.symfont import x, y, printGreenPen # <<<<<<<<<<<<<< + * + * printGreenPen( +*/ + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_x,__pyx_mstate_global->__pyx_n_u_y,__pyx_mstate_global->__pyx_n_u_printGreenPen}; + __pyx_t_6 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_fontTools_misc_symfont, __pyx_imported_names, 3, NULL, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 867, __pyx_L1_error) + } + __pyx_t_2 = __pyx_t_6; + __Pyx_GOTREF(__pyx_t_2); + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_x,__pyx_mstate_global->__pyx_n_u_y,__pyx_mstate_global->__pyx_n_u_printGreenPen}; + for (__pyx_t_3=0; __pyx_t_3 < 3; __pyx_t_3++) { + __pyx_t_7 = __Pyx_ImportFrom(__pyx_t_2, __pyx_imported_names[__pyx_t_3]); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 867, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_imported_names[__pyx_t_3], __pyx_t_7) < (0)) __PYX_ERR(0, 867, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + } + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":869 + * from fontTools.misc.symfont import x, y, printGreenPen + * + * printGreenPen( # <<<<<<<<<<<<<< + * "MomentsPen", + * [ +*/ + __pyx_t_7 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_mstate_global->__pyx_n_u_printGreenPen); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 869, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + + /* "fontTools/pens/momentsPen.py":873 + * [ + * ("area", 1), + * ("momentX", x), # <<<<<<<<<<<<<< + * ("momentY", y), + * ("momentXX", x**2), +*/ + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_x); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 873, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_10 = PyTuple_Pack(2, __pyx_mstate_global->__pyx_n_u_momentX, __pyx_t_4); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 873, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/pens/momentsPen.py":874 + * ("area", 1), + * ("momentX", x), + * ("momentY", y), # <<<<<<<<<<<<<< + * ("momentXX", x**2), + * ("momentXY", x * y), +*/ + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_y); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 874, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_11 = PyTuple_Pack(2, __pyx_mstate_global->__pyx_n_u_momentY, __pyx_t_4); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 874, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "fontTools/pens/momentsPen.py":875 + * ("momentX", x), + * ("momentY", y), + * ("momentXX", x**2), # <<<<<<<<<<<<<< + * ("momentXY", x * y), + * ("momentYY", y**2), +*/ + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_x); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 875, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_12 = PyNumber_Power(__pyx_t_4, __pyx_mstate_global->__pyx_int_2, Py_None); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 875, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyTuple_Pack(2, __pyx_mstate_global->__pyx_n_u_momentXX, __pyx_t_12); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 875, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + + /* "fontTools/pens/momentsPen.py":876 + * ("momentY", y), + * ("momentXX", x**2), + * ("momentXY", x * y), # <<<<<<<<<<<<<< + * ("momentYY", y**2), + * ], +*/ + __Pyx_GetModuleGlobalName(__pyx_t_12, __pyx_mstate_global->__pyx_n_u_x); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 876, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_GetModuleGlobalName(__pyx_t_13, __pyx_mstate_global->__pyx_n_u_y); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 876, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_13); + __pyx_t_14 = PyNumber_Multiply(__pyx_t_12, __pyx_t_13); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 876, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_14); + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + __pyx_t_13 = PyTuple_Pack(2, __pyx_mstate_global->__pyx_n_u_momentXY, __pyx_t_14); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 876, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_13); + __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; + + /* "fontTools/pens/momentsPen.py":877 + * ("momentXX", x**2), + * ("momentXY", x * y), + * ("momentYY", y**2), # <<<<<<<<<<<<<< + * ], + * ) +*/ + __Pyx_GetModuleGlobalName(__pyx_t_14, __pyx_mstate_global->__pyx_n_u_y); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 877, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_14); + __pyx_t_12 = PyNumber_Power(__pyx_t_14, __pyx_mstate_global->__pyx_int_2, Py_None); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 877, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; + __pyx_t_14 = PyTuple_Pack(2, __pyx_mstate_global->__pyx_n_u_momentYY, __pyx_t_12); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 877, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_14); + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + + /* "fontTools/pens/momentsPen.py":871 + * printGreenPen( + * "MomentsPen", + * [ # <<<<<<<<<<<<<< + * ("area", 1), + * ("momentX", x), +*/ + __pyx_t_12 = __Pyx_PyList_Pack(6, __pyx_mstate_global->__pyx_tuple[1], __pyx_t_10, __pyx_t_11, __pyx_t_4, __pyx_t_13, __pyx_t_14); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 871, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; + __pyx_t_15 = 1; + { + PyObject *__pyx_callargs[3] = {__pyx_t_7, __pyx_mstate_global->__pyx_n_u_MomentsPen, __pyx_t_12}; + __pyx_t_2 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_8, __pyx_callargs+__pyx_t_15, (3-__pyx_t_15) | (__pyx_t_15*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 869, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "fontTools/pens/momentsPen.py":866 + * + * + * if __name__ == "__main__": # <<<<<<<<<<<<<< + * from fontTools.misc.symfont import x, y, printGreenPen + * +*/ + } + + /* "fontTools/pens/momentsPen.py":1 + * from fontTools.pens.basePen import BasePen, OpenContourError # <<<<<<<<<<<<<< + * + * try: +*/ + __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_test, __pyx_t_2) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_XDECREF(__pyx_t_13); + __Pyx_XDECREF(__pyx_t_14); + if (__pyx_m) { + if (__pyx_mstate->__pyx_d && stringtab_initialized) { + __Pyx_AddTraceback("init fontTools.pens.momentsPen", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + #if !CYTHON_USE_MODULE_STATE + Py_CLEAR(__pyx_m); + #else + Py_DECREF(__pyx_m); + if (pystate_addmodule_run) { + PyObject *tp, *value, *tb; + PyErr_Fetch(&tp, &value, &tb); + PyState_RemoveModule(&__pyx_moduledef); + PyErr_Restore(tp, value, tb); + } + #endif + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init fontTools.pens.momentsPen"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #else + return __pyx_m; + #endif +} +/* #### Code section: pystring_table ### */ +/* #### Code section: cached_builtins ### */ + +static int __Pyx_InitCachedBuiltins(__pyx_mstatetype *__pyx_mstate) { + CYTHON_UNUSED_VAR(__pyx_mstate); + + /* Cached unbound methods */ + __pyx_mstate->__pyx_umethod_PyDict_Type_items.type = (PyObject*)&PyDict_Type; + __pyx_mstate->__pyx_umethod_PyDict_Type_items.method_name = &__pyx_mstate->__pyx_n_u_items; + __pyx_mstate->__pyx_umethod_PyDict_Type_pop.type = (PyObject*)&PyDict_Type; + __pyx_mstate->__pyx_umethod_PyDict_Type_pop.method_name = &__pyx_mstate->__pyx_n_u_pop; + __pyx_mstate->__pyx_umethod_PyDict_Type_values.type = (PyObject*)&PyDict_Type; + __pyx_mstate->__pyx_umethod_PyDict_Type_values.method_name = &__pyx_mstate->__pyx_n_u_values; + return 0; +} +/* #### Code section: cached_constants ### */ + +static int __Pyx_InitCachedConstants(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "fontTools/pens/momentsPen.py":16 + * class MomentsPen(BasePen): + * + * def __init__(self, glyphset=None): # <<<<<<<<<<<<<< + * BasePen.__init__(self, glyphset) + * +*/ + __pyx_mstate_global->__pyx_tuple[0] = PyTuple_Pack(1, Py_None); if (unlikely(!__pyx_mstate_global->__pyx_tuple[0])) __PYX_ERR(0, 16, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[0]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[0]); + + /* "fontTools/pens/momentsPen.py":872 + * "MomentsPen", + * [ + * ("area", 1), # <<<<<<<<<<<<<< + * ("momentX", x), + * ("momentY", y), +*/ + __pyx_mstate_global->__pyx_tuple[1] = PyTuple_Pack(2, __pyx_mstate_global->__pyx_n_u_area, __pyx_mstate_global->__pyx_int_1); if (unlikely(!__pyx_mstate_global->__pyx_tuple[1])) __PYX_ERR(0, 872, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[1]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[1]); + #if CYTHON_IMMORTAL_CONSTANTS + { + PyObject **table = __pyx_mstate->__pyx_tuple; + for (Py_ssize_t i=0; i<2; ++i) { + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL); + #else + Py_SET_REFCNT(table[i], _Py_IMMORTAL_INITIAL_REFCNT); + #endif + } + } + #endif + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} +/* #### Code section: init_constants ### */ + +static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) { + CYTHON_UNUSED_VAR(__pyx_mstate); + { + const struct { const unsigned int length: 13; } index[] = {{1},{49},{32},{1},{7},{8},{10},{19},{21},{22},{19},{18},{18},{23},{16},{20},{7},{4},{18},{18},{10},{11},{7},{8},{22},{22},{25},{8},{16},{8},{8},{13},{5},{7},{8},{13},{10},{7},{8},{8},{7},{8},{7},{15},{8},{2},{2},{2},{2},{3},{11},{13},{12},{12},{2},{2},{3},{4},{4},{4},{4},{4},{4},{4},{4},{4},{4},{3},{4},{4},{4},{4},{4},{4},{4},{4},{4},{4},{3},{4},{4},{4},{4},{4},{4},{4},{4},{4},{4},{3},{4},{4},{4},{3},{3},{3},{3},{3},{3},{2},{3},{3},{3},{3},{3},{3},{3},{3},{3},{3},{2},{3},{3},{3},{3},{3},{3},{3},{3},{3},{3},{2},{3},{3},{3},{3},{3},{3},{3},{3},{3},{3},{2},{3},{3},{3},{3},{3},{3},{3},{3},{3},{3},{2},{3},{3},{3},{3},{3},{3},{3},{3},{3},{3},{2},{3},{3},{3},{3},{3},{3},{3},{3},{3},{3},{2},{3},{3},{3},{3},{3},{3},{3},{3},{3},{3},{2},{3},{3},{3},{3},{3},{3},{3},{3},{3},{3},{4},{12},{10},{11},{8},{6},{1},{2},{2},{2},{2},{1},{2},{2},{2},{2},{4139},{568},{9},{33},{34},{1710},{58}}; + #if (CYTHON_COMPRESS_STRINGS) == 2 /* compression: bz2 (1942 bytes) */ +const char* const cstring = "BZh91AY&SYn\312\265%\000\004@\177\377\376o\377\200\177\001\377\340\276\357\376`\277\357\377`@@@@@@@@@@@@@\000@\000`\010\377\017O\251\235\343\326\333\346n\2631/\270\372\212*x\367\017\205\004\246\222I\2652\203\310\374$\311\023C\322d\006\203@4\017\325\000\006\200\000\000%\024\232i\277J'\242\237\244jC@h\003\324\000\000\000\00044\000\000\032\236!\024\246CM\r\000\r\000\006\201\240\311\240\014\200\000\r\r2\002M%)\251\003\375T\311\376\252\001\352y \366\232\240\000\031\000\000\000h\000\006\236\240IE\036\236\246\244\000\310\000\000\000\000\003@\000\006\236\240\006\200\010\222Bi#\023Q\340M\232Jx\247\250\000\310\031\006\200\001\246\203\020i\265\r\351K\253{\274\376\277\322\036C\373\241\362\312\265\026\222\"\265\003\312\000\221\006\220\270\033\216\221\377\034\034\004\300p00\372\177\354\027\007\007\000\302\315W\230\326\022)\006\020\022\021I\000\024\317\330wK\"\335\000\"H\004\204D\032U\336`\257\002\220\212\022 \021\024\212\202\200\204\" \204\004$H\211\005\001\022\004\000$,\002\245\007\\\3431s\301\r\2316\366YD+j\303Q\002\256sf\001\022\200\022\344\013\326\364\332LS\023Y\261\234\"\222\"\n1Q%\225\220\311\204\231\r!$\025\004\310d\316\245\375\351F\251R\336<\306/XQ\255\231F\347b\254\337\nA\272\"%)\315\314^\247\234\231\014\022\331\304@\021\001\223\"BH\002\021\004\020\010$\322A\001=\370\252\362\302\275'{8\0374\323\215A\036\356\325v\266\275W\277gkor\236\357\337\345\004\212\307$)\005\005UUU\327[\206\272\256\272\353\256\272\353\257}\307\340\001'&Y\203\311\323\352*\252\252\252\256\333a\266\334V\355\266\333m\266\333t\302\035F`\312\014gf\316\006r2\325\325I %(I*\245)JR\224\245\376&\303\030\2068\266%\303\023\234\335\347L\3479\316w5\314\305\315qv!\2162\030\234\346\3579\345\234\3479\353_}\350bR\223\274\245*\245)J\221\210\210w\210\210\315\021\031\006\"!\336\"\"+\210\240b\"\035\342\"\"\270\215\030\037\346p\002N6\226\035\315\303x\363\357J\222\366\326\261\231\372\254\001p\r\313\231s\016&\366\203\237\314g\031\231,\333\237=\3250\025\005McY\265\206\263\006b\353m\361\335V\333\266\3254\006\336\035M_e\266o""\325\277\000\301_\273v\035\004\271`:1\276C\021\245e\263i;\203N\325\007N\344\242\373\202\241\027\263\014\331\366\324/An\004\304\\G\0239\302\354p\370\340`\200\"\000\210#\343\321\274\t\004\004\014@@A\r\022\314\031qo\301\327+4\005\240\200\\em\356p\353\211\375l\356\357s\310\245\304\222{\006\3302$V\316R\317\204r\021sg(,\305\203g\224\200e\032\334h\316\324\377\177\330\266dV\2763v\263\300\277w\210\342uj\205\2059\256+\223U\2548Ba! \300\265\212\352\337\340\270U\301U/P\300\014D\364\034\375\236=\375\311\013o\037|\331\333(\332\000\0310\322iH\221+\244O=\227\332\003\005\241k5\201c\"\340}\303\016\357\246\333\240\342~#\276\215\242\025\345\326\271\201(\243TPm\216g\017F\312BQ\030\351\3624\244\236DK7x\3440>\336\030l\340\260\032\300,\013\013,\246\366Lr\232\336L\026d0BobqU\034\006\240`\270x\025&c\001\233\0000f0\033\00660\356\335\316\267\231\247\230\372(w\240\223\022\221}8\203\343\253V\254\273\233\207\302\020\304\320\220\242?2\306\234\245)\363\252\035\002Gzr\007!\"d\222H\201\024C\274\241\342\005\306.\261>\200$P!\340\241\246\004\210QS\264\361(G%\006\231!\360\305$\002\035\372T\227>\024\027\300\203 \363\202\360\211\006Z\315\201\250\020\217T.\205C&\222\000\326\243%\n\200\330\000 \220A\000`+\357\003\374\007%\022\300\376\361j\212\273_H\251\332'\222]MJ\263\222K \220E\021\005\354\177g8M\302\026\001\371 9d\254D""\003\030\210\263\241\207\334\023\303\t\331 \002\254%\336\230L\013\230\377\307\213\331d!\351\204\350\222[+\3642bUh9CD\360\235=\272:\005C\305\351A\215J\t\031\032B\242\364(\360\337\3031\314\300\034\207\360\225\033B\305\024F\3607\310\210s\305IFD\354s\033\341\301TU\255i\016\201\r\346\363\372\212pj\314X\203\016}\362NjT\254Q\025\224\243\343\020\346=\022\236{Z4FYL\235|\234\252Y\003@e\225~\326(\220\035)\325\352\250\226M\247')9b\3208\370\374/)9pK\024Qhv\203\244\322i\265@\343\r.\262\2112-%#\324\350\rZ\252MTV\204\350\312\241\252\200\320j\312\005B\211I\240\322\031P{\031\031\003\306\232&\202\243f\265\\\316=\201\232\326\035\247FI\254I\322\n\023\032-\2617f\224\364;\320\227\024(\364'G\022p\2212\210N\3225\320\323\2311\2455;h\222\243FS\021\022i\nh\330\244\330\214\323FY\207\214\324e\254\215e\nJ\223\013\247\257\220\322\330l>\306\215\336\207\321u\372\324\022\226ssnw\317\236\313tY\237\221h\252m\336|\333'\177\236sY\363\263\311\321\271\304i\026E\210(\312u\325Krnf\232P\320p\342wf\206F\322\255\256\266\315)UT\035\0253&d\266\212U\271wesJ\213\202%\252-\335\322\270i\2731\211\203iLf\227\245\242\351\245\310\256\224\241\243E7XN \014\020\222\014L\t\213^\202f\327\245p\344\331\272\223r\3158\264\210\233\314\250\233\305\323E\230\002*\320\341S\252\021xX\211\0218X\275@@\222\250\340^\246\3224Db\344 p\300\273\202M\215\020\240\025%\262\213A\222L7*\013\274C%C\025\016\033\020\231T\341\222\3410@\017)r\301\307C1\266\225\254\251\240\232Z\0327-q\315*&`\"\010e\031\010\253\213[\030\242\252xXt+&H7\263\262\2522\035\204*\267\374]\311\024\341BA\273*\324\224"; + PyObject *data = __Pyx_DecompressString(cstring, 1942, 2); + if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error) + const char* const bytes = __Pyx_PyBytes_AsString(data); + #if !CYTHON_ASSUME_SAFE_MACROS + if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) } + #endif + #elif (CYTHON_COMPRESS_STRINGS) != 0 /* compression: zlib (2182 bytes) */ +const char* const cstring = "x\332\245X;s\333H\022>\211r\225\256\326>\233\017\335\245\"%_(\023/>\242-\221R\355m\235\367,>\266\3526B\201 \274\313:\222 \033\240K\314\0342D\210\220!C\206\014\0312T\350P?\301?\341z\000\0148x\020\204\356\244\0021\230\351\351\351\376\3721=s\363\323p>\371\343\3220\025s`\230\003\325\270\034\030\227c\335\274\354k\237\007c\255\177\251\217/\365\2116\276T\365\261\251\317\300\270\3718\350}\370\214\037]]\037\032\037p\310\3700\322G\332\3304\036\264\361\315d\376cC14l6?\375\362\360\363\307\373\273_\374\301}\353F\226\007\343\201)\313l\227:\324q\242b\376\021\350\234\301\027\255\253\177\032kl\2576\356\207\t\207(mWg{F\372\227P\317\264\351s\373\204\2027]\225\356\001t\220\345\207\371#>w\003\325\224\377\245=\232m\355\263,+\303!\376\200\246(\306|\254\016\364\033U\007}f\342R\206J\026D-d\023\024U\353)\352\177\366\n0R\313r_We\231J\354\003w3\032\030\352\2151\037\221\236}/\201\363\246\347\002\030\352\335\203,\313\237gc\302\364w\315D\215\000\273\037\364\301\330\374\235\230\322\320L\n\256<0d_\340\201\251\215\014\017%Y\036)(9\376\2154SQ\207\212a8\037z\1776\324\310\233\254\364o\357E\337\277\271o\372\372\315\303\027\311AG\365L\030h\016\227\2612B\036\223\362\204\233\360\023a\242O\360\003\264\t\242H\032(\346O\240ic\242\006c\016Y\236\316\224\241;\025\312\300\001\207?e\362\220&\217\217\200\217\210\217\204O\005\237*>5|\352\300!\t!w\336H\312!)\207\244\034\222rH\312!)\207\244\034\222\3420\217\244<\222\362\244\215\244<\222\362H\312#)\217\244<\222\362H\212C\002\222\nH* )R!\021\322 \tR\324\201\007\344\204\214\220\017\262A.\310\004y \013\344\200\014\004\300\3518\033'\013\330\026A\220@\250\200P\005\241\006B\035D\020\313 r \362 \n \342\247\004b\005\304*\2105\020\353 \201T\006\211\003\211\007I\000I\004\t{* UA\252\201T\207\nT\312P\341\240\302CE\200\212\010\025\t*\330Y\205J\r*u\250B\265\014U\016\252<]d%\242_\025\203\372\021\207\273fV\2408\277Z\267\327\351\0008f\334\375\270\257\177\210g\024\302(\272IPR\207$P6\321S\013\230\003\214ui}\2679\335\274\247P\272\212\366\234pkQg 0\372Q\344\346]\377#\021\252\331\262\261\364\243\230P\233^\024\213\270~\036C\274\217\3533\201qq\304KLG\252d\374^\324(\2450X\000w\007\227C\026Jc\230\004?\310\004\264s\026\361\375\362\327\260\031\374\217\210\305\250\001.\230\204E\363}\007m}\275\351mO\267\245\355\375.\267\343b\260\177\357\030\370@pF\373\367\344>,}gt\357mw\214\004\255\270\034b""\256\370Uw\235[K(^1.\201\206\367,\t5(&z\233\273=\\9\336\306{K\264\366\332fq\001&\256fN1\304j\023\325/j\31344\305x\353\276\244\021\235\031\211\2053\"\177\310-\243\006\215\212YLH\322!v\376\246U<\302\363\2106g\024\352\000V\356N\036A0\032\004\367\3506\216\327j(O\227\375\350\260\021\361\0369\222M\361\025MK\032\356\020t\237\276\306\002\343\204\272\031a(x\224\006\356\323\367\350\207\302\272\267y\265io\2461\031p\357\271\027\224\r\002\264/\210$\\\340\312s\270\316\372t}\215\2742\033~\323\335\346\266\342\026v\371]cGaMa\252\004\327J\252\020\342y\004\360?\374\221&\325\036\362\216\204\01089\354\303\376\207\3176\034\303\307v\014\177\271Rd\277< R\000\236|,\020\0076\036G\310\257\267\337/cn\n\236\223o\002\376\257\333\202\203\247A\022!?c!J\374\217\367\222n\003\2753\203E\212\212\376,\256a\343\\^|\264O\3742\233\367\034\276\341\025Edo(m\032\033u\233\3376\321Q\013\273\366n\372\215\255\343\335\254\356\206K\306\231\357\332\204,\301c%dl\2566\035\314\314WXV\031\273\322\356\356\351\241\375\324\356\004\212+\301\261\177\270\226P\331\021\372\021\330\321\\bw\3553\222\350\237\303\222M\0172:\t\037\021zL\214\266\330\n2|~H\342\036S\014\371\332\004\253rv\367j}\275%\230~\2629\322@L\236\262%<}\234\377\260\020p^\001\203\350u\356)\207]\313\303\004\357\254s\264c\301F^\337\315\223\303\327UG\356\251\376\227\353)\177z\272\333\244#\027@.\226/\275\356Hs\375\222\366\316\313\227 \215\354\361\"\007\030\273\256\222\362J'\rL\301\362\356\234\006\203s\325\220\250\246\323Hq\014\317\263\207\273\330\210q\016\352L\020\347\255[\177\017\314\262\233\242\037\233\307\"1\264\010\215\0252W\305\223\225\204\333f\221\035,y)\213l\002\331@:\341b#1rP\315\306i\374\362\363d\223\036\234\375\353\205\214\243\311)SXd\274Z\226\324\020g\230N\225\027\037\253b\016\335l~\322\250D\354\241\252\023\316h\207n\032\022\252\207Pq\0378<6\274m\261\347iy\346m\305\344\360Xd\320\020\231\014\033\246\273\302\212\312\334\362\333.\036<\304\035<\265\332\35412P\255E\020\241\206\314;\373Z\340\006\206\275\316\214\337WB\226\244'\200B\2123\331\321C\372\241k\006z\003s""\217e_0\014\257\331\r$\266\260,\260\206<\274\315D\034<\375%\304\261\373\211`\021\305(\033\2043p\027\026w\027EoT5,\200[Og\177#\271\361\355b\216\273\327_\335\224\362\017\313\331\016\377iM\231\327G\222a\331\327\177\001<\245]\242"; + PyObject *data = __Pyx_DecompressString(cstring, 2182, 1); + if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error) + const char* const bytes = __Pyx_PyBytes_AsString(data); + #if !CYTHON_ASSUME_SAFE_MACROS + if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) } + #endif + #else /* compression: none (7701 bytes) */ +const char* const bytes = ".Glyph statistics is not defined on open contours.Lib/fontTools/pens/momentsPen.py?BasePenCOMPILEDMomentsPenMomentsPen.__init__MomentsPen._closePathMomentsPen._curveToOneMomentsPen._endPathMomentsPen._lineToMomentsPen._moveToMomentsPen._qCurveToOneOpenContourError__Pyx_PyDict_NextRef__all__areaasyncio.coroutinescline_in_traceback_closePath_curveToOne__doc___endPathfontTools.misc.symfontfontTools.pens.basePenfontTools.pens.momentsPen__func___getCurrentPointglyphset__init___is_coroutineitems_lineTo__main____metaclass____module__momentXmomentXXmomentXYmomentYmomentYY_moveTo__mro_entries____name__p0p1p2p3pop__prepare__printGreenPen_qCurveToOne__qualname__r0r1r10r100r101r102r103r104r105r106r107r108r109r11r110r111r112r113r114r115r116r117r118r119r12r120r121r122r123r124r125r126r127r128r129r13r130r131r132r14r15r16r17r18r19r2r20r21r22r23r24r25r26r27r28r29r3r30r31r32r33r34r35r36r37r38r39r4r40r41r42r43r44r45r46r47r48r49r5r50r51r52r53r54r55r56r57r58r59r6r60r61r62r63r64r65r66r67r68r69r7r70r71r72r73r74r75r76r77r78r79r8r80r81r82r83r84r85r86r87r88r89r9r90r91r92r93r94r95r96r97r98r99self__set_name__setdefault_startPoint__test__valuesxx0x1x2x3yy0y1y2y3\200A\360T\004\000\t\r\210E\220\024\320\025&\240a\330\010\014\210E\220\021\330\010\014\210E\220\021\330\010\014\210E\220\021\340\010\r\210R\210r\220\021\330\010\r\210S\220\002\220!\330\010\r\210S\220\002\220!\330\010\r\210S\220\002\220!\330\010\r\210R\210r\220\021\330\010\r\210R\210r\220\021\330\010\r\210R\210r\220\021\330\010\r\210R\210r\220\021\330\010\r\210R\210r\220\021\330\010\r\210R\210r\220\021\330\010\016\210c\220\022\2201\330\010\016\210d\220\"\220A\330\010\016\210b\220\002\220!\330\010\016\210d\220\"\220A\330\010\016\210d\220\"\220A\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210d\220\"\220A\330\010\016\210b\220\002\220!\330\010\016\210b\220\002\220!\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210b\220\002\220!""\330\010\016\210d\220\"\220C\220r\230\021\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210a\210t\2202\220S\230\002\230#\230R\230q\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210d\220\"\220A\330\010\016\210c\220\022\2201\330\010\016\210d\220\"\220A\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210b\220\002\220!\330\010\016\210d\220\"\220A\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210d\220\"\220D\230\002\230$\230b\240\001\330\010\016\210c\220\022\2201\330\010\016\210d\220\"\220A\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210d\220\"\220A\330\010\016\210b\220\002\220!\330\010\016\210d\220\"\220A\330\010\016\210b\220\002\220!\330\010\016\210b\220\002\220!\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210b\220\002\220!\330\010\016\210d\220\"\220A\330\010\016\210d\220\"\220A\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210b\220\002\220!\330\010\016\210d\220\"\220A\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210b\220\002\220!\330\010\016\210b\220\002\220!\330\010\016\210b\220\002\220!\330\010\016\210d\220\"\220A\330\010\016\210d\220\"\220A\330\010\016\210b\220\002\220!\330\010\016\210d\220\"\220A\330\010\016\210c\220\022\2201\330\010\016\210d\220\"\220A\330\010\016\210d\220\"\220C\220r\230\023\230B\230a\330\010\016\210d\220\"\220A\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210d\220\"\220D\230\002\230$\230b\240\001\330\010\016\210c\220\022\2201\330\010\016\210d\220\"\220A\330\010\016\210d\220\"\220A\330\010\016\210c\220\022\2201\330""\010\016\210d\220\"\220A\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210d\220\"\220A\330\010\016\210d\220\"\220A\330\010\016\210d\220\"\220A\330\010\016\210d\220\"\220C\220r\230\021\330\010\016\210d\220\"\220A\330\010\016\210c\220\022\2201\330\010\016\210d\220\"\220A\330\010\016\210c\220\022\2201\330\010\017\210s\220\"\220A\330\010\017\210t\2202\220Q\330\010\017\210t\2202\220S\230\002\230#\230R\230t\2402\240T\250\022\2504\250r\260\023\260B\260d\270\"\270A\330\010\017\210t\2202\220Q\330\010\017\210s\220\"\220A\330\010\017\210u\220B\220a\330\010\017\210s\220\"\220A\330\010\017\210t\2202\220Q\330\010\017\210u\220B\220a\330\010\017\210s\220\"\220A\330\010\017\210s\220\"\220A\330\010\017\210t\2202\220Q\330\010\017\210s\220\"\220A\330\010\017\210s\220\"\220A\330\010\017\210t\2202\220Q\330\010\017\210u\220B\220d\230\"\230C\230r\240\021\330\010\017\210s\220\"\220A\330\010\017\210s\220\"\220A\330\010\017\210t\2202\220Q\330\010\017\210t\2202\220Q\330\010\017\210t\2202\220Q\330\010\017\210s\220\"\220A\330\010\017\210t\2202\220Q\330\010\017\210t\2202\220Q\330\010\017\210s\220\"\220D\230\002\230#\230R\230t\2402\240S\250\002\250#\250R\250t\2602\260T\270\022\2704\270r\300\021\330\010\017\210r\220\022\2201\330\010\017\210r\220\022\2201\330\010\017\210r\220\022\2201\330\010\017\210r\220\022\2201\330\010\017\210t\2202\220Q\330\010\017\210u\220B\220c\230\022\2304\230r\240\021\330\010\017\210t\2202\220Q\330\010\017\210s\220\"\220A\340\010\014\210A\330\014\r\210S\220\002\220!\330\014\016\210c\220\022\2201\330\014\016\210c\220\023\220C\220r\230\024\230R\230q\330\014\016\210c\220\023\220C\220r\230\023\230B\230c\240\022\2403\240b\250\004\250B\250a\330\014\016\210b\220\002\220#\220S\230\003\2302\230T\240\022\2401\330\014\016\210b\220\002\220#\220R\220s\230\"\230A\330\014\016\210c\220\023\220C\220r\230\023\230B\230d\240\"\240A\340\010\014\210A\330\014\020\220\002\220!\330\014\016\210d\220\"\220A\330\014\016\210d\220\"\220A\330\014\016\210d\220#\220Q\220d\230\"""\230D\240\002\240!\330\014\016\210d\220#\220S\230\002\230\"\230B\230d\240\"\240A\330\014\016\210d\220#\220S\230\002\230$\230b\240\003\2402\240S\250\002\250$\250b\260\001\330\014\016\210d\220#\220Q\220d\230\"\230D\240\002\240%\240r\250\021\330\014\016\210c\220\023\220C\220r\230\024\230R\230t\2402\240U\250\"\250A\330\014\016\210a\330\014\r\330\020\023\2202\220Q\330\020\022\220$\220b\230\001\330\020\022\220!\330\020\022\220$\220b\230\001\330\020\022\220!\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220#\220R\220q\330\020\022\220!\340\014\016\210a\330\014\016\210c\220\023\220D\230\002\230$\230b\240\003\2402\240T\250\022\2503\250b\260\004\260B\260d\270\"\270C\270r\300\024\300R\300q\340\010\014\210A\330\014\r\210S\220\003\2204\220r\230\025\230b\240\001\330\014\016\210d\220\"\220A\330\014\016\210d\220\"\220A\330\014\016\210d\220\"\220A\330\014\016\210d\220#\220S\230\002\230\"\230B\230d\240\"\240A\330\014\016\210d\220#\220T\230\022\2304\230r\240\024\240R\240q\330\014\016\210a\330\014\r\330\020\024\220B\220a\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220#\220R\220q\330\020\022\220$\220b\230\001\330\020\022\220!\330\020\022\220!\330\020\022\220#\220R\220q\330\020\022\220!\330\020\022\220!\340\014\016\210a\330\014\016\210c\220\023\220D\230\002\230#\230R\230s\240\"\240D\250\002\250$\250b\260\004\260B\260c\270\022\2704\270r\300\021\330\014\016\210c\220\022\2203\220c\230\024\230R\230t\2402\240Q\330\014\016\210c\220\023\220D\230\002\230#\230R\230t\2402\240S\250\002\250$\250b\260\003\2602\260T\270\022\2704\270r\300\024\300R\300t\3102\310Q\340\010\014\210A\330\014\r\210T\220\022\2204\220s\230!\2304\230r\240\024\240R\240q\330\014\016\210b\220\002\220$\220c\230\024\230R\230t\2402\240T\250\022\2503\250b\260\005\260R\260q\330\014\016\210a\330\014\r\330\020\024\220B\220a\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220!\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230""\001\330\020\022\220$\220b\230\001\330\020\022\220!\340\014\016\210a\330\014\016\210a\330\014\r\330\020\024\220B\220a\330\020\022\220#\220R\220q\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220#\220R\220q\330\020\022\220#\220R\220q\330\020\022\220!\330\020\022\220!\340\014\016\210a\330\014\016\210c\220\023\220C\220r\230\024\230R\230s\240\"\240C\240r\250\024\250R\250s\260\"\260D\270\002\270%\270r\300\021\330\014\016\210b\220\002\220$\220b\230\003\2302\230Q\330\014\016\210d\220\"\220D\230\002\230!\330\014\016\210d\220\"\220C\220r\230\021\330\014\016\210d\220\"\220C\220s\230!\2304\230r\240\024\240R\240q\330\014\016\210b\220\002\220$\220c\230\024\230R\230u\240B\240a\330\014\016\210b\220\002\220\"\220C\220t\2302\230T\240\022\2404\240r\250\023\250B\250d\260\"\260A\330\014\016\210a\330\014\r\330\020\025\220R\220q\330\020\022\220$\220b\230\001\330\020\022\220!\330\020\022\220!\330\020\022\220#\220R\220t\2302\230Q\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220\"\220B\220a\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220#\220R\220q\330\020\022\220$\220b\230\003\2302\230Q\340\014\016\210a\330\014\016\210a\330\014\r\330\020\024\220B\220a\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220#\220R\220q\330\020\022\220#\220R\220q\330\020\022\220$\220b\230\001\330\020\022\220!\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\003\2302\230Q\330\020\022\220$\220b\230\001\340\014\016\210a\340\010\014\210A\330\014\r\210U\220\"\220D\230\002\230!\330\014\016\210d\220\"\220D\230\002\230!\330\014\016\210b\220\002\220$\220b\230\003\2302\230Q\330\014\016\210b\220\002\220$\220c\230\025\230b\240\003\2402\240S\250\002\250#\250R\250t\2602\260S\270\002\270$\270b\300\002\300\"\300E""\310\022\3101\330\014\016\210a\330\014\r\330\020\025\220R\220q\330\020\022\220%\220r\230\021\330\020\022\220!\330\020\022\220#\220R\220q\330\020\022\220!\330\020\022\220!\330\020\022\220!\330\020\022\220#\220R\220q\330\020\022\220%\220r\230\021\330\020\022\220!\340\014\016\210a\330\014\016\210d\220#\220R\220r\230\024\230R\230s\240\"\240D\250\002\250#\250R\250t\2602\260Q\330\014\016\210d\220#\220T\230\022\2304\230r\240\024\240R\240t\2502\250T\260\022\2605\270\002\270!\330\014\016\210c\220\023\220C\220r\230\024\230R\230t\2402\240S\250\002\250#\250R\250t\2602\260T\270\022\2705\300\002\300!\330\014\016\210b\220\002\220$\220c\230\024\230R\230u\240B\240a\330\014\016\210b\220\002\220#\220R\220s\230#\230T\240\022\2402\240R\240t\2502\250Q\330\014\016\210a\330\014\r\330\020\021\220\023\220B\220a\330\020\022\220#\220R\220u\230B\230a\330\020\022\220%\220r\230\021\330\020\022\220#\220R\220q\330\020\022\220%\220r\230\021\330\020\022\220#\220R\220q\330\020\022\220#\220R\220q\330\020\022\220#\220R\220q\330\020\022\220%\220r\230\021\330\020\022\220#\220R\220q\330\020\022\220#\220R\220q\330\020\022\220!\330\020\022\220$\220b\230\003\2302\230Q\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\003\2302\230Q\330\020\022\220$\220b\230\001\330\020\022\220#\220R\220t\2302\230Q\330\020\022\220$\220b\230\004\230B\230a\340\014\016\210a\330\014\016\210a\330\014\r\330\020\025\220R\220q\330\020\022\220%\220r\230\021\330\020\022\220%\220r\230\021\330\020\022\220#\220R\220q\330\020\022\220!\330\020\022\220$\220b\230\001\330\020\022\220#\220R\220q\330\020\022\220$\220b\230\001\340\014\016\210a\330\014\016\210a\330\014\r\330\020\023\2202\220Q\330\020\022\220!\330\020\022\220%\220r\230\021\330\020\022\220%\220r\230\021\330\020\022\220#\220R\220q\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\004\230B\230a""\330\020\022\220#\220R\220q\330\020\022\220#\220R\220s\230\"\230A\330\020\022\220#\220R\220q\330\020\022\220#\220R\220q\340\014\016\210a\340\010\014\210A\330\014\r\210U\220\"\220E\230\022\2301\330\014\016\210e\2202\220T\230\022\2301\330\014\016\210e\2202\220S\230\002\230!\330\014\016\210b\220\002\220%\220s\230$\230b\240\005\240R\240q\330\014\016\210e\2203\220d\230\"\230D\240\002\240$\240b\250\001\330\014\016\210c\220\023\220E\230\022\2303\230b\240\005\240R\240s\250\"\250E\260\022\2603\260b\270\005\270R\270q\330\014\016\210d\220\"\220D\230\002\230!\330\014\016\210d\220#\220T\230\022\2304\230r\240\025\240b\250\001\330\014\016\210a\330\014\017\210u\220B\220c\230\022\2305\240\002\240#\240R\240t\2502\250S\260\002\260$\260b\270\003\2702\270T\300\022\3004\300r\310\023\310B\310a\330\014\016\210a\330\014\016\210a\330\014\r\330\020\025\220R\220q\330\020\022\220%\220r\230\021\330\020\022\220%\220r\230\021\330\020\022\220%\220r\230\021\330\020\022\220#\220R\220q\330\020\022\220#\220R\220q\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220#\220R\220q\330\020\022\220!\330\020\022\220%\220r\230\021\330\020\022\220%\220r\230\021\330\020\022\220$\220b\230\004\230B\230a\330\020\022\220$\220b\230\004\230B\230a\330\020\022\220$\220b\230\004\230B\230a\330\020\022\220#\220R\220t\2302\230Q\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\340\014\016\210a\330\014\016\210a\330\014\r\330\020\023\2202\220Q\330\020\022\220#\220R\220q\330\020\022\220#\220R\220q\330\020\022\220!\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220#\220R\220t\2302\230Q\330\020\022\220#\220R\220t\2302\230Q\340\014\016\210a\330\014\016\210b\220\002\220#\220R\220s\230#\230T\240\022\2404\240r\250\023\250B\250d\260\"\260A\330\014\016\210a\330\014\r\330\020\025\220R\220q\330\020\022\220#\220R\220q\330\020\022\220\"\220B\220a\330\020\022\220#\220R\220q\330\020\022\220#\220R\220q\330\020\022\220#\220R\220q\330\020\022\220!\330\020""\022\220%\220r\230\021\330\020\022\220%\220r\230\023\230B\230a\330\020\022\220$\220b\230\004\230B\230a\330\020\022\220!\330\020\022\220#\220R\220t\2302\230Q\330\020\022\220$\220b\230\001\340\014\016\210a\200A\360 \000\t\r\210E\220\024\320\025&\240a\330\010\014\210E\220\021\340\010\r\210S\220\002\220!\330\010\r\210S\220\002\220!\330\010\r\210R\210r\220\021\330\010\r\210S\220\002\220!\330\010\r\210S\220\002\220!\330\010\r\210S\220\002\220!\330\010\r\210R\210r\220\021\330\010\r\210R\210r\220\021\330\010\r\210R\210r\220\021\330\010\r\210R\210r\220\021\330\010\016\210b\220\002\220!\330\010\016\210b\220\002\220!\330\010\016\210b\220\002\220!\340\010\014\210I\220Q\220c\230\022\2302\230R\230s\240\"\240B\240b\250\003\2503\250c\260\022\2604\260r\270\021\330\010\014\210L\230\001\230\023\230B\230c\240\022\2402\240R\240s\250\"\250B\250b\260\003\2602\260S\270\002\270\"\270B\270c\300\023\300C\300r\310\024\310R\310q\330\010\014\210A\330\014\r\210S\220\002\220#\220R\220r\230\022\2303\230b\240\003\2402\240R\240r\250\023\250B\250c\260\022\2602\260R\260s\270#\270S\300\002\300#\300R\300s\310\"\310D\320PR\320RS\340\010\014\210A\330\014\r\210T\220\022\2203\220b\230\001\330\014\016\210d\220\"\220C\220r\230\021\330\014\016\210c\220\022\2203\220b\230\001\330\014\016\210c\220\022\2203\220b\230\003\2302\230Q\330\014\016\210b\220\002\220\"\220C\220r\230\022\2303\230b\240\004\240B\240a\340\010\014\210A\330\014\r\210S\220\002\220#\220R\220q\330\014\016\210c\220\022\2203\220b\230\001\330\014\016\210c\220\022\2203\220b\230\001\330\014\016\210c\220\023\220C\220r\230\023\230B\230b\240\002\240#\240R\240t\2502\250Q\330\014\016\210c\220\022\2203\220c\230\023\230B\230d\240\"\240A\340\010\014\210A\330\014\r\210S\220\002\220#\220R\220q\330\014\016\210c\220\022\2203\220b\230\001\330\014\016\210d\220\"\220C\220r\230\021\330\014\016\210d\220\"\220C\220r\230\021\330\014\016\210c\220\023\220D\230\002\230$\230b\240\003\2402\240S\250\002\250#\250R\250t\2602\260Q\200A\330\010\014\210O\2301\200A\330\010\r\210T\320""\021\"\240!\330\010\013\2103\210c\220\024\220Q\330\014\022\320\022\"\240!\2401\200A\330\010\r\210T\320\021\"\240!\330\010\013\2103\210c\220\024\220Q\330\014\020\220\010\230\001\230\024\230Q\200A\360t\001\000\t\r\210E\220\024\320\025&\240a\330\010\014\210E\220\021\330\010\014\210E\220\021\340\010\r\210R\210r\220\021\330\010\r\210S\220\002\220!\330\010\r\210S\220\002\220!\330\010\r\210R\210r\220\021\330\010\r\210R\210r\220\021\330\010\r\210R\210r\220\021\330\010\r\210R\210r\220\021\330\010\r\210R\210r\220\021\330\010\r\210R\210r\220\021\330\010\r\210S\220\002\220!\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2203\220b\230\001\330\010\016\210c\220\022\2201\330\010\016\210b\220\002\220!\330\010\016\210b\220\002\220!\330\010\016\210b\220\002\220!\330\010\016\210d\220\"\220A\330\010\016\210b\220\002\220!\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210b\220\002\220!\330\010\016\210b\220\002\220!\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2203\220b\230\001\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2203\220b\230\001\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210b\220\002\220#\220R\220q\330\010\016\210d\220\"\220A\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\330\010\016\210b\220\002\220!\330\010\016\210b\220\002\220$\220b\230\003\2302\230Q\330\010\016\210b\220\002\220\"\220B\220a\330\010\016\210b\220\002\220!\330\010\016\210b\220\002\220!\330\010\016\210c\220\022\2201\330\010\016\210c\220\022\2201\340\010\014\210A\330\014\r\210S""\220\002\220!\330\014\016\210c\220\022\2201\330\014\016\210c\220\023\220C\220r\230\023\230B\230d\240\"\240A\330\014\016\210c\220\022\2203\220b\230\001\330\014\016\210c\220\023\220C\220r\230\024\230R\230q\340\010\014\210A\330\014\r\210T\220\023\220A\220T\230\022\2304\230r\240\021\330\014\016\210d\220#\220T\230\022\2303\230b\240\004\240B\240a\330\014\016\210c\220\022\2203\220b\230\001\330\014\016\210c\220\022\2203\220b\230\001\330\014\016\210c\220\022\2203\220b\230\001\330\014\016\210c\220\023\220D\230\002\230$\230b\240\004\240B\240c\250\022\2505\260\002\260!\330\014\016\210c\220\023\220D\230\002\230\"\230B\230c\240\022\2404\240r\250\021\340\010\014\210A\330\014\r\210T\220\022\2201\330\014\016\210d\220\"\220C\220r\230\021\330\014\016\210d\220\"\220A\330\014\016\210d\220#\220T\230\022\2304\230r\240\021\330\014\016\210c\220\023\220C\220r\230\023\230B\230d\240\"\240D\250\002\250$\250b\260\004\260B\260c\270\022\2704\270r\300\021\330\014\016\210c\220\022\2203\220c\230\024\230R\230t\2402\240Q\330\014\016\210c\220\023\220C\220r\230\025\230b\240\001\340\010\014\210A\330\014\020\220\003\2203\220b\230\002\230\"\230D\240\002\240$\240b\250\003\2502\250T\260\022\2603\260b\270\004\270B\270a\330\014\016\210b\220\002\220$\220b\230\003\2302\230Q\330\014\016\210d\220\"\220D\230\002\230!\330\014\016\210d\220\"\220C\220r\230\021\330\014\016\210d\220#\220S\230\002\230\"\230B\230d\240\"\240A\330\014\016\210c\220\022\2203\220c\230\023\230B\230e\2402\240Q\330\014\016\210b\220\002\220\"\220C\220t\2302\230S\240\002\240#\240R\240t\2502\250Q\330\014\016\210a\330\014\r\330\020\023\2202\220Q\330\020\022\220$\220b\230\001\330\020\022\220#\220R\220q\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220!\330\020\022\220!\330\020\022\220#\220R\220q\340\014\016\210a\330\014\016\210c\220\023\220B\220b\230\004\230B\230b\240\002\240$\240b\250\004\250B\250d\260\"\260D\270\002\270!\340\010\014\210A\330\014\020\220\003\2204\220r\230\023\230B\230b\240\002\240$\240b\250\004\250B\250d\260""\"\260D\270\002\270#\270R\270t\3002\300T\310\022\3104\310r\320QR\330\014\016\210d\220\"\220C\220s\230$\230b\240\005\240R\240q\330\014\016\210d\220\"\220C\220r\230\021\330\014\016\210d\220#\220T\230\022\2304\230r\240\023\240B\240b\250\002\250$\250b\260\001\330\014\016\210d\220\"\220C\220r\230\023\230B\230a\330\014\016\210d\220\"\220C\220r\230\021\330\014\016\210c\220\022\2203\220c\230\024\230R\230t\2402\240Q\330\014\016\210a\330\014\r\330\020\021\220\024\220R\220q\330\020\022\220$\220b\230\001\330\020\022\220!\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220!\340\014\016\210a\330\014\016\210c\220\023\220D\230\002\230#\230R\230t\2402\240S\250\002\250$\250b\260\004\260B\260d\270\"\270E\300\022\3001\340\010\014\210A\330\014\r\210S\220\002\220$\220b\230\001\330\014\016\210d\220\"\220D\230\002\230!\330\014\016\210d\220#\220T\230\022\2304\230r\240\024\240R\240t\2502\250Q\330\014\016\210d\220\"\220C\220r\230\021\330\014\016\210d\220\"\220C\220r\230\021\330\014\016\210d\220#\220T\230\022\2304\230r\240\021\330\014\016\210a\330\014\r\330\020\024\220B\220a\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220$\220b\230\001\330\020\022\220!\330\020\022\220\"\220B\220a\330\020\022\220#\220R\220q\340\014\016\210a\330\014\016\210c\220\022\2203\220c\230\024\230R\230t\2402\240S\250\002\250$\250b\260\001\330\014\016\210c\220\023\220D\230\002\230$\230b\240\003\2402\240T\250\022\2504\250r\260\023\260B\260e\2702\270Q\320\004\027\220q\330\010\017\210y\230\001\230\026\230q\340\010\014\210H\220A\330\010\014\210K\220q\330\010\014\210K\220q\330\010\014\210L\230\001\330\010\014\210L\230\001\330\010\014\210L\230\001"; + PyObject *data = NULL; + CYTHON_UNUSED_VAR(__Pyx_DecompressString); + #endif + PyObject **stringtab = __pyx_mstate->__pyx_string_tab; + Py_ssize_t pos = 0; + for (int i = 0; i < 203; i++) { + Py_ssize_t bytes_length = index[i].length; + PyObject *string = PyUnicode_DecodeUTF8(bytes + pos, bytes_length, NULL); + if (likely(string) && i >= 4) PyUnicode_InternInPlace(&string); + if (unlikely(!string)) { + Py_XDECREF(data); + __PYX_ERR(0, 1, __pyx_L1_error) + } + stringtab[i] = string; + pos += bytes_length; + } + for (int i = 203; i < 210; i++) { + Py_ssize_t bytes_length = index[i].length; + PyObject *string = PyBytes_FromStringAndSize(bytes + pos, bytes_length); + stringtab[i] = string; + pos += bytes_length; + if (unlikely(!string)) { + Py_XDECREF(data); + __PYX_ERR(0, 1, __pyx_L1_error) + } + } + Py_XDECREF(data); + for (Py_ssize_t i = 0; i < 210; i++) { + if (unlikely(PyObject_Hash(stringtab[i]) == -1)) { + __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #if CYTHON_IMMORTAL_CONSTANTS + { + PyObject **table = stringtab + 203; + for (Py_ssize_t i=0; i<7; ++i) { + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL); + #else + Py_SET_REFCNT(table[i], _Py_IMMORTAL_INITIAL_REFCNT); + #endif + } + } + #endif + } + { + PyObject **numbertab = __pyx_mstate->__pyx_number_tab + 0; + int8_t const cint_constants_1[] = {0,1,2}; + for (int i = 0; i < 3; i++) { + numbertab[i] = PyLong_FromLong(cint_constants_1[i - 0]); + if (unlikely(!numbertab[i])) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #if CYTHON_IMMORTAL_CONSTANTS + { + PyObject **table = __pyx_mstate->__pyx_number_tab; + for (Py_ssize_t i=0; i<3; ++i) { + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL); + #else + Py_SET_REFCNT(table[i], _Py_IMMORTAL_INITIAL_REFCNT); + #endif + } + } + #endif + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: init_codeobjects ### */ +typedef struct { + unsigned int argcount : 3; + unsigned int num_posonly_args : 1; + unsigned int num_kwonly_args : 1; + unsigned int nlocals : 8; + unsigned int flags : 10; + unsigned int first_line : 9; +} __Pyx_PyCode_New_function_description; +/* NewCodeObj.proto */ +static PyObject* __Pyx_PyCode_New( + const __Pyx_PyCode_New_function_description descr, + PyObject * const *varnames, + PyObject *filename, + PyObject *funcname, + PyObject *line_table, + PyObject *tuple_dedup_map +); + + +static int __Pyx_CreateCodeObjects(__pyx_mstatetype *__pyx_mstate) { + PyObject* tuple_dedup_map = PyDict_New(); + if (unlikely(!tuple_dedup_map)) return -1; + { + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 2, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 16}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_glyphset}; + __pyx_mstate_global->__pyx_codeobj_tab[0] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_pens_momentsPen_py, __pyx_mstate->__pyx_n_u_init, __pyx_mstate->__pyx_kp_b_iso88591_q_y_q_HA_Kq_Kq_L_L_L, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[0])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 2, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 26}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_p0}; + __pyx_mstate_global->__pyx_codeobj_tab[1] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_pens_momentsPen_py, __pyx_mstate->__pyx_n_u_moveTo, __pyx_mstate->__pyx_kp_b_iso88591_A_O1, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[1])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 2, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 29}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_p0}; + __pyx_mstate_global->__pyx_codeobj_tab[2] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_pens_momentsPen_py, __pyx_mstate->__pyx_n_u_closePath, __pyx_mstate->__pyx_kp_b_iso88591_A_T_3c_Q_Q, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[2])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {1, 0, 0, 2, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 34}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_p0}; + __pyx_mstate_global->__pyx_codeobj_tab[3] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_pens_momentsPen_py, __pyx_mstate->__pyx_n_u_endPath, __pyx_mstate->__pyx_kp_b_iso88591_A_T_3c_Q_1, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[3])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 19, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 39}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_p1, __pyx_mstate->__pyx_n_u_x1, __pyx_mstate->__pyx_n_u_y1, __pyx_mstate->__pyx_n_u_x0, __pyx_mstate->__pyx_n_u_y0, __pyx_mstate->__pyx_n_u_r12, __pyx_mstate->__pyx_n_u_r11, __pyx_mstate->__pyx_n_u_r10, __pyx_mstate->__pyx_n_u_r9, __pyx_mstate->__pyx_n_u_r8, __pyx_mstate->__pyx_n_u_r7, __pyx_mstate->__pyx_n_u_r6, __pyx_mstate->__pyx_n_u_r5, __pyx_mstate->__pyx_n_u_r4, __pyx_mstate->__pyx_n_u_r3, __pyx_mstate->__pyx_n_u_r2, __pyx_mstate->__pyx_n_u_r1, __pyx_mstate->__pyx_n_u_r0}; + __pyx_mstate_global->__pyx_codeobj_tab[4] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_pens_momentsPen_py, __pyx_mstate->__pyx_n_u_lineTo, __pyx_mstate->__pyx_kp_b_iso88591_A_E_a_E_S_S_Rr_S_S_S_Rr_Rr_Rr_Rr, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[4])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {3, 0, 0, 63, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 99}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_p1, __pyx_mstate->__pyx_n_u_p2, __pyx_mstate->__pyx_n_u_x2, __pyx_mstate->__pyx_n_u_y2, __pyx_mstate->__pyx_n_u_x1, __pyx_mstate->__pyx_n_u_y1, __pyx_mstate->__pyx_n_u_x0, __pyx_mstate->__pyx_n_u_y0, __pyx_mstate->__pyx_n_u_r53, __pyx_mstate->__pyx_n_u_r52, __pyx_mstate->__pyx_n_u_r51, __pyx_mstate->__pyx_n_u_r50, __pyx_mstate->__pyx_n_u_r49, __pyx_mstate->__pyx_n_u_r48, __pyx_mstate->__pyx_n_u_r47, __pyx_mstate->__pyx_n_u_r46, __pyx_mstate->__pyx_n_u_r45, __pyx_mstate->__pyx_n_u_r44, __pyx_mstate->__pyx_n_u_r43, __pyx_mstate->__pyx_n_u_r42, __pyx_mstate->__pyx_n_u_r41, __pyx_mstate->__pyx_n_u_r40, __pyx_mstate->__pyx_n_u_r39, __pyx_mstate->__pyx_n_u_r38, __pyx_mstate->__pyx_n_u_r37, __pyx_mstate->__pyx_n_u_r36, __pyx_mstate->__pyx_n_u_r35, __pyx_mstate->__pyx_n_u_r34, __pyx_mstate->__pyx_n_u_r33, __pyx_mstate->__pyx_n_u_r32, __pyx_mstate->__pyx_n_u_r31, __pyx_mstate->__pyx_n_u_r30, __pyx_mstate->__pyx_n_u_r29, __pyx_mstate->__pyx_n_u_r28, __pyx_mstate->__pyx_n_u_r27, __pyx_mstate->__pyx_n_u_r26, __pyx_mstate->__pyx_n_u_r25, __pyx_mstate->__pyx_n_u_r24, __pyx_mstate->__pyx_n_u_r23, __pyx_mstate->__pyx_n_u_r22, __pyx_mstate->__pyx_n_u_r21, __pyx_mstate->__pyx_n_u_r20, __pyx_mstate->__pyx_n_u_r19, __pyx_mstate->__pyx_n_u_r18, __pyx_mstate->__pyx_n_u_r17, __pyx_mstate->__pyx_n_u_r16, __pyx_mstate->__pyx_n_u_r15, __pyx_mstate->__pyx_n_u_r14, __pyx_mstate->__pyx_n_u_r13, __pyx_mstate->__pyx_n_u_r12, __pyx_mstate->__pyx_n_u_r11, __pyx_mstate->__pyx_n_u_r10, __pyx_mstate->__pyx_n_u_r9, __pyx_mstate->__pyx_n_u_r8, __pyx_mstate->__pyx_n_u_r7, __pyx_mstate->__pyx_n_u_r6, __pyx_mstate->__pyx_n_u_r5, __pyx_mstate->__pyx_n_u_r4, __pyx_mstate->__pyx_n_u_r3, __pyx_mstate->__pyx_n_u_r2, __pyx_mstate->__pyx_n_u_r1, __pyx_mstate->__pyx_n_u_r0}; + __pyx_mstate_global->__pyx_codeobj_tab[5] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_pens_momentsPen_py, __pyx_mstate->__pyx_n_u_qCurveToOne, __pyx_mstate->__pyx_kp_b_iso88591_At_E_a_E_E_Rr_S_S_Rr_Rr_Rr_Rr_Rr, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[5])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 145, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 310}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_p1, __pyx_mstate->__pyx_n_u_p2, __pyx_mstate->__pyx_n_u_p3, __pyx_mstate->__pyx_n_u_x3, __pyx_mstate->__pyx_n_u_y3, __pyx_mstate->__pyx_n_u_x2, __pyx_mstate->__pyx_n_u_y2, __pyx_mstate->__pyx_n_u_x1, __pyx_mstate->__pyx_n_u_y1, __pyx_mstate->__pyx_n_u_x0, __pyx_mstate->__pyx_n_u_y0, __pyx_mstate->__pyx_n_u_r132, __pyx_mstate->__pyx_n_u_r131, __pyx_mstate->__pyx_n_u_r130, __pyx_mstate->__pyx_n_u_r129, __pyx_mstate->__pyx_n_u_r128, __pyx_mstate->__pyx_n_u_r127, __pyx_mstate->__pyx_n_u_r126, __pyx_mstate->__pyx_n_u_r125, __pyx_mstate->__pyx_n_u_r124, __pyx_mstate->__pyx_n_u_r123, __pyx_mstate->__pyx_n_u_r122, __pyx_mstate->__pyx_n_u_r121, __pyx_mstate->__pyx_n_u_r120, __pyx_mstate->__pyx_n_u_r119, __pyx_mstate->__pyx_n_u_r118, __pyx_mstate->__pyx_n_u_r117, __pyx_mstate->__pyx_n_u_r116, __pyx_mstate->__pyx_n_u_r115, __pyx_mstate->__pyx_n_u_r114, __pyx_mstate->__pyx_n_u_r113, __pyx_mstate->__pyx_n_u_r112, __pyx_mstate->__pyx_n_u_r111, __pyx_mstate->__pyx_n_u_r110, __pyx_mstate->__pyx_n_u_r109, __pyx_mstate->__pyx_n_u_r108, __pyx_mstate->__pyx_n_u_r107, __pyx_mstate->__pyx_n_u_r106, __pyx_mstate->__pyx_n_u_r105, __pyx_mstate->__pyx_n_u_r104, __pyx_mstate->__pyx_n_u_r103, __pyx_mstate->__pyx_n_u_r102, __pyx_mstate->__pyx_n_u_r101, __pyx_mstate->__pyx_n_u_r100, __pyx_mstate->__pyx_n_u_r99, __pyx_mstate->__pyx_n_u_r98, __pyx_mstate->__pyx_n_u_r97, __pyx_mstate->__pyx_n_u_r96, __pyx_mstate->__pyx_n_u_r95, __pyx_mstate->__pyx_n_u_r94, __pyx_mstate->__pyx_n_u_r93, __pyx_mstate->__pyx_n_u_r92, __pyx_mstate->__pyx_n_u_r91, __pyx_mstate->__pyx_n_u_r90, __pyx_mstate->__pyx_n_u_r89, __pyx_mstate->__pyx_n_u_r88, __pyx_mstate->__pyx_n_u_r87, __pyx_mstate->__pyx_n_u_r86, __pyx_mstate->__pyx_n_u_r85, __pyx_mstate->__pyx_n_u_r84, __pyx_mstate->__pyx_n_u_r83, __pyx_mstate->__pyx_n_u_r82, __pyx_mstate->__pyx_n_u_r81, __pyx_mstate->__pyx_n_u_r80, __pyx_mstate->__pyx_n_u_r79, __pyx_mstate->__pyx_n_u_r78, __pyx_mstate->__pyx_n_u_r77, __pyx_mstate->__pyx_n_u_r76, __pyx_mstate->__pyx_n_u_r75, __pyx_mstate->__pyx_n_u_r74, __pyx_mstate->__pyx_n_u_r73, __pyx_mstate->__pyx_n_u_r72, __pyx_mstate->__pyx_n_u_r71, __pyx_mstate->__pyx_n_u_r70, __pyx_mstate->__pyx_n_u_r69, __pyx_mstate->__pyx_n_u_r68, __pyx_mstate->__pyx_n_u_r67, __pyx_mstate->__pyx_n_u_r66, __pyx_mstate->__pyx_n_u_r65, __pyx_mstate->__pyx_n_u_r64, __pyx_mstate->__pyx_n_u_r63, __pyx_mstate->__pyx_n_u_r62, __pyx_mstate->__pyx_n_u_r61, __pyx_mstate->__pyx_n_u_r60, __pyx_mstate->__pyx_n_u_r59, __pyx_mstate->__pyx_n_u_r58, __pyx_mstate->__pyx_n_u_r57, __pyx_mstate->__pyx_n_u_r56, __pyx_mstate->__pyx_n_u_r55, __pyx_mstate->__pyx_n_u_r54, __pyx_mstate->__pyx_n_u_r53, __pyx_mstate->__pyx_n_u_r52, __pyx_mstate->__pyx_n_u_r51, __pyx_mstate->__pyx_n_u_r50, __pyx_mstate->__pyx_n_u_r49, __pyx_mstate->__pyx_n_u_r48, __pyx_mstate->__pyx_n_u_r47, __pyx_mstate->__pyx_n_u_r46, __pyx_mstate->__pyx_n_u_r45, __pyx_mstate->__pyx_n_u_r44, __pyx_mstate->__pyx_n_u_r43, __pyx_mstate->__pyx_n_u_r42, __pyx_mstate->__pyx_n_u_r41, __pyx_mstate->__pyx_n_u_r40, __pyx_mstate->__pyx_n_u_r39, __pyx_mstate->__pyx_n_u_r38, __pyx_mstate->__pyx_n_u_r37, __pyx_mstate->__pyx_n_u_r36, __pyx_mstate->__pyx_n_u_r35, __pyx_mstate->__pyx_n_u_r34, __pyx_mstate->__pyx_n_u_r33, __pyx_mstate->__pyx_n_u_r32, __pyx_mstate->__pyx_n_u_r31, __pyx_mstate->__pyx_n_u_r30, __pyx_mstate->__pyx_n_u_r29, __pyx_mstate->__pyx_n_u_r28, __pyx_mstate->__pyx_n_u_r27, __pyx_mstate->__pyx_n_u_r26, __pyx_mstate->__pyx_n_u_r25, __pyx_mstate->__pyx_n_u_r24, __pyx_mstate->__pyx_n_u_r23, __pyx_mstate->__pyx_n_u_r22, __pyx_mstate->__pyx_n_u_r21, __pyx_mstate->__pyx_n_u_r20, __pyx_mstate->__pyx_n_u_r19, __pyx_mstate->__pyx_n_u_r18, __pyx_mstate->__pyx_n_u_r17, __pyx_mstate->__pyx_n_u_r16, __pyx_mstate->__pyx_n_u_r15, __pyx_mstate->__pyx_n_u_r14, __pyx_mstate->__pyx_n_u_r13, __pyx_mstate->__pyx_n_u_r12, __pyx_mstate->__pyx_n_u_r11, __pyx_mstate->__pyx_n_u_r10, __pyx_mstate->__pyx_n_u_r9, __pyx_mstate->__pyx_n_u_r8, __pyx_mstate->__pyx_n_u_r7, __pyx_mstate->__pyx_n_u_r6, __pyx_mstate->__pyx_n_u_r5, __pyx_mstate->__pyx_n_u_r4, __pyx_mstate->__pyx_n_u_r3, __pyx_mstate->__pyx_n_u_r2, __pyx_mstate->__pyx_n_u_r1, __pyx_mstate->__pyx_n_u_r0}; + __pyx_mstate_global->__pyx_codeobj_tab[6] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_Lib_fontTools_pens_momentsPen_py, __pyx_mstate->__pyx_n_u_curveToOne, __pyx_mstate->__pyx_kp_b_iso88591_AT_E_a_E_E_E_Rr_S_S_S_Rr_Rr_Rr_R, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[6])) goto bad; + } + Py_DECREF(tuple_dedup_map); + return 0; + bad: + Py_DECREF(tuple_dedup_map); + return -1; +} +/* #### Code section: init_globals ### */ + +static int __Pyx_InitGlobals(void) { + /* PythonCompatibility.init */ + if (likely(__Pyx_init_co_variables() == 0)); else + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* CommonTypesMetaclass.init */ + if (likely(__pyx_CommonTypesMetaclass_init(__pyx_m) == 0)); else + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* CachedMethodType.init */ + #if CYTHON_COMPILING_IN_LIMITED_API + { + PyObject *typesModule=NULL; + typesModule = PyImport_ImportModule("types"); + if (typesModule) { + __pyx_mstate_global->__Pyx_CachedMethodType = PyObject_GetAttrString(typesModule, "MethodType"); + Py_DECREF(typesModule); + } + } // error handling follows + #endif + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* CythonFunctionShared.init */ + if (likely(__pyx_CyFunction_init(__pyx_m) == 0)); else + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: cleanup_globals ### */ +/* #### Code section: cleanup_module ### */ +/* #### Code section: main_method ### */ +/* #### Code section: utility_code_pragmas ### */ +#ifdef _MSC_VER +#pragma warning( push ) +/* Warning 4127: conditional expression is constant + * Cython uses constant conditional expressions to allow in inline functions to be optimized at + * compile-time, so this warning is not useful + */ +#pragma warning( disable : 4127 ) +#endif + + + +/* #### Code section: utility_code_def ### */ + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* TupleAndListFromArray (used by fastcall) */ +#if !CYTHON_COMPILING_IN_CPYTHON && CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + Py_ssize_t i; + if (n <= 0) { + return __Pyx_NewRef(__pyx_mstate_global->__pyx_empty_tuple); + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + for (i = 0; i < n; i++) { + if (unlikely(__Pyx_PyTuple_SET_ITEM(res, i, src[i]) < (0))) { + Py_DECREF(res); + return NULL; + } + Py_INCREF(src[i]); + } + return res; +} +#elif CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE void __Pyx_copy_object_array(PyObject *const *CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) { + PyObject *v; + Py_ssize_t i; + for (i = 0; i < length; i++) { + v = dest[i] = src[i]; + Py_INCREF(v); + } +} +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return __Pyx_NewRef(__pyx_mstate_global->__pyx_empty_tuple); + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyTupleObject*)res)->ob_item, n); + return res; +} +static CYTHON_INLINE PyObject * +__Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return PyList_New(0); + } + res = PyList_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyListObject*)res)->ob_item, n); + return res; +} +#endif + +/* BytesEquals (used by UnicodeEquals) */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_GRAAL ||\ + !(CYTHON_ASSUME_SAFE_SIZE && CYTHON_ASSUME_SAFE_MACROS) + return PyObject_RichCompareBool(s1, s2, equals); +#else + if (s1 == s2) { + return (equals == Py_EQ); + } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { + const char *ps1, *ps2; + Py_ssize_t length = PyBytes_GET_SIZE(s1); + if (length != PyBytes_GET_SIZE(s2)) + return (equals == Py_NE); + ps1 = PyBytes_AS_STRING(s1); + ps2 = PyBytes_AS_STRING(s2); + if (ps1[0] != ps2[0]) { + return (equals == Py_NE); + } else if (length == 1) { + return (equals == Py_EQ); + } else { + int result; +#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) + Py_hash_t hash1, hash2; + hash1 = ((PyBytesObject*)s1)->ob_shash; + hash2 = ((PyBytesObject*)s2)->ob_shash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + return (equals == Py_NE); + } +#endif + result = memcmp(ps1, ps2, (size_t)length); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { + return (equals == Py_NE); + } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { + return (equals == Py_NE); + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +#endif +} + +/* UnicodeEquals (used by fastcall) */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_GRAAL + return PyObject_RichCompareBool(s1, s2, equals); +#else + int s1_is_unicode, s2_is_unicode; + if (s1 == s2) { + goto return_eq; + } + s1_is_unicode = PyUnicode_CheckExact(s1); + s2_is_unicode = PyUnicode_CheckExact(s2); + if (s1_is_unicode & s2_is_unicode) { + Py_ssize_t length, length2; + int kind; + void *data1, *data2; + #if !CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) + return -1; + #endif + length = __Pyx_PyUnicode_GET_LENGTH(s1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(length < 0)) return -1; + #endif + length2 = __Pyx_PyUnicode_GET_LENGTH(s2); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(length2 < 0)) return -1; + #endif + if (length != length2) { + goto return_ne; + } +#if CYTHON_USE_UNICODE_INTERNALS + { + Py_hash_t hash1, hash2; + hash1 = ((PyASCIIObject*)s1)->hash; + hash2 = ((PyASCIIObject*)s2)->hash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + goto return_ne; + } + } +#endif + kind = __Pyx_PyUnicode_KIND(s1); + if (kind != __Pyx_PyUnicode_KIND(s2)) { + goto return_ne; + } + data1 = __Pyx_PyUnicode_DATA(s1); + data2 = __Pyx_PyUnicode_DATA(s2); + if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { + goto return_ne; + } else if (length == 1) { + goto return_eq; + } else { + int result = memcmp(data1, data2, (size_t)(length * kind)); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & s2_is_unicode) { + goto return_ne; + } else if ((s2 == Py_None) & s1_is_unicode) { + goto return_ne; + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +return_eq: + return (equals == Py_EQ); +return_ne: + return (equals == Py_NE); +#endif +} + +/* fastcall */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s) +{ + Py_ssize_t i, n = __Pyx_PyTuple_GET_SIZE(kwnames); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(n == -1)) return NULL; + #endif + for (i = 0; i < n; i++) + { + PyObject *namei = __Pyx_PyTuple_GET_ITEM(kwnames, i); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(!namei)) return NULL; + #endif + if (s == namei) return kwvalues[i]; + } + for (i = 0; i < n; i++) + { + PyObject *namei = __Pyx_PyTuple_GET_ITEM(kwnames, i); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(!namei)) return NULL; + #endif + int eq = __Pyx_PyUnicode_Equals(s, namei, Py_EQ); + if (unlikely(eq != 0)) { + if (unlikely(eq < 0)) return NULL; + return kwvalues[i]; + } + } + return NULL; +} +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 || CYTHON_COMPILING_IN_LIMITED_API +CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues) { + Py_ssize_t i, nkwargs; + PyObject *dict; +#if !CYTHON_ASSUME_SAFE_SIZE + nkwargs = PyTuple_Size(kwnames); + if (unlikely(nkwargs < 0)) return NULL; +#else + nkwargs = PyTuple_GET_SIZE(kwnames); +#endif + dict = PyDict_New(); + if (unlikely(!dict)) + return NULL; + for (i=0; itp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallMethO (used by PyObjectFastCall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = __Pyx_CyOrPyCFunction_GET_FUNCTION(func); + self = __Pyx_CyOrPyCFunction_GET_SELF(func); + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectFastCall (used by PyObjectCallOneArg) */ +#if PY_VERSION_HEX < 0x03090000 || CYTHON_COMPILING_IN_LIMITED_API +static PyObject* __Pyx_PyObject_FastCall_fallback(PyObject *func, PyObject * const*args, size_t nargs, PyObject *kwargs) { + PyObject *argstuple; + PyObject *result = 0; + size_t i; + argstuple = PyTuple_New((Py_ssize_t)nargs); + if (unlikely(!argstuple)) return NULL; + for (i = 0; i < nargs; i++) { + Py_INCREF(args[i]); + if (__Pyx_PyTuple_SET_ITEM(argstuple, (Py_ssize_t)i, args[i]) != (0)) goto bad; + } + result = __Pyx_PyObject_Call(func, argstuple, kwargs); + bad: + Py_DECREF(argstuple); + return result; +} +#endif +#if CYTHON_VECTORCALL && !CYTHON_COMPILING_IN_LIMITED_API + #if PY_VERSION_HEX < 0x03090000 + #define __Pyx_PyVectorcall_Function(callable) _PyVectorcall_Function(callable) + #elif CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE vectorcallfunc __Pyx_PyVectorcall_Function(PyObject *callable) { + PyTypeObject *tp = Py_TYPE(callable); + #if defined(__Pyx_CyFunction_USED) + if (__Pyx_CyFunction_CheckExact(callable)) { + return __Pyx_CyFunction_func_vectorcall(callable); + } + #endif + if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) { + return NULL; + } + assert(PyCallable_Check(callable)); + Py_ssize_t offset = tp->tp_vectorcall_offset; + assert(offset > 0); + vectorcallfunc ptr; + memcpy(&ptr, (char *) callable + offset, sizeof(ptr)); + return ptr; +} + #else + #define __Pyx_PyVectorcall_Function(callable) PyVectorcall_Function(callable) + #endif +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject *const *args, size_t _nargs, PyObject *kwargs) { + Py_ssize_t nargs = __Pyx_PyVectorcall_NARGS(_nargs); +#if CYTHON_COMPILING_IN_CPYTHON + if (nargs == 0 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_NOARGS)) + return __Pyx_PyObject_CallMethO(func, NULL); + } + else if (nargs == 1 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_O)) + return __Pyx_PyObject_CallMethO(func, args[0]); + } +#endif + if (kwargs == NULL) { + #if CYTHON_VECTORCALL + #if CYTHON_COMPILING_IN_LIMITED_API + return PyObject_Vectorcall(func, args, _nargs, NULL); + #else + vectorcallfunc f = __Pyx_PyVectorcall_Function(func); + if (f) { + return f(func, args, _nargs, NULL); + } + #endif + #endif + } + if (nargs == 0) { + return __Pyx_PyObject_Call(func, __pyx_mstate_global->__pyx_empty_tuple, kwargs); + } + #if PY_VERSION_HEX >= 0x03090000 && !CYTHON_COMPILING_IN_LIMITED_API + return PyObject_VectorcallDict(func, args, (size_t)nargs, kwargs); + #else + return __Pyx_PyObject_FastCall_fallback(func, args, (size_t)nargs, kwargs); + #endif +} + +/* PyObjectCallOneArg (used by CallUnboundCMethod0) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *args[2] = {NULL, arg}; + return __Pyx_PyObject_FastCall(func, args+1, 1 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectGetAttrStr (used by UnpackUnboundCMethod) */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* UnpackUnboundCMethod (used by CallUnboundCMethod0) */ +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030C0000 +static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject *args, PyObject *kwargs) { + PyObject *result; + PyObject *selfless_args = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); + if (unlikely(!selfless_args)) return NULL; + result = PyObject_Call(method, selfless_args, kwargs); + Py_DECREF(selfless_args); + return result; +} +#elif CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03090000 +static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { + return _PyObject_Vectorcall + (method, args ? args+1 : NULL, nargs ? nargs-1 : 0, kwnames); +} +#else +static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { + return +#if PY_VERSION_HEX < 0x03090000 + _PyObject_Vectorcall +#else + PyObject_Vectorcall +#endif + (method, args ? args+1 : NULL, nargs ? (size_t) nargs-1 : 0, kwnames); +} +#endif +static PyMethodDef __Pyx_UnboundCMethod_Def = { + "CythonUnboundCMethod", + __PYX_REINTERPRET_FUNCION(PyCFunction, __Pyx_SelflessCall), +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030C0000 + METH_VARARGS | METH_KEYWORDS, +#else + METH_FASTCALL | METH_KEYWORDS, +#endif + NULL +}; +static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) { + PyObject *method, *result=NULL; + method = __Pyx_PyObject_GetAttrStr(target->type, *target->method_name); + if (unlikely(!method)) + return -1; + result = method; +#if CYTHON_COMPILING_IN_CPYTHON + if (likely(__Pyx_TypeCheck(method, &PyMethodDescr_Type))) + { + PyMethodDescrObject *descr = (PyMethodDescrObject*) method; + target->func = descr->d_method->ml_meth; + target->flag = descr->d_method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_STACKLESS); + } else +#endif +#if CYTHON_COMPILING_IN_PYPY +#else + if (PyCFunction_Check(method)) +#endif + { + PyObject *self; + int self_found; +#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY + self = PyObject_GetAttrString(method, "__self__"); + if (!self) { + PyErr_Clear(); + } +#else + self = PyCFunction_GET_SELF(method); +#endif + self_found = (self && self != Py_None); +#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY + Py_XDECREF(self); +#endif + if (self_found) { + PyObject *unbound_method = PyCFunction_New(&__Pyx_UnboundCMethod_Def, method); + if (unlikely(!unbound_method)) return -1; + Py_DECREF(method); + result = unbound_method; + } + } +#if !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + if (unlikely(target->method)) { + Py_DECREF(result); + } else +#endif + target->method = result; + return 0; +} + +/* CallUnboundCMethod0 */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self) { + int was_initialized = __Pyx_CachedCFunction_GetAndSetInitializing(cfunc); + if (likely(was_initialized == 2 && cfunc->func)) { + if (likely(cfunc->flag == METH_NOARGS)) + return __Pyx_CallCFunction(cfunc, self, NULL); + if (likely(cfunc->flag == METH_FASTCALL)) + return __Pyx_CallCFunctionFast(cfunc, self, NULL, 0); + if (cfunc->flag == (METH_FASTCALL | METH_KEYWORDS)) + return __Pyx_CallCFunctionFastWithKeywords(cfunc, self, NULL, 0, NULL); + if (likely(cfunc->flag == (METH_VARARGS | METH_KEYWORDS))) + return __Pyx_CallCFunctionWithKeywords(cfunc, self, __pyx_mstate_global->__pyx_empty_tuple, NULL); + if (cfunc->flag == METH_VARARGS) + return __Pyx_CallCFunction(cfunc, self, __pyx_mstate_global->__pyx_empty_tuple); + return __Pyx__CallUnboundCMethod0(cfunc, self); + } +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + else if (unlikely(was_initialized == 1)) { + __Pyx_CachedCFunction tmp_cfunc = { +#ifndef __cplusplus + 0 +#endif + }; + tmp_cfunc.type = cfunc->type; + tmp_cfunc.method_name = cfunc->method_name; + return __Pyx__CallUnboundCMethod0(&tmp_cfunc, self); + } +#endif + PyObject *result = __Pyx__CallUnboundCMethod0(cfunc, self); + __Pyx_CachedCFunction_SetFinishedInitializing(cfunc); + return result; +} +#endif +static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self) { + PyObject *result; + if (unlikely(!cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; + result = __Pyx_PyObject_CallOneArg(cfunc->method, self); + return result; +} + +/* py_dict_items (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d) { + return __Pyx_CallUnboundCMethod0(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_items, d); +} + +/* py_dict_values (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Values(PyObject* d) { + return __Pyx_CallUnboundCMethod0(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_values, d); +} + +/* OwnedDictNext (used by ParseKeywordsImpl) */ +#if CYTHON_AVOID_BORROWED_REFS +static int __Pyx_PyDict_NextRef(PyObject *p, PyObject **ppos, PyObject **pkey, PyObject **pvalue) { + PyObject *next = NULL; + if (!*ppos) { + if (pvalue) { + PyObject *dictview = pkey ? __Pyx_PyDict_Items(p) : __Pyx_PyDict_Values(p); + if (unlikely(!dictview)) goto bad; + *ppos = PyObject_GetIter(dictview); + Py_DECREF(dictview); + } else { + *ppos = PyObject_GetIter(p); + } + if (unlikely(!*ppos)) goto bad; + } + next = PyIter_Next(*ppos); + if (!next) { + if (PyErr_Occurred()) goto bad; + return 0; + } + if (pkey && pvalue) { + *pkey = __Pyx_PySequence_ITEM(next, 0); + if (unlikely(*pkey)) goto bad; + *pvalue = __Pyx_PySequence_ITEM(next, 1); + if (unlikely(*pvalue)) goto bad; + Py_DECREF(next); + } else if (pkey) { + *pkey = next; + } else { + assert(pvalue); + *pvalue = next; + } + return 1; + bad: + Py_XDECREF(next); +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d0000 + PyErr_FormatUnraisable("Exception ignored in __Pyx_PyDict_NextRef"); +#else + PyErr_WriteUnraisable(__pyx_mstate_global->__pyx_n_u_Pyx_PyDict_NextRef); +#endif + if (pkey) *pkey = NULL; + if (pvalue) *pvalue = NULL; + return 0; +} +#else // !CYTHON_AVOID_BORROWED_REFS +static int __Pyx_PyDict_NextRef(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) { + int result = PyDict_Next(p, ppos, pkey, pvalue); + if (likely(result == 1)) { + if (pkey) Py_INCREF(*pkey); + if (pvalue) Py_INCREF(*pvalue); + } + return result; +} +#endif + +/* RaiseDoubleKeywords (used by ParseKeywordsImpl) */ +static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); +} + +/* CallUnboundCMethod2 */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject *__Pyx_CallUnboundCMethod2(__Pyx_CachedCFunction *cfunc, PyObject *self, PyObject *arg1, PyObject *arg2) { + int was_initialized = __Pyx_CachedCFunction_GetAndSetInitializing(cfunc); + if (likely(was_initialized == 2 && cfunc->func)) { + PyObject *args[2] = {arg1, arg2}; + if (cfunc->flag == METH_FASTCALL) { + return __Pyx_CallCFunctionFast(cfunc, self, args, 2); + } + if (cfunc->flag == (METH_FASTCALL | METH_KEYWORDS)) + return __Pyx_CallCFunctionFastWithKeywords(cfunc, self, args, 2, NULL); + } +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + else if (unlikely(was_initialized == 1)) { + __Pyx_CachedCFunction tmp_cfunc = { +#ifndef __cplusplus + 0 +#endif + }; + tmp_cfunc.type = cfunc->type; + tmp_cfunc.method_name = cfunc->method_name; + return __Pyx__CallUnboundCMethod2(&tmp_cfunc, self, arg1, arg2); + } +#endif + PyObject *result = __Pyx__CallUnboundCMethod2(cfunc, self, arg1, arg2); + __Pyx_CachedCFunction_SetFinishedInitializing(cfunc); + return result; +} +#endif +static PyObject* __Pyx__CallUnboundCMethod2(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg1, PyObject* arg2){ + if (unlikely(!cfunc->func && !cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; +#if CYTHON_COMPILING_IN_CPYTHON + if (cfunc->func && (cfunc->flag & METH_VARARGS)) { + PyObject *result = NULL; + PyObject *args = PyTuple_New(2); + if (unlikely(!args)) return NULL; + Py_INCREF(arg1); + PyTuple_SET_ITEM(args, 0, arg1); + Py_INCREF(arg2); + PyTuple_SET_ITEM(args, 1, arg2); + if (cfunc->flag & METH_KEYWORDS) + result = __Pyx_CallCFunctionWithKeywords(cfunc, self, args, NULL); + else + result = __Pyx_CallCFunction(cfunc, self, args); + Py_DECREF(args); + return result; + } +#endif + { + PyObject *args[4] = {NULL, self, arg1, arg2}; + return __Pyx_PyObject_FastCall(cfunc->method, args+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); + } +} + +/* ParseKeywordsImpl (used by ParseKeywords) */ +static int __Pyx_ValidateDuplicatePosArgs( + PyObject *kwds, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + const char* function_name) +{ + PyObject ** const *name = argnames; + while (name != first_kw_arg) { + PyObject *key = **name; + int found = PyDict_Contains(kwds, key); + if (unlikely(found)) { + if (found == 1) __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; + } + name++; + } + return 0; +bad: + return -1; +} +#if CYTHON_USE_UNICODE_INTERNALS +static CYTHON_INLINE int __Pyx_UnicodeKeywordsEqual(PyObject *s1, PyObject *s2) { + int kind; + Py_ssize_t len = PyUnicode_GET_LENGTH(s1); + if (len != PyUnicode_GET_LENGTH(s2)) return 0; + kind = PyUnicode_KIND(s1); + if (kind != PyUnicode_KIND(s2)) return 0; + const void *data1 = PyUnicode_DATA(s1); + const void *data2 = PyUnicode_DATA(s2); + return (memcmp(data1, data2, (size_t) len * (size_t) kind) == 0); +} +#endif +static int __Pyx_MatchKeywordArg_str( + PyObject *key, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + size_t *index_found, + const char *function_name) +{ + PyObject ** const *name; + #if CYTHON_USE_UNICODE_INTERNALS + Py_hash_t key_hash = ((PyASCIIObject*)key)->hash; + if (unlikely(key_hash == -1)) { + key_hash = PyObject_Hash(key); + if (unlikely(key_hash == -1)) + goto bad; + } + #endif + name = first_kw_arg; + while (*name) { + PyObject *name_str = **name; + #if CYTHON_USE_UNICODE_INTERNALS + if (key_hash == ((PyASCIIObject*)name_str)->hash && __Pyx_UnicodeKeywordsEqual(name_str, key)) { + *index_found = (size_t) (name - argnames); + return 1; + } + #else + #if CYTHON_ASSUME_SAFE_SIZE + if (PyUnicode_GET_LENGTH(name_str) == PyUnicode_GET_LENGTH(key)) + #endif + { + int cmp = PyUnicode_Compare(name_str, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + *index_found = (size_t) (name - argnames); + return 1; + } + } + #endif + name++; + } + name = argnames; + while (name != first_kw_arg) { + PyObject *name_str = **name; + #if CYTHON_USE_UNICODE_INTERNALS + if (unlikely(key_hash == ((PyASCIIObject*)name_str)->hash)) { + if (__Pyx_UnicodeKeywordsEqual(name_str, key)) + goto arg_passed_twice; + } + #else + #if CYTHON_ASSUME_SAFE_SIZE + if (PyUnicode_GET_LENGTH(name_str) == PyUnicode_GET_LENGTH(key)) + #endif + { + if (unlikely(name_str == key)) goto arg_passed_twice; + int cmp = PyUnicode_Compare(name_str, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + } + #endif + name++; + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +bad: + return -1; +} +static int __Pyx_MatchKeywordArg_nostr( + PyObject *key, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + size_t *index_found, + const char *function_name) +{ + PyObject ** const *name; + if (unlikely(!PyUnicode_Check(key))) goto invalid_keyword_type; + name = first_kw_arg; + while (*name) { + int cmp = PyObject_RichCompareBool(**name, key, Py_EQ); + if (cmp == 1) { + *index_found = (size_t) (name - argnames); + return 1; + } + if (unlikely(cmp == -1)) goto bad; + name++; + } + name = argnames; + while (name != first_kw_arg) { + int cmp = PyObject_RichCompareBool(**name, key, Py_EQ); + if (unlikely(cmp != 0)) { + if (cmp == 1) goto arg_passed_twice; + else goto bad; + } + name++; + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +bad: + return -1; +} +static CYTHON_INLINE int __Pyx_MatchKeywordArg( + PyObject *key, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + size_t *index_found, + const char *function_name) +{ + return likely(PyUnicode_CheckExact(key)) ? + __Pyx_MatchKeywordArg_str(key, argnames, first_kw_arg, index_found, function_name) : + __Pyx_MatchKeywordArg_nostr(key, argnames, first_kw_arg, index_found, function_name); +} +static void __Pyx_RejectUnknownKeyword( + PyObject *kwds, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + const char *function_name) +{ + #if CYTHON_AVOID_BORROWED_REFS + PyObject *pos = NULL; + #else + Py_ssize_t pos = 0; + #endif + PyObject *key = NULL; + __Pyx_BEGIN_CRITICAL_SECTION(kwds); + while ( + #if CYTHON_AVOID_BORROWED_REFS + __Pyx_PyDict_NextRef(kwds, &pos, &key, NULL) + #else + PyDict_Next(kwds, &pos, &key, NULL) + #endif + ) { + PyObject** const *name = first_kw_arg; + while (*name && (**name != key)) name++; + if (!*name) { + size_t index_found = 0; + int cmp = __Pyx_MatchKeywordArg(key, argnames, first_kw_arg, &index_found, function_name); + if (cmp != 1) { + if (cmp == 0) { + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(key); + #endif + break; + } + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(key); + #endif + } + __Pyx_END_CRITICAL_SECTION(); + #if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(pos); + #endif + assert(PyErr_Occurred()); +} +static int __Pyx_ParseKeywordDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs) +{ + PyObject** const *name; + PyObject** const *first_kw_arg = argnames + num_pos_args; + Py_ssize_t extracted = 0; +#if !CYTHON_COMPILING_IN_PYPY || defined(PyArg_ValidateKeywordArguments) + if (unlikely(!PyArg_ValidateKeywordArguments(kwds))) return -1; +#endif + name = first_kw_arg; + while (*name && num_kwargs > extracted) { + PyObject * key = **name; + PyObject *value; + int found = 0; + #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + found = PyDict_GetItemRef(kwds, key, &value); + #else + value = PyDict_GetItemWithError(kwds, key); + if (value) { + Py_INCREF(value); + found = 1; + } else { + if (unlikely(PyErr_Occurred())) goto bad; + } + #endif + if (found) { + if (unlikely(found < 0)) goto bad; + values[name-argnames] = value; + extracted++; + } + name++; + } + if (num_kwargs > extracted) { + if (ignore_unknown_kwargs) { + if (unlikely(__Pyx_ValidateDuplicatePosArgs(kwds, argnames, first_kw_arg, function_name) == -1)) + goto bad; + } else { + __Pyx_RejectUnknownKeyword(kwds, argnames, first_kw_arg, function_name); + goto bad; + } + } + return 0; +bad: + return -1; +} +static int __Pyx_ParseKeywordDictToDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject** const *name; + PyObject** const *first_kw_arg = argnames + num_pos_args; + Py_ssize_t len; +#if !CYTHON_COMPILING_IN_PYPY || defined(PyArg_ValidateKeywordArguments) + if (unlikely(!PyArg_ValidateKeywordArguments(kwds))) return -1; +#endif + if (PyDict_Update(kwds2, kwds) < 0) goto bad; + name = first_kw_arg; + while (*name) { + PyObject *key = **name; + PyObject *value; +#if !CYTHON_COMPILING_IN_LIMITED_API && (PY_VERSION_HEX >= 0x030d00A2 || defined(PyDict_Pop)) + int found = PyDict_Pop(kwds2, key, &value); + if (found) { + if (unlikely(found < 0)) goto bad; + values[name-argnames] = value; + } +#elif __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + int found = PyDict_GetItemRef(kwds2, key, &value); + if (found) { + if (unlikely(found < 0)) goto bad; + values[name-argnames] = value; + if (unlikely(PyDict_DelItem(kwds2, key) < 0)) goto bad; + } +#else + #if CYTHON_COMPILING_IN_CPYTHON + value = _PyDict_Pop(kwds2, key, kwds2); + #else + value = __Pyx_CallUnboundCMethod2(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_pop, kwds2, key, kwds2); + #endif + if (value == kwds2) { + Py_DECREF(value); + } else { + if (unlikely(!value)) goto bad; + values[name-argnames] = value; + } +#endif + name++; + } + len = PyDict_Size(kwds2); + if (len > 0) { + return __Pyx_ValidateDuplicatePosArgs(kwds, argnames, first_kw_arg, function_name); + } else if (unlikely(len == -1)) { + goto bad; + } + return 0; +bad: + return -1; +} +static int __Pyx_ParseKeywordsTuple( + PyObject *kwds, + PyObject * const *kwvalues, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs) +{ + PyObject *key = NULL; + PyObject** const * name; + PyObject** const *first_kw_arg = argnames + num_pos_args; + for (Py_ssize_t pos = 0; pos < num_kwargs; pos++) { +#if CYTHON_AVOID_BORROWED_REFS + key = __Pyx_PySequence_ITEM(kwds, pos); +#else + key = __Pyx_PyTuple_GET_ITEM(kwds, pos); +#endif +#if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(!key)) goto bad; +#endif + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + PyObject *value = kwvalues[pos]; + values[name-argnames] = __Pyx_NewRef(value); + } else { + size_t index_found = 0; + int cmp = __Pyx_MatchKeywordArg(key, argnames, first_kw_arg, &index_found, function_name); + if (cmp == 1) { + PyObject *value = kwvalues[pos]; + values[index_found] = __Pyx_NewRef(value); + } else { + if (unlikely(cmp == -1)) goto bad; + if (kwds2) { + PyObject *value = kwvalues[pos]; + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else if (!ignore_unknown_kwargs) { + goto invalid_keyword; + } + } + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(key); + key = NULL; + #endif + } + return 0; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + goto bad; +bad: + #if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(key); + #endif + return -1; +} + +/* ParseKeywords */ +static int __Pyx_ParseKeywords( + PyObject *kwds, + PyObject * const *kwvalues, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs) +{ + if (CYTHON_METH_FASTCALL && likely(PyTuple_Check(kwds))) + return __Pyx_ParseKeywordsTuple(kwds, kwvalues, argnames, kwds2, values, num_pos_args, num_kwargs, function_name, ignore_unknown_kwargs); + else if (kwds2) + return __Pyx_ParseKeywordDictToDict(kwds, argnames, kwds2, values, num_pos_args, function_name); + else + return __Pyx_ParseKeywordDict(kwds, argnames, values, num_pos_args, num_kwargs, function_name, ignore_unknown_kwargs); +} + +/* RaiseArgTupleInvalid */ +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* PyErrExceptionMatches (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); + for (i=0; i= 0x030C00A6 + PyObject *current_exception = tstate->current_exception; + if (unlikely(!current_exception)) return 0; + exc_type = (PyObject*) Py_TYPE(current_exception); + if (exc_type == err) return 1; +#else + exc_type = tstate->curexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; +#endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(exc_type); + #endif + if (unlikely(PyTuple_Check(err))) { + result = __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + } else { + result = __Pyx_PyErr_GivenExceptionMatches(exc_type, err); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(exc_type); + #endif + return result; +} +#endif + +/* PyErrFetchRestore (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject *tmp_value; + assert(type == NULL || (value != NULL && type == (PyObject*) Py_TYPE(value))); + if (value) { + #if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(((PyBaseExceptionObject*) value)->traceback != tb)) + #endif + PyException_SetTraceback(value, tb); + } + tmp_value = tstate->current_exception; + tstate->current_exception = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#endif +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject* exc_value; + exc_value = tstate->current_exception; + tstate->current_exception = 0; + *value = exc_value; + *type = NULL; + *tb = NULL; + if (exc_value) { + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + #if CYTHON_COMPILING_IN_CPYTHON + *tb = ((PyBaseExceptionObject*) exc_value)->traceback; + Py_XINCREF(*tb); + #else + *tb = PyException_GetTraceback(exc_value); + #endif + } +#else + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#endif +} +#endif + +/* PyObjectGetAttrStrNoError (used by GetBuiltinName) */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d0000 +static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + __Pyx_PyErr_Clear(); +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { + PyObject *result; +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + (void) PyObject_GetOptionalAttr(obj, attr_name, &result); + return result; +#else +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { + return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); + } +#endif + result = __Pyx_PyObject_GetAttrStr(obj, attr_name); + if (unlikely(!result)) { + __Pyx_PyObject_GetAttrStr_ClearAttributeError(); + } + return result; +#endif +} + +/* GetBuiltinName (used by GetModuleGlobalName) */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStrNoError(__pyx_mstate_global->__pyx_b, name); + if (unlikely(!result) && !PyErr_Occurred()) { + PyErr_Format(PyExc_NameError, + "name '%U' is not defined", name); + } + return result; +} + +/* PyDictVersioning (used by GetModuleGlobalName) */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* GetModuleGlobalName */ +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ + PyObject *result; +#if CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(!__pyx_m)) { + if (!PyErr_Occurred()) + PyErr_SetNone(PyExc_NameError); + return NULL; + } + result = PyObject_GetAttr(__pyx_m, name); + if (likely(result)) { + return result; + } + PyErr_Clear(); +#elif CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + if (unlikely(__Pyx_PyDict_GetItemRef(__pyx_mstate_global->__pyx_d, name, &result) == -1)) PyErr_Clear(); + __PYX_UPDATE_DICT_CACHE(__pyx_mstate_global->__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return result; + } +#else + result = _PyDict_GetItem_KnownHash(__pyx_mstate_global->__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_mstate_global->__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); +} + +/* PyObjectSetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr_name, PyObject* value) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_setattro)) + return tp->tp_setattro(obj, attr_name, value); + return PyObject_SetAttr(obj, attr_name, value); +} +#endif + +/* PyObjectFastCallMethod */ +#if !CYTHON_VECTORCALL || PY_VERSION_HEX < 0x03090000 +static PyObject *__Pyx_PyObject_FastCallMethod(PyObject *name, PyObject *const *args, size_t nargsf) { + PyObject *result; + PyObject *attr = PyObject_GetAttr(args[0], name); + if (unlikely(!attr)) + return NULL; + result = __Pyx_PyObject_FastCall(attr, args+1, nargsf - 1); + Py_DECREF(attr); + return result; +} +#endif + +/* RaiseException */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyException_SetTraceback(value, tb); +#elif CYTHON_FAST_THREAD_STATE + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} + +/* RaiseTooManyValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +/* RaiseNeedMoreValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +/* IterFinish */ +static CYTHON_INLINE int __Pyx_IterFinish(void) { + PyObject* exc_type; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + exc_type = __Pyx_PyErr_CurrentExceptionType(); + if (unlikely(exc_type)) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) + return -1; + __Pyx_PyErr_Clear(); + return 0; + } + return 0; +} + +/* UnpackItemEndCheck */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { + if (unlikely(retval)) { + Py_DECREF(retval); + __Pyx_RaiseTooManyValuesError(expected); + return -1; + } + return __Pyx_IterFinish(); +} + +/* HasAttr (used by ImportImpl) */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d0000 +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { + PyObject *r; + if (unlikely(!PyUnicode_Check(n))) { + PyErr_SetString(PyExc_TypeError, + "hasattr(): attribute name must be string"); + return -1; + } + r = __Pyx_PyObject_GetAttrStrNoError(o, n); + if (!r) { + return (unlikely(PyErr_Occurred())) ? -1 : 0; + } else { + Py_DECREF(r); + return 1; + } +} +#endif + +/* ImportImpl (used by Import) */ +static int __Pyx__Import_GetModule(PyObject *qualname, PyObject **module) { + PyObject *imported_module = PyImport_GetModule(qualname); + if (unlikely(!imported_module)) { + *module = NULL; + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + *module = imported_module; + return 1; +} +static int __Pyx__Import_Lookup(PyObject *qualname, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject **module) { + PyObject *imported_module; + PyObject *top_level_package_name; + Py_ssize_t i; + int status, module_found; + Py_ssize_t dot_index; + module_found = __Pyx__Import_GetModule(qualname, &imported_module); + if (unlikely(!module_found || module_found == -1)) { + *module = NULL; + return module_found; + } + if (imported_names) { + for (i = 0; i < len_imported_names; i++) { + PyObject *imported_name = imported_names[i]; +#if __PYX_LIMITED_VERSION_HEX < 0x030d0000 + int has_imported_attribute = PyObject_HasAttr(imported_module, imported_name); +#else + int has_imported_attribute = PyObject_HasAttrWithError(imported_module, imported_name); + if (unlikely(has_imported_attribute == -1)) goto error; +#endif + if (!has_imported_attribute) { + goto not_found; + } + } + *module = imported_module; + return 1; + } + dot_index = PyUnicode_FindChar(qualname, '.', 0, PY_SSIZE_T_MAX, 1); + if (dot_index == -1) { + *module = imported_module; + return 1; + } + if (unlikely(dot_index == -2)) goto error; + top_level_package_name = PyUnicode_Substring(qualname, 0, dot_index); + if (unlikely(!top_level_package_name)) goto error; + Py_DECREF(imported_module); + status = __Pyx__Import_GetModule(top_level_package_name, module); + Py_DECREF(top_level_package_name); + return status; +error: + Py_DECREF(imported_module); + *module = NULL; + return -1; +not_found: + Py_DECREF(imported_module); + *module = NULL; + return 0; +} +static PyObject *__Pyx__Import(PyObject *name, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject *qualname, PyObject *moddict, int level) { + PyObject *module = 0; + PyObject *empty_dict = 0; + PyObject *from_list = 0; + int module_found; + if (!qualname) { + qualname = name; + } + module_found = __Pyx__Import_Lookup(qualname, imported_names, len_imported_names, &module); + if (likely(module_found == 1)) { + return module; + } else if (unlikely(module_found == -1)) { + return NULL; + } + empty_dict = PyDict_New(); + if (unlikely(!empty_dict)) + goto bad; + if (imported_names) { +#if CYTHON_COMPILING_IN_CPYTHON + from_list = __Pyx_PyList_FromArray(imported_names, len_imported_names); + if (unlikely(!from_list)) + goto bad; +#else + from_list = PyList_New(len_imported_names); + if (unlikely(!from_list)) goto bad; + for (Py_ssize_t i=0; i__pyx_d, level); +} + +/* ImportFrom */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { + PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); + if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { + const char* module_name_str = 0; + PyObject* module_name = 0; + PyObject* module_dot = 0; + PyObject* full_name = 0; + PyErr_Clear(); + module_name_str = PyModule_GetName(module); + if (unlikely(!module_name_str)) { goto modbad; } + module_name = PyUnicode_FromString(module_name_str); + if (unlikely(!module_name)) { goto modbad; } + module_dot = PyUnicode_Concat(module_name, __pyx_mstate_global->__pyx_kp_u_); + if (unlikely(!module_dot)) { goto modbad; } + full_name = PyUnicode_Concat(module_dot, name); + if (unlikely(!full_name)) { goto modbad; } + #if (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) ||\ + CYTHON_COMPILING_IN_GRAAL + { + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + goto modbad; + value = PyObject_GetItem(modules, full_name); + } + #else + value = PyImport_GetModule(full_name); + #endif + modbad: + Py_XDECREF(full_name); + Py_XDECREF(module_dot); + Py_XDECREF(module_name); + } + if (unlikely(!value)) { + PyErr_Format(PyExc_ImportError, "cannot import name %S", name); + } + return value; +} + +/* ListPack */ +static PyObject *__Pyx_PyList_Pack(Py_ssize_t n, ...) { + va_list va; + PyObject *l = PyList_New(n); + va_start(va, n); + if (unlikely(!l)) goto end; + for (Py_ssize_t i=0; i__pyx_n_u_mro_entries); + if (!meth && PyErr_Occurred()) { + goto error; + } + if (!meth) { + if (new_bases) { + if (PyList_Append(new_bases, base) < 0) { + goto error; + } + } + continue; + } + new_base = __Pyx_PyObject_CallOneArg(meth, bases); + Py_DECREF(meth); + if (!new_base) { + goto error; + } + if (!PyTuple_Check(new_base)) { + PyErr_SetString(PyExc_TypeError, + "__mro_entries__ must return a tuple"); + Py_DECREF(new_base); + goto error; + } + if (!new_bases) { + if (!(new_bases = PyList_New(i))) { + goto error; + } + for (j = 0; j < i; j++) { + PyObject *base_from_list; +#if CYTHON_ASSUME_SAFE_MACROS + base_from_list = PyTuple_GET_ITEM(bases, j); + PyList_SET_ITEM(new_bases, j, base_from_list); + Py_INCREF(base_from_list); +#else + base_from_list = PyTuple_GetItem(bases, j); + if (!base_from_list) goto error; + Py_INCREF(base_from_list); + if (PyList_SetItem(new_bases, j, base_from_list) < 0) goto error; +#endif + } + } +#if CYTHON_ASSUME_SAFE_SIZE + j = PyList_GET_SIZE(new_bases); +#else + j = PyList_Size(new_bases); + if (j < 0) goto error; +#endif + if (PyList_SetSlice(new_bases, j, j, new_base) < 0) { + goto error; + } + Py_DECREF(new_base); + } + if (!new_bases) { + Py_INCREF(bases); + return bases; + } + result = PyList_AsTuple(new_bases); + Py_DECREF(new_bases); +#if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(base); +#endif + return result; +error: + Py_XDECREF(new_bases); +#if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(base); +#endif + return NULL; +} + +/* CalculateMetaclass */ +static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases) { + Py_ssize_t i, nbases; +#if CYTHON_ASSUME_SAFE_SIZE + nbases = PyTuple_GET_SIZE(bases); +#else + nbases = PyTuple_Size(bases); + if (nbases < 0) return NULL; +#endif + for (i=0; i < nbases; i++) { + PyTypeObject *tmptype; +#if CYTHON_ASSUME_SAFE_MACROS + PyObject *tmp = PyTuple_GET_ITEM(bases, i); +#else + PyObject *tmp = PyTuple_GetItem(bases, i); + if (!tmp) return NULL; +#endif + tmptype = Py_TYPE(tmp); + if (!metaclass) { + metaclass = tmptype; + continue; + } + if (PyType_IsSubtype(metaclass, tmptype)) + continue; + if (PyType_IsSubtype(tmptype, metaclass)) { + metaclass = tmptype; + continue; + } + PyErr_SetString(PyExc_TypeError, + "metaclass conflict: " + "the metaclass of a derived class " + "must be a (non-strict) subclass " + "of the metaclasses of all its bases"); + return NULL; + } + if (!metaclass) { + metaclass = &PyType_Type; + } + Py_INCREF((PyObject*) metaclass); + return (PyObject*) metaclass; +} + +/* dict_setdefault (used by FetchCommonType) */ +static CYTHON_INLINE PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value) { + PyObject* value; +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX >= 0x030C0000 + PyObject *args[] = {d, key, default_value}; + value = PyObject_VectorcallMethod(__pyx_mstate_global->__pyx_n_u_setdefault, args, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +#elif CYTHON_COMPILING_IN_LIMITED_API + value = PyObject_CallMethodObjArgs(d, __pyx_mstate_global->__pyx_n_u_setdefault, key, default_value, NULL); +#elif PY_VERSION_HEX >= 0x030d0000 + PyDict_SetDefaultRef(d, key, default_value, &value); +#else + value = PyDict_SetDefault(d, key, default_value); + if (unlikely(!value)) return NULL; + Py_INCREF(value); +#endif + return value; +} + +/* LimitedApiGetTypeDict (used by SetItemOnTypeDict) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static Py_ssize_t __Pyx_GetTypeDictOffset(void) { + PyObject *tp_dictoffset_o; + Py_ssize_t tp_dictoffset; + tp_dictoffset_o = PyObject_GetAttrString((PyObject*)(&PyType_Type), "__dictoffset__"); + if (unlikely(!tp_dictoffset_o)) return -1; + tp_dictoffset = PyLong_AsSsize_t(tp_dictoffset_o); + Py_DECREF(tp_dictoffset_o); + if (unlikely(tp_dictoffset == 0)) { + PyErr_SetString( + PyExc_TypeError, + "'type' doesn't have a dictoffset"); + return -1; + } else if (unlikely(tp_dictoffset < 0)) { + PyErr_SetString( + PyExc_TypeError, + "'type' has an unexpected negative dictoffset. " + "Please report this as Cython bug"); + return -1; + } + return tp_dictoffset; +} +static PyObject *__Pyx_GetTypeDict(PyTypeObject *tp) { + static Py_ssize_t tp_dictoffset = 0; + if (unlikely(tp_dictoffset == 0)) { + tp_dictoffset = __Pyx_GetTypeDictOffset(); + if (unlikely(tp_dictoffset == -1 && PyErr_Occurred())) { + tp_dictoffset = 0; // try again next time? + return NULL; + } + } + return *(PyObject**)((char*)tp + tp_dictoffset); +} +#endif + +/* SetItemOnTypeDict (used by FixUpExtensionType) */ +static int __Pyx__SetItemOnTypeDict(PyTypeObject *tp, PyObject *k, PyObject *v) { + int result; + PyObject *tp_dict; +#if CYTHON_COMPILING_IN_LIMITED_API + tp_dict = __Pyx_GetTypeDict(tp); + if (unlikely(!tp_dict)) return -1; +#else + tp_dict = tp->tp_dict; +#endif + result = PyDict_SetItem(tp_dict, k, v); + if (likely(!result)) { + PyType_Modified(tp); + if (unlikely(PyObject_HasAttr(v, __pyx_mstate_global->__pyx_n_u_set_name))) { + PyObject *setNameResult = PyObject_CallMethodObjArgs(v, __pyx_mstate_global->__pyx_n_u_set_name, (PyObject *) tp, k, NULL); + if (!setNameResult) return -1; + Py_DECREF(setNameResult); + } + } + return result; +} + +/* FixUpExtensionType (used by FetchCommonType) */ +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) { +#if __PYX_LIMITED_VERSION_HEX > 0x030900B1 + CYTHON_UNUSED_VAR(spec); + CYTHON_UNUSED_VAR(type); + CYTHON_UNUSED_VAR(__Pyx__SetItemOnTypeDict); +#else + const PyType_Slot *slot = spec->slots; + int changed = 0; +#if !CYTHON_COMPILING_IN_LIMITED_API + while (slot && slot->slot && slot->slot != Py_tp_members) + slot++; + if (slot && slot->slot == Py_tp_members) { +#if !CYTHON_COMPILING_IN_CPYTHON + const +#endif // !CYTHON_COMPILING_IN_CPYTHON) + PyMemberDef *memb = (PyMemberDef*) slot->pfunc; + while (memb && memb->name) { + if (memb->name[0] == '_' && memb->name[1] == '_') { + if (strcmp(memb->name, "__weaklistoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_weaklistoffset = memb->offset; + changed = 1; + } + else if (strcmp(memb->name, "__dictoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_dictoffset = memb->offset; + changed = 1; + } +#if CYTHON_METH_FASTCALL + else if (strcmp(memb->name, "__vectorcalloffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_vectorcall_offset = memb->offset; + changed = 1; + } +#endif // CYTHON_METH_FASTCALL +#if !CYTHON_COMPILING_IN_PYPY + else if (strcmp(memb->name, "__module__") == 0) { + PyObject *descr; + assert(memb->type == T_OBJECT); + assert(memb->flags == 0 || memb->flags == READONLY); + descr = PyDescr_NewMember(type, memb); + if (unlikely(!descr)) + return -1; + int set_item_result = PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr); + Py_DECREF(descr); + if (unlikely(set_item_result < 0)) { + return -1; + } + changed = 1; + } +#endif // !CYTHON_COMPILING_IN_PYPY + } + memb++; + } + } +#endif // !CYTHON_COMPILING_IN_LIMITED_API +#if !CYTHON_COMPILING_IN_PYPY + slot = spec->slots; + while (slot && slot->slot && slot->slot != Py_tp_getset) + slot++; + if (slot && slot->slot == Py_tp_getset) { + PyGetSetDef *getset = (PyGetSetDef*) slot->pfunc; + while (getset && getset->name) { + if (getset->name[0] == '_' && getset->name[1] == '_' && strcmp(getset->name, "__module__") == 0) { + PyObject *descr = PyDescr_NewGetSet(type, getset); + if (unlikely(!descr)) + return -1; + #if CYTHON_COMPILING_IN_LIMITED_API + PyObject *pyname = PyUnicode_FromString(getset->name); + if (unlikely(!pyname)) { + Py_DECREF(descr); + return -1; + } + int set_item_result = __Pyx_SetItemOnTypeDict(type, pyname, descr); + Py_DECREF(pyname); + #else + CYTHON_UNUSED_VAR(__Pyx__SetItemOnTypeDict); + int set_item_result = PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr); + #endif + Py_DECREF(descr); + if (unlikely(set_item_result < 0)) { + return -1; + } + changed = 1; + } + ++getset; + } + } +#else + CYTHON_UNUSED_VAR(__Pyx__SetItemOnTypeDict); +#endif // !CYTHON_COMPILING_IN_PYPY + if (changed) + PyType_Modified(type); +#endif // PY_VERSION_HEX > 0x030900B1 + return 0; +} + +/* AddModuleRef (used by FetchSharedCythonModule) */ +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + static PyObject *__Pyx_PyImport_AddModuleObjectRef(PyObject *name) { + PyObject *module_dict = PyImport_GetModuleDict(); + PyObject *m; + if (PyMapping_GetOptionalItem(module_dict, name, &m) < 0) { + return NULL; + } + if (m != NULL && PyModule_Check(m)) { + return m; + } + Py_XDECREF(m); + m = PyModule_NewObject(name); + if (m == NULL) + return NULL; + if (PyDict_CheckExact(module_dict)) { + PyObject *new_m; + (void)PyDict_SetDefaultRef(module_dict, name, m, &new_m); + Py_DECREF(m); + return new_m; + } else { + if (PyObject_SetItem(module_dict, name, m) != 0) { + Py_DECREF(m); + return NULL; + } + return m; + } + } + static PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *py_name = PyUnicode_FromString(name); + if (!py_name) return NULL; + PyObject *module = __Pyx_PyImport_AddModuleObjectRef(py_name); + Py_DECREF(py_name); + return module; + } +#elif __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#else + static PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *module = PyImport_AddModule(name); + Py_XINCREF(module); + return module; + } +#endif + +/* FetchSharedCythonModule (used by FetchCommonType) */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void) { + return __Pyx_PyImport_AddModuleRef(__PYX_ABI_MODULE_NAME); +} + +/* FetchCommonType (used by CommonTypesMetaclass) */ +#if __PYX_LIMITED_VERSION_HEX < 0x030C0000 +static PyObject* __Pyx_PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *result = __Pyx_PyType_FromModuleAndSpec(module, spec, bases); + if (result && metaclass) { + PyObject *old_tp = (PyObject*)Py_TYPE(result); + Py_INCREF((PyObject*)metaclass); +#if __PYX_LIMITED_VERSION_HEX >= 0x03090000 + Py_SET_TYPE(result, metaclass); +#else + result->ob_type = metaclass; +#endif + Py_DECREF(old_tp); + } + return result; +} +#else +#define __Pyx_PyType_FromMetaclass(me, mo, s, b) PyType_FromMetaclass(me, mo, s, b) +#endif +static int __Pyx_VerifyCachedType(PyObject *cached_type, + const char *name, + Py_ssize_t expected_basicsize) { + Py_ssize_t basicsize; + if (!PyType_Check(cached_type)) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s is not a type object", name); + return -1; + } + if (expected_basicsize == 0) { + return 0; // size is inherited, nothing useful to check + } +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_basicsize; + py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__"); + if (unlikely(!py_basicsize)) return -1; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = NULL; + if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) return -1; +#else + basicsize = ((PyTypeObject*) cached_type)->tp_basicsize; +#endif + if (basicsize != expected_basicsize) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s has the wrong size, try recompiling", + name); + return -1; + } + return 0; +} +static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *abi_module = NULL, *cached_type = NULL, *abi_module_dict, *new_cached_type, *py_object_name; + int get_item_ref_result; + const char* object_name = strrchr(spec->name, '.'); + object_name = object_name ? object_name+1 : spec->name; + py_object_name = PyUnicode_FromString(object_name); + if (!py_object_name) return NULL; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) goto done; + abi_module_dict = PyModule_GetDict(abi_module); + if (!abi_module_dict) goto done; + get_item_ref_result = __Pyx_PyDict_GetItemRef(abi_module_dict, py_object_name, &cached_type); + if (get_item_ref_result == 1) { + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + spec->basicsize) < 0) { + goto bad; + } + goto done; + } else if (unlikely(get_item_ref_result == -1)) { + goto bad; + } + cached_type = __Pyx_PyType_FromMetaclass( + metaclass, + CYTHON_USE_MODULE_STATE ? module : abi_module, + spec, bases); + if (unlikely(!cached_type)) goto bad; + if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad; + new_cached_type = __Pyx_PyDict_SetDefault(abi_module_dict, py_object_name, cached_type); + if (unlikely(new_cached_type != cached_type)) { + if (unlikely(!new_cached_type)) goto bad; + Py_DECREF(cached_type); + cached_type = new_cached_type; + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + spec->basicsize) < 0) { + goto bad; + } + goto done; + } else { + Py_DECREF(new_cached_type); + } +done: + Py_XDECREF(abi_module); + Py_DECREF(py_object_name); + assert(cached_type == NULL || PyType_Check(cached_type)); + return (PyTypeObject *) cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} + +/* CommonTypesMetaclass (used by CythonFunctionShared) */ +static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) { + return PyUnicode_FromString(__PYX_ABI_MODULE_NAME); +} +#if __PYX_LIMITED_VERSION_HEX < 0x030A0000 +static PyObject* __pyx_CommonTypesMetaclass_call(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *args, CYTHON_UNUSED PyObject *kwds) { + PyErr_SetString(PyExc_TypeError, "Cannot instantiate Cython internal types"); + return NULL; +} +static int __pyx_CommonTypesMetaclass_setattr(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *attr, CYTHON_UNUSED PyObject *value) { + PyErr_SetString(PyExc_TypeError, "Cython internal types are immutable"); + return -1; +} +#endif +static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = { + {"__module__", __pyx_CommonTypesMetaclass_get_module, NULL, NULL, NULL}, + {0, 0, 0, 0, 0} +}; +static PyType_Slot __pyx_CommonTypesMetaclass_slots[] = { + {Py_tp_getset, (void *)__pyx_CommonTypesMetaclass_getset}, + #if __PYX_LIMITED_VERSION_HEX < 0x030A0000 + {Py_tp_call, (void*)__pyx_CommonTypesMetaclass_call}, + {Py_tp_new, (void*)__pyx_CommonTypesMetaclass_call}, + {Py_tp_setattro, (void*)__pyx_CommonTypesMetaclass_setattr}, + #endif + {0, 0} +}; +static PyType_Spec __pyx_CommonTypesMetaclass_spec = { + __PYX_TYPE_MODULE_PREFIX "_common_types_metatype", + 0, + 0, + Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_DEFAULT, + __pyx_CommonTypesMetaclass_slots +}; +static int __pyx_CommonTypesMetaclass_init(PyObject *module) { + __pyx_mstatetype *mstate = __Pyx_PyModule_GetState(module); + PyObject *bases = PyTuple_Pack(1, &PyType_Type); + if (unlikely(!bases)) { + return -1; + } + mstate->__pyx_CommonTypesMetaclassType = __Pyx_FetchCommonTypeFromSpec(NULL, module, &__pyx_CommonTypesMetaclass_spec, bases); + Py_DECREF(bases); + if (unlikely(mstate->__pyx_CommonTypesMetaclassType == NULL)) { + return -1; + } + return 0; +} + +/* CallTypeTraverse (used by CythonFunctionShared) */ +#if !CYTHON_USE_TYPE_SPECS || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x03090000) +#else +static int __Pyx_call_type_traverse(PyObject *o, int always_call, visitproc visit, void *arg) { + #if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x03090000 + if (__Pyx_get_runtime_version() < 0x03090000) return 0; + #endif + if (!always_call) { + PyTypeObject *base = __Pyx_PyObject_GetSlot(o, tp_base, PyTypeObject*); + unsigned long flags = PyType_GetFlags(base); + if (flags & Py_TPFLAGS_HEAPTYPE) { + return 0; + } + } + Py_VISIT((PyObject*)Py_TYPE(o)); + return 0; +} +#endif + +/* PyMethodNew (used by CythonFunctionShared) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + PyObject *result; + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + #if __PYX_LIMITED_VERSION_HEX >= 0x030C0000 + { + PyObject *args[] = {func, self}; + result = PyObject_Vectorcall(__pyx_mstate_global->__Pyx_CachedMethodType, args, 2, NULL); + } + #else + result = PyObject_CallFunctionObjArgs(__pyx_mstate_global->__Pyx_CachedMethodType, func, self, NULL); + #endif + return result; +} +#else +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + return PyMethod_New(func, self); +} +#endif + +/* PyVectorcallFastCallDict (used by CythonFunctionShared) */ +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL +static PyObject *__Pyx_PyVectorcall_FastCallDict_kw(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + PyObject *res = NULL; + PyObject *kwnames; + PyObject **newargs; + PyObject **kwvalues; + Py_ssize_t i; + #if CYTHON_AVOID_BORROWED_REFS + PyObject *pos; + #else + Py_ssize_t pos; + #endif + size_t j; + PyObject *key, *value; + unsigned long keys_are_strings; + #if !CYTHON_ASSUME_SAFE_SIZE + Py_ssize_t nkw = PyDict_Size(kw); + if (unlikely(nkw == -1)) return NULL; + #else + Py_ssize_t nkw = PyDict_GET_SIZE(kw); + #endif + newargs = (PyObject **)PyMem_Malloc((nargs + (size_t)nkw) * sizeof(args[0])); + if (unlikely(newargs == NULL)) { + PyErr_NoMemory(); + return NULL; + } + for (j = 0; j < nargs; j++) newargs[j] = args[j]; + kwnames = PyTuple_New(nkw); + if (unlikely(kwnames == NULL)) { + PyMem_Free(newargs); + return NULL; + } + kwvalues = newargs + nargs; + pos = 0; + i = 0; + keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; + while (__Pyx_PyDict_NextRef(kw, &pos, &key, &value)) { + keys_are_strings &= + #if CYTHON_COMPILING_IN_LIMITED_API + PyType_GetFlags(Py_TYPE(key)); + #else + Py_TYPE(key)->tp_flags; + #endif + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(PyTuple_SetItem(kwnames, i, key) < 0)) goto cleanup; + #else + PyTuple_SET_ITEM(kwnames, i, key); + #endif + kwvalues[i] = value; + i++; + } + if (unlikely(!keys_are_strings)) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + goto cleanup; + } + res = vc(func, newargs, nargs, kwnames); +cleanup: + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(pos); + #endif + Py_DECREF(kwnames); + for (i = 0; i < nkw; i++) + Py_DECREF(kwvalues[i]); + PyMem_Free(newargs); + return res; +} +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + Py_ssize_t kw_size = + likely(kw == NULL) ? + 0 : +#if !CYTHON_ASSUME_SAFE_SIZE + PyDict_Size(kw); +#else + PyDict_GET_SIZE(kw); +#endif + if (kw_size == 0) { + return vc(func, args, nargs, NULL); + } +#if !CYTHON_ASSUME_SAFE_SIZE + else if (unlikely(kw_size == -1)) { + return NULL; + } +#endif + return __Pyx_PyVectorcall_FastCallDict_kw(func, vc, args, nargs, kw); +} +#endif + +/* CythonFunctionShared (used by CythonFunction) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunctionNoMethod(PyObject *func, void (*cfunc)(void)) { + if (__Pyx_CyFunction_Check(func)) { + return PyCFunction_GetFunction(((__pyx_CyFunctionObject*)func)->func) == (PyCFunction) cfunc; + } else if (PyCFunction_Check(func)) { + return PyCFunction_GetFunction(func) == (PyCFunction) cfunc; + } + return 0; +} +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void (*cfunc)(void)) { + if ((PyObject*)Py_TYPE(func) == __pyx_mstate_global->__Pyx_CachedMethodType) { + int result; + PyObject *newFunc = PyObject_GetAttr(func, __pyx_mstate_global->__pyx_n_u_func); + if (unlikely(!newFunc)) { + PyErr_Clear(); // It's only an optimization, so don't throw an error + return 0; + } + result = __Pyx__IsSameCyOrCFunctionNoMethod(newFunc, cfunc); + Py_DECREF(newFunc); + return result; + } + return __Pyx__IsSameCyOrCFunctionNoMethod(func, cfunc); +} +#else +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void (*cfunc)(void)) { + if (PyMethod_Check(func)) { + func = PyMethod_GET_FUNCTION(func); + } + return __Pyx_CyOrPyCFunction_Check(func) && __Pyx_CyOrPyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +} +#endif +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj) { +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + __Pyx_Py_XDECREF_SET( + __Pyx_CyFunction_GetClassObj(f), + ((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#else + __Pyx_Py_XDECREF_SET( + ((PyCMethodObject *) (f))->mm_class, + (PyTypeObject*)((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#endif +} +static PyObject * +__Pyx_CyFunction_get_doc_locked(__pyx_CyFunctionObject *op) +{ + if (unlikely(op->func_doc == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_doc = PyObject_GetAttrString(op->func, "__doc__"); + if (unlikely(!op->func_doc)) return NULL; +#else + if (((PyCFunctionObject*)op)->m_ml->ml_doc) { + op->func_doc = PyUnicode_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); + if (unlikely(op->func_doc == NULL)) + return NULL; + } else { + Py_INCREF(Py_None); + return Py_None; + } +#endif + } + Py_INCREF(op->func_doc); + return op->func_doc; +} +static PyObject * +__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure) { + PyObject *result; + CYTHON_UNUSED_VAR(closure); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_doc_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (value == NULL) { + value = Py_None; + } + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_doc, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_name_locked(__pyx_CyFunctionObject *op) +{ + if (unlikely(op->func_name == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_name = PyObject_GetAttrString(op->func, "__name__"); +#else + op->func_name = PyUnicode_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#endif + if (unlikely(op->func_name == NULL)) + return NULL; + } + Py_INCREF(op->func_name); + return op->func_name; +} +static PyObject * +__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, void *context) +{ + PyObject *result = NULL; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_name_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL || !PyUnicode_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_name, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + PyObject *result; + __Pyx_BEGIN_CRITICAL_SECTION(op); + Py_INCREF(op->func_qualname); + result = op->func_qualname; + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL || !PyUnicode_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_qualname, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 +static PyObject * +__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_dict == NULL)) { + op->func_dict = PyDict_New(); + if (unlikely(op->func_dict == NULL)) + return NULL; + } + Py_INCREF(op->func_dict); + return op->func_dict; +} +#endif +static PyObject * +__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_globals); + return op->func_globals; +} +static PyObject * +__Pyx_CyFunction_get_closure(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(op); + CYTHON_UNUSED_VAR(context); + Py_INCREF(Py_None); + return Py_None; +} +static PyObject * +__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, void *context) +{ + PyObject* result = (op->func_code) ? op->func_code : Py_None; + CYTHON_UNUSED_VAR(context); + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { + int result = 0; + PyObject *res = op->defaults_getter((PyObject *) op); + if (unlikely(!res)) + return -1; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + op->defaults_tuple = PyTuple_GET_ITEM(res, 0); + Py_INCREF(op->defaults_tuple); + op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); + Py_INCREF(op->defaults_kwdict); + #else + op->defaults_tuple = __Pyx_PySequence_ITEM(res, 0); + if (unlikely(!op->defaults_tuple)) result = -1; + else { + op->defaults_kwdict = __Pyx_PySequence_ITEM(res, 1); + if (unlikely(!op->defaults_kwdict)) result = -1; + } + #endif + Py_DECREF(res); + return result; +} +static int +__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyTuple_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__defaults__ must be set to a tuple object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__defaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->defaults_tuple, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_defaults_locked(__pyx_CyFunctionObject *op) { + PyObject* result = op->defaults_tuple; + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_tuple; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = NULL; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_defaults_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__kwdefaults__ must be set to a dict object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__kwdefaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->defaults_kwdict, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults_locked(__pyx_CyFunctionObject *op) { + PyObject* result = op->defaults_kwdict; + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_kwdict; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_kwdefaults_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value || value == Py_None) { + value = NULL; + } else if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__annotations__ must be set to a dict object"); + return -1; + } + Py_XINCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_annotations, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_annotations_locked(__pyx_CyFunctionObject *op) { + PyObject* result = op->func_annotations; + if (unlikely(!result)) { + result = PyDict_New(); + if (unlikely(!result)) return NULL; + op->func_annotations = result; + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, void *context) { + PyObject *result; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_annotations_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static PyObject * +__Pyx_CyFunction_get_is_coroutine_value(__pyx_CyFunctionObject *op) { + int is_coroutine = op->flags & __Pyx_CYFUNCTION_COROUTINE; + if (is_coroutine) { + PyObject *is_coroutine_value, *module, *fromlist, *marker = __pyx_mstate_global->__pyx_n_u_is_coroutine; + fromlist = PyList_New(1); + if (unlikely(!fromlist)) return NULL; + Py_INCREF(marker); +#if CYTHON_ASSUME_SAFE_MACROS + PyList_SET_ITEM(fromlist, 0, marker); +#else + if (unlikely(PyList_SetItem(fromlist, 0, marker) < 0)) { + Py_DECREF(marker); + Py_DECREF(fromlist); + return NULL; + } +#endif + module = PyImport_ImportModuleLevelObject(__pyx_mstate_global->__pyx_n_u_asyncio_coroutines, NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + if (unlikely(!module)) goto ignore; + is_coroutine_value = __Pyx_PyObject_GetAttrStr(module, marker); + Py_DECREF(module); + if (likely(is_coroutine_value)) { + return is_coroutine_value; + } +ignore: + PyErr_Clear(); + } + return __Pyx_PyBool_FromLong(is_coroutine); +} +static PyObject * +__Pyx_CyFunction_get_is_coroutine(__pyx_CyFunctionObject *op, void *context) { + PyObject *result; + CYTHON_UNUSED_VAR(context); + if (op->func_is_coroutine) { + return __Pyx_NewRef(op->func_is_coroutine); + } + result = __Pyx_CyFunction_get_is_coroutine_value(op); + if (unlikely(!result)) + return NULL; + __Pyx_BEGIN_CRITICAL_SECTION(op); + if (op->func_is_coroutine) { + Py_DECREF(result); + result = __Pyx_NewRef(op->func_is_coroutine); + } else { + op->func_is_coroutine = __Pyx_NewRef(result); + } + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static void __Pyx_CyFunction_raise_argument_count_error(__pyx_CyFunctionObject *func, const char* message, Py_ssize_t size) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_name = __Pyx_CyFunction_get_name(func, NULL); + if (!py_name) return; + PyErr_Format(PyExc_TypeError, + "%.200S() %s (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, message, size); + Py_DECREF(py_name); +#else + const char* name = ((PyCFunctionObject*)func)->m_ml->ml_name; + PyErr_Format(PyExc_TypeError, + "%.200s() %s (%" CYTHON_FORMAT_SSIZE_T "d given)", + name, message, size); +#endif +} +static void __Pyx_CyFunction_raise_type_error(__pyx_CyFunctionObject *func, const char* message) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_name = __Pyx_CyFunction_get_name(func, NULL); + if (!py_name) return; + PyErr_Format(PyExc_TypeError, + "%.200S() %s", + py_name, message); + Py_DECREF(py_name); +#else + const char* name = ((PyCFunctionObject*)func)->m_ml->ml_name; + PyErr_Format(PyExc_TypeError, + "%.200s() %s", + name, message); +#endif +} +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject * +__Pyx_CyFunction_get_module(__pyx_CyFunctionObject *op, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_GetAttrString(op->func, "__module__"); +} +static int +__Pyx_CyFunction_set_module(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_SetAttrString(op->func, "__module__", value); +} +#endif +static PyGetSetDef __pyx_CyFunction_getsets[] = { + {"func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {"__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {"func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {"__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {"__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 + {"func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)PyObject_GenericSetDict, 0, 0}, + {"__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)PyObject_GenericSetDict, 0, 0}, +#else + {"func_dict", (getter)PyObject_GenericGetDict, (setter)PyObject_GenericSetDict, 0, 0}, + {"__dict__", (getter)PyObject_GenericGetDict, (setter)PyObject_GenericSetDict, 0, 0}, +#endif + {"func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {"__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {"func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {"__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {"func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {"__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {"func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {"__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {"__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, + {"__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, + {"_is_coroutine", (getter)__Pyx_CyFunction_get_is_coroutine, 0, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API + {"__module__", (getter)__Pyx_CyFunction_get_module, (setter)__Pyx_CyFunction_set_module, 0, 0}, +#endif + {0, 0, 0, 0, 0} +}; +static PyMemberDef __pyx_CyFunction_members[] = { +#if !CYTHON_COMPILING_IN_LIMITED_API + {"__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), 0, 0}, +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + {"__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0}, +#endif +#if CYTHON_METH_FASTCALL +#if CYTHON_COMPILING_IN_LIMITED_API + {"__vectorcalloffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_vectorcall), READONLY, 0}, +#else + {"__vectorcalloffset__", T_PYSSIZET, offsetof(PyCFunctionObject, vectorcall), READONLY, 0}, +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + {"__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0}, +#else + {"__weaklistoffset__", T_PYSSIZET, offsetof(PyCFunctionObject, m_weakreflist), READONLY, 0}, +#endif +#endif + {0, 0, 0, 0, 0} +}; +static PyObject * +__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, PyObject *args) +{ + PyObject *result = NULL; + CYTHON_UNUSED_VAR(args); + __Pyx_BEGIN_CRITICAL_SECTION(m); + Py_INCREF(m->func_qualname); + result = m->func_qualname; + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static PyMethodDef __pyx_CyFunction_methods[] = { + {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, + {0, 0, 0, 0} +}; +#if CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) +#else +#define __Pyx_CyFunction_weakreflist(cyfunc) (((PyCFunctionObject*)cyfunc)->m_weakreflist) +#endif +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { +#if !CYTHON_COMPILING_IN_LIMITED_API + PyCFunctionObject *cf = (PyCFunctionObject*) op; +#endif + if (unlikely(op == NULL)) + return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + op->func = PyCFunction_NewEx(ml, (PyObject*)op, module); + if (unlikely(!op->func)) return NULL; +#endif + op->flags = flags; + __Pyx_CyFunction_weakreflist(op) = NULL; +#if !CYTHON_COMPILING_IN_LIMITED_API + cf->m_ml = ml; + cf->m_self = (PyObject *) op; +#endif + Py_XINCREF(closure); + op->func_closure = closure; +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_XINCREF(module); + cf->m_module = module; +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + op->func_dict = NULL; +#endif + op->func_name = NULL; + Py_INCREF(qualname); + op->func_qualname = qualname; + op->func_doc = NULL; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + op->func_classobj = NULL; +#else + ((PyCMethodObject*)op)->mm_class = NULL; +#endif + op->func_globals = globals; + Py_INCREF(op->func_globals); + Py_XINCREF(code); + op->func_code = code; + op->defaults = NULL; + op->defaults_tuple = NULL; + op->defaults_kwdict = NULL; + op->defaults_getter = NULL; + op->func_annotations = NULL; + op->func_is_coroutine = NULL; +#if CYTHON_METH_FASTCALL + switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { + case METH_NOARGS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS; + break; + case METH_O: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O; + break; + case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD; + break; + case METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS; + break; + case METH_VARARGS | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = NULL; + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + Py_DECREF(op); + return NULL; + } +#endif + return (PyObject *) op; +} +static int +__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) +{ + Py_CLEAR(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func); +#else + Py_CLEAR(((PyCFunctionObject*)m)->m_module); +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func_dict); +#elif PY_VERSION_HEX < 0x030d0000 + _PyObject_ClearManagedDict((PyObject*)m); +#else + PyObject_ClearManagedDict((PyObject*)m); +#endif + Py_CLEAR(m->func_name); + Py_CLEAR(m->func_qualname); + Py_CLEAR(m->func_doc); + Py_CLEAR(m->func_globals); + Py_CLEAR(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API +#if PY_VERSION_HEX < 0x030900B1 + Py_CLEAR(__Pyx_CyFunction_GetClassObj(m)); +#else + { + PyObject *cls = (PyObject*) ((PyCMethodObject *) (m))->mm_class; + ((PyCMethodObject *) (m))->mm_class = NULL; + Py_XDECREF(cls); + } +#endif +#endif + Py_CLEAR(m->defaults_tuple); + Py_CLEAR(m->defaults_kwdict); + Py_CLEAR(m->func_annotations); + Py_CLEAR(m->func_is_coroutine); + Py_CLEAR(m->defaults); + return 0; +} +static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + if (__Pyx_CyFunction_weakreflist(m) != NULL) + PyObject_ClearWeakRefs((PyObject *) m); + __Pyx_CyFunction_clear(m); + __Pyx_PyHeapTypeObject_GC_Del(m); +} +static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + PyObject_GC_UnTrack(m); + __Pyx__CyFunction_dealloc(m); +} +static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) +{ + { + int e = __Pyx_call_type_traverse((PyObject*)m, 1, visit, arg); + if (e) return e; + } + Py_VISIT(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func); +#else + Py_VISIT(((PyCFunctionObject*)m)->m_module); +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func_dict); +#else + { + int e = +#if PY_VERSION_HEX < 0x030d0000 + _PyObject_VisitManagedDict +#else + PyObject_VisitManagedDict +#endif + ((PyObject*)m, visit, arg); + if (e != 0) return e; + } +#endif + __Pyx_VISIT_CONST(m->func_name); + __Pyx_VISIT_CONST(m->func_qualname); + Py_VISIT(m->func_doc); + Py_VISIT(m->func_globals); + __Pyx_VISIT_CONST(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(__Pyx_CyFunction_GetClassObj(m)); +#endif + Py_VISIT(m->defaults_tuple); + Py_VISIT(m->defaults_kwdict); + Py_VISIT(m->func_is_coroutine); + Py_VISIT(m->defaults); + return 0; +} +static PyObject* +__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) +{ + PyObject *repr; + __Pyx_BEGIN_CRITICAL_SECTION(op); + repr = PyUnicode_FromFormat("", + op->func_qualname, (void *)op); + __Pyx_END_CRITICAL_SECTION(); + return repr; +} +static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *f = ((__pyx_CyFunctionObject*)func)->func; + PyCFunction meth; + int flags; + meth = PyCFunction_GetFunction(f); + if (unlikely(!meth)) return NULL; + flags = PyCFunction_GetFlags(f); + if (unlikely(flags < 0)) return NULL; +#else + PyCFunctionObject* f = (PyCFunctionObject*)func; + PyCFunction meth = f->m_ml->ml_meth; + int flags = f->m_ml->ml_flags; +#endif + Py_ssize_t size; + switch (flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { + case METH_VARARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) + return (*meth)(self, arg); + break; + case METH_VARARGS | METH_KEYWORDS: + return (*(PyCFunctionWithKeywords)(void(*)(void))meth)(self, arg, kw); + case METH_NOARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_SIZE + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 0)) + return (*meth)(self, NULL); + __Pyx_CyFunction_raise_argument_count_error( + (__pyx_CyFunctionObject*)func, + "takes no arguments", size); + return NULL; + } + break; + case METH_O: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_SIZE + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 1)) { + PyObject *result, *arg0; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + arg0 = PyTuple_GET_ITEM(arg, 0); + #else + arg0 = __Pyx_PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; + #endif + result = (*meth)(self, arg0); + #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(arg0); + #endif + return result; + } + __Pyx_CyFunction_raise_argument_count_error( + (__pyx_CyFunctionObject*)func, + "takes exactly one argument", size); + return NULL; + } + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + return NULL; + } + __Pyx_CyFunction_raise_type_error( + (__pyx_CyFunctionObject*)func, "takes no keyword arguments"); + return NULL; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *self, *result; +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)func)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)func)->m_self; +#endif + result = __Pyx_CyFunction_CallMethod(func, self, arg, kw); + return result; +} +static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) { + PyObject *result; + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL + __pyx_vectorcallfunc vc = __Pyx_CyFunction_func_vectorcall(cyfunc); + if (vc) { +#if CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE + return __Pyx_PyVectorcall_FastCallDict(func, vc, &PyTuple_GET_ITEM(args, 0), (size_t)PyTuple_GET_SIZE(args), kw); +#else + (void) &__Pyx_PyVectorcall_FastCallDict; + return PyVectorcall_Call(func, args, kw); +#endif + } +#endif + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + Py_ssize_t argc; + PyObject *new_args; + PyObject *self; +#if CYTHON_ASSUME_SAFE_SIZE + argc = PyTuple_GET_SIZE(args); +#else + argc = PyTuple_Size(args); + if (unlikely(argc < 0)) return NULL; +#endif + new_args = PyTuple_GetSlice(args, 1, argc); + if (unlikely(!new_args)) + return NULL; + self = PyTuple_GetItem(args, 0); + if (unlikely(!self)) { + Py_DECREF(new_args); + PyErr_Format(PyExc_TypeError, + "unbound method %.200S() needs an argument", + cyfunc->func_qualname); + return NULL; + } + result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw); + Py_DECREF(new_args); + } else { + result = __Pyx_CyFunction_Call(func, args, kw); + } + return result; +} +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL +static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionObject *cyfunc, Py_ssize_t nargs, PyObject *kwnames) +{ + int ret = 0; + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + if (unlikely(nargs < 1)) { + __Pyx_CyFunction_raise_type_error( + cyfunc, "needs an argument"); + return -1; + } + ret = 1; + } + if (unlikely(kwnames) && unlikely(__Pyx_PyTuple_GET_SIZE(kwnames))) { + __Pyx_CyFunction_raise_type_error( + cyfunc, "takes no keyword arguments"); + return -1; + } + return ret; +} +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + if (unlikely(nargs != 0)) { + __Pyx_CyFunction_raise_argument_count_error( + cyfunc, "takes no arguments", nargs); + return NULL; + } + return meth(self, NULL); +} +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + if (unlikely(nargs != 1)) { + __Pyx_CyFunction_raise_argument_count_error( + cyfunc, "takes exactly one argument", nargs); + return NULL; + } + return meth(self, args[0]); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + return ((__Pyx_PyCFunctionFastWithKeywords)(void(*)(void))meth)(self, args, nargs, kwnames); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyTypeObject *cls = (PyTypeObject *) __Pyx_CyFunction_GetClassObj(cyfunc); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + #if PY_VERSION_HEX < 0x030e00A6 + size_t nargs_value = (size_t) nargs; + #else + Py_ssize_t nargs_value = nargs; + #endif + return ((__Pyx_PyCMethod)(void(*)(void))meth)(self, cls, args, nargs_value, kwnames); +} +#endif +static PyType_Slot __pyx_CyFunctionType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc}, + {Py_tp_repr, (void *)__Pyx_CyFunction_repr}, + {Py_tp_call, (void *)__Pyx_CyFunction_CallAsMethod}, + {Py_tp_traverse, (void *)__Pyx_CyFunction_traverse}, + {Py_tp_clear, (void *)__Pyx_CyFunction_clear}, + {Py_tp_methods, (void *)__pyx_CyFunction_methods}, + {Py_tp_members, (void *)__pyx_CyFunction_members}, + {Py_tp_getset, (void *)__pyx_CyFunction_getsets}, + {Py_tp_descr_get, (void *)__Pyx_PyMethod_New}, + {0, 0}, +}; +static PyType_Spec __pyx_CyFunctionType_spec = { + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if CYTHON_METH_FASTCALL +#if defined(Py_TPFLAGS_HAVE_VECTORCALL) + Py_TPFLAGS_HAVE_VECTORCALL | +#elif defined(_Py_TPFLAGS_HAVE_VECTORCALL) + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif +#endif // CYTHON_METH_FASTCALL +#if PY_VERSION_HEX >= 0x030C0000 && !CYTHON_COMPILING_IN_LIMITED_API + Py_TPFLAGS_MANAGED_DICT | +#endif + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + __pyx_CyFunctionType_slots +}; +static int __pyx_CyFunction_init(PyObject *module) { + __pyx_mstatetype *mstate = __Pyx_PyModule_GetState(module); + mstate->__pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec( + mstate->__pyx_CommonTypesMetaclassType, module, &__pyx_CyFunctionType_spec, NULL); + if (unlikely(mstate->__pyx_CyFunctionType == NULL)) { + return -1; + } + return 0; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_InitDefaults(PyObject *func, PyTypeObject *defaults_type) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults = PyObject_CallObject((PyObject*)defaults_type, NULL); // _PyObject_New(defaults_type); + if (unlikely(!m->defaults)) + return NULL; + return m->defaults; +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_tuple = tuple; + Py_INCREF(tuple); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_kwdict = dict; + Py_INCREF(dict); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->func_annotations = dict; + Py_INCREF(dict); +} + +/* CythonFunction */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { + PyObject *op = __Pyx_CyFunction_Init( + PyObject_GC_New(__pyx_CyFunctionObject, __pyx_mstate_global->__pyx_CyFunctionType), + ml, flags, qualname, closure, module, globals, code + ); + if (likely(op)) { + PyObject_GC_Track(op); + } + return op; +} + +/* PyObjectCall2Args (used by Py3ClassCreate) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args[3] = {NULL, arg1, arg2}; + return __Pyx_PyObject_FastCall(function, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectLookupSpecial (used by Py3ClassCreate) */ +#if CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx__PyObject_LookupSpecial(PyObject* obj, PyObject* attr_name, int with_error) { + PyObject *res; + PyTypeObject *tp = Py_TYPE(obj); + res = _PyType_Lookup(tp, attr_name); + if (likely(res)) { + descrgetfunc f = Py_TYPE(res)->tp_descr_get; + if (!f) { + Py_INCREF(res); + } else { + res = f(res, obj, (PyObject *)tp); + } + } else if (with_error) { + PyErr_SetObject(PyExc_AttributeError, attr_name); + } + return res; +} +#endif + +/* Py3ClassCreate */ +static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, + PyObject *qualname, PyObject *mkw, PyObject *modname, PyObject *doc) { + PyObject *ns; + if (metaclass) { + PyObject *prep = __Pyx_PyObject_GetAttrStrNoError(metaclass, __pyx_mstate_global->__pyx_n_u_prepare); + if (prep) { + PyObject *pargs[3] = {NULL, name, bases}; + ns = __Pyx_PyObject_FastCallDict(prep, pargs+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET, mkw); + Py_DECREF(prep); + } else { + if (unlikely(PyErr_Occurred())) + return NULL; + ns = PyDict_New(); + } + } else { + ns = PyDict_New(); + } + if (unlikely(!ns)) + return NULL; + if (unlikely(PyObject_SetItem(ns, __pyx_mstate_global->__pyx_n_u_module, modname) < 0)) goto bad; + if (unlikely(PyObject_SetItem(ns, __pyx_mstate_global->__pyx_n_u_qualname, qualname) < 0)) goto bad; + if (unlikely(doc && PyObject_SetItem(ns, __pyx_mstate_global->__pyx_n_u_doc, doc) < 0)) goto bad; + return ns; +bad: + Py_DECREF(ns); + return NULL; +} +static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, + PyObject *dict, PyObject *mkw, + int calculate_metaclass, int allow_py2_metaclass) { + PyObject *result; + PyObject *owned_metaclass = NULL; + PyObject *margs[4] = {NULL, name, bases, dict}; + if (allow_py2_metaclass) { + owned_metaclass = PyObject_GetItem(dict, __pyx_mstate_global->__pyx_n_u_metaclass); + if (owned_metaclass) { + metaclass = owned_metaclass; + } else if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) { + PyErr_Clear(); + } else { + return NULL; + } + } + if (calculate_metaclass && (!metaclass || PyType_Check(metaclass))) { + metaclass = __Pyx_CalculateMetaclass((PyTypeObject*) metaclass, bases); + Py_XDECREF(owned_metaclass); + if (unlikely(!metaclass)) + return NULL; + owned_metaclass = metaclass; + } + result = __Pyx_PyObject_FastCallDict(metaclass, margs+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET, mkw); + Py_XDECREF(owned_metaclass); + return result; +} + +/* CLineInTraceback (used by AddTraceback) */ +#if CYTHON_CLINE_IN_TRACEBACK && CYTHON_CLINE_IN_TRACEBACK_RUNTIME +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 +#define __Pyx_PyProbablyModule_GetDict(o) __Pyx_XNewRef(PyModule_GetDict(o)) +#elif !CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __Pyx_PyProbablyModule_GetDict(o) PyObject_GenericGetDict(o, NULL); +#else +PyObject* __Pyx_PyProbablyModule_GetDict(PyObject *o) { + PyObject **dict_ptr = _PyObject_GetDictPtr(o); + return dict_ptr ? __Pyx_XNewRef(*dict_ptr) : NULL; +} +#endif +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { + PyObject *use_cline = NULL; + PyObject *ptype, *pvalue, *ptraceback; + PyObject *cython_runtime_dict; + CYTHON_MAYBE_UNUSED_VAR(tstate); + if (unlikely(!__pyx_mstate_global->__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + cython_runtime_dict = __Pyx_PyProbablyModule_GetDict(__pyx_mstate_global->__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, cython_runtime_dict, + __Pyx_PyDict_SetDefault(cython_runtime_dict, __pyx_mstate_global->__pyx_n_u_cline_in_traceback, Py_False)) + } + if (use_cline == NULL || use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + Py_XDECREF(use_cline); + Py_XDECREF(cython_runtime_dict); + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache (used by AddTraceback) */ +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static __Pyx_CachedCodeObjectType *__pyx__find_code_object(struct __Pyx_CodeObjectCache *code_cache, int code_line) { + __Pyx_CachedCodeObjectType* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!code_cache->entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(code_cache->entries, code_cache->count, code_line); + if (unlikely(pos >= code_cache->count) || unlikely(code_cache->entries[pos].code_line != code_line)) { + return NULL; + } + code_object = code_cache->entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static __Pyx_CachedCodeObjectType *__pyx_find_code_object(int code_line) { +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && !CYTHON_ATOMICS + (void)__pyx__find_code_object; + return NULL; // Most implementation should have atomics. But otherwise, don't make it thread-safe, just miss. +#else + struct __Pyx_CodeObjectCache *code_cache = &__pyx_mstate_global->__pyx_code_cache; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_nonatomic_int_type old_count = __pyx_atomic_incr_acq_rel(&code_cache->accessor_count); + if (old_count < 0) { + __pyx_atomic_decr_acq_rel(&code_cache->accessor_count); + return NULL; + } +#endif + __Pyx_CachedCodeObjectType *result = __pyx__find_code_object(code_cache, code_line); +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_atomic_decr_acq_rel(&code_cache->accessor_count); +#endif + return result; +#endif +} +static void __pyx__insert_code_object(struct __Pyx_CodeObjectCache *code_cache, int code_line, __Pyx_CachedCodeObjectType* code_object) +{ + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = code_cache->entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + code_cache->entries = entries; + code_cache->max_count = 64; + code_cache->count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(code_cache->entries, code_cache->count, code_line); + if ((pos < code_cache->count) && unlikely(code_cache->entries[pos].code_line == code_line)) { + __Pyx_CachedCodeObjectType* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_INCREF(code_object); + Py_DECREF(tmp); + return; + } + if (code_cache->count == code_cache->max_count) { + int new_max = code_cache->max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + code_cache->entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + code_cache->entries = entries; + code_cache->max_count = new_max; + } + for (i=code_cache->count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + code_cache->count++; + Py_INCREF(code_object); +} +static void __pyx_insert_code_object(int code_line, __Pyx_CachedCodeObjectType* code_object) { +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && !CYTHON_ATOMICS + (void)__pyx__insert_code_object; + return; // Most implementation should have atomics. But otherwise, don't make it thread-safe, just fail. +#else + struct __Pyx_CodeObjectCache *code_cache = &__pyx_mstate_global->__pyx_code_cache; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_nonatomic_int_type expected = 0; + if (!__pyx_atomic_int_cmp_exchange(&code_cache->accessor_count, &expected, INT_MIN)) { + return; + } +#endif + __pyx__insert_code_object(code_cache, code_line, code_object); +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_atomic_sub(&code_cache->accessor_count, INT_MIN); +#endif +#endif +} + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION) + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyCode_Replace_For_AddTraceback(PyObject *code, PyObject *scratch_dict, + PyObject *firstlineno, PyObject *name) { + PyObject *replace = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_firstlineno", firstlineno))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_name", name))) return NULL; + replace = PyObject_GetAttrString(code, "replace"); + if (likely(replace)) { + PyObject *result = PyObject_Call(replace, __pyx_mstate_global->__pyx_empty_tuple, scratch_dict); + Py_DECREF(replace); + return result; + } + PyErr_Clear(); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyObject *code_object = NULL, *py_py_line = NULL, *py_funcname = NULL, *dict = NULL; + PyObject *replace = NULL, *getframe = NULL, *frame = NULL; + PyObject *exc_type, *exc_value, *exc_traceback; + int success = 0; + if (c_line) { + c_line = __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line); + } + PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); + code_object = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!code_object) { + code_object = Py_CompileString("_getframe()", filename, Py_eval_input); + if (unlikely(!code_object)) goto bad; + py_py_line = PyLong_FromLong(py_line); + if (unlikely(!py_py_line)) goto bad; + if (c_line) { + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + } else { + py_funcname = PyUnicode_FromString(funcname); + } + if (unlikely(!py_funcname)) goto bad; + dict = PyDict_New(); + if (unlikely(!dict)) goto bad; + { + PyObject *old_code_object = code_object; + code_object = __Pyx_PyCode_Replace_For_AddTraceback(code_object, dict, py_py_line, py_funcname); + Py_DECREF(old_code_object); + } + if (unlikely(!code_object)) goto bad; + __pyx_insert_code_object(c_line ? -c_line : py_line, code_object); + } else { + dict = PyDict_New(); + } + getframe = PySys_GetObject("_getframe"); + if (unlikely(!getframe)) goto bad; + if (unlikely(PyDict_SetItemString(dict, "_getframe", getframe))) goto bad; + frame = PyEval_EvalCode(code_object, dict, dict); + if (unlikely(!frame) || frame == Py_None) goto bad; + success = 1; + bad: + PyErr_Restore(exc_type, exc_value, exc_traceback); + Py_XDECREF(code_object); + Py_XDECREF(py_py_line); + Py_XDECREF(py_funcname); + Py_XDECREF(dict); + Py_XDECREF(replace); + if (success) { + PyTraceBack_Here( + (struct _frame*)frame); + } + Py_XDECREF(frame); +} +#else +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = NULL; + PyObject *py_funcname = NULL; + if (c_line) { + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + funcname = PyUnicode_AsUTF8(py_funcname); + if (!funcname) goto bad; + } + py_code = PyCode_NewEmpty(filename, funcname, py_line); + Py_XDECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_funcname); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject *ptype, *pvalue, *ptraceback; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) { + /* If the code object creation fails, then we should clear the + fetched exception references and propagate the new exception */ + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + goto bad; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_mstate_global->__pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} +#endif + +/* FormatTypeName */ +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030d0000 +static __Pyx_TypeName +__Pyx_PyType_GetFullyQualifiedName(PyTypeObject* tp) +{ + PyObject *module = NULL, *name = NULL, *result = NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030b0000 + name = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_mstate_global->__pyx_n_u_qualname); + #else + name = PyType_GetQualName(tp); + #endif + if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) goto bad; + module = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_mstate_global->__pyx_n_u_module); + if (unlikely(module == NULL) || unlikely(!PyUnicode_Check(module))) goto bad; + if (PyUnicode_CompareWithASCIIString(module, "builtins") == 0) { + result = name; + name = NULL; + goto done; + } + result = PyUnicode_FromFormat("%U.%U", module, name); + if (unlikely(result == NULL)) goto bad; + done: + Py_XDECREF(name); + Py_XDECREF(module); + return result; + bad: + PyErr_Clear(); + if (name) { + result = name; + name = NULL; + } else { + result = __Pyx_NewRef(__pyx_mstate_global->__pyx_kp_u__2); + } + goto done; +} +#endif + +/* PyObjectVectorCallKwBuilder (used by CIntToPy) */ +#if CYTHON_VECTORCALL +static int __Pyx_VectorcallBuilder_AddArg(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n) { + (void)__Pyx_PyObject_FastCallDict; + if (__Pyx_PyTuple_SET_ITEM(builder, n, key) != (0)) return -1; + Py_INCREF(key); + args[n] = value; + return 0; +} +CYTHON_UNUSED static int __Pyx_VectorcallBuilder_AddArg_Check(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n) { + (void)__Pyx_VectorcallBuilder_AddArgStr; + if (unlikely(!PyUnicode_Check(key))) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + return -1; + } + return __Pyx_VectorcallBuilder_AddArg(key, value, builder, args, n); +} +static int __Pyx_VectorcallBuilder_AddArgStr(const char *key, PyObject *value, PyObject *builder, PyObject **args, int n) { + PyObject *pyKey = PyUnicode_FromString(key); + if (!pyKey) return -1; + return __Pyx_VectorcallBuilder_AddArg(pyKey, value, builder, args, n); +} +#else // CYTHON_VECTORCALL +CYTHON_UNUSED static int __Pyx_VectorcallBuilder_AddArg_Check(PyObject *key, PyObject *value, PyObject *builder, CYTHON_UNUSED PyObject **args, CYTHON_UNUSED int n) { + if (unlikely(!PyUnicode_Check(key))) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + return -1; + } + return PyDict_SetItem(builder, key, value); +} +#endif + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyLong_From_long(long value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyLong_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#if !CYTHON_COMPILING_IN_PYPY + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyLong_FromLong((long) value); + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); + } + } + { + unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d00A4 + if (is_unsigned) { + return PyLong_FromUnsignedNativeBytes(bytes, sizeof(value), -1); + } else { + return PyLong_FromNativeBytes(bytes, sizeof(value), -1); + } +#elif !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 + int one = 1; int little = (int)*(unsigned char *)&one; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); +#else + int one = 1; int little = (int)*(unsigned char *)&one; + PyObject *from_bytes, *result = NULL, *kwds = NULL; + PyObject *py_bytes = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(long)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + { + PyObject *args[3+(CYTHON_VECTORCALL ? 1 : 0)] = { NULL, py_bytes, order_str }; + if (!is_unsigned) { + kwds = __Pyx_MakeVectorcallBuilderKwds(1); + if (!kwds) goto limited_bad; + if (__Pyx_VectorcallBuilder_AddArgStr("signed", __Pyx_NewRef(Py_True), kwds, args+3, 0) < 0) goto limited_bad; + } + result = __Pyx_Object_Vectorcall_CallFromBuilder(from_bytes, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET, kwds); + } + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif + } +} + +/* CIntFromPyVerify (used by CIntFromPy) */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyLong_As_long(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (unlikely(!PyLong_Check(x))) { + long val; + PyObject *tmp = __Pyx_PyNumber_Long(x); + if (!tmp) return (long) -1; + val = __Pyx_PyLong_As_long(tmp); + Py_DECREF(tmp); + return val; + } + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 2 * PyLong_SHIFT)) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 3 * PyLong_SHIFT)) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 4 * PyLong_SHIFT)) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(long) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) + } else if ((sizeof(long) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(long) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(long) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) + } else if ((sizeof(long) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) + } + } + { + long val; + int ret = -1; +#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API + Py_ssize_t bytes_copied = PyLong_AsNativeBytes( + x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0)); + if (unlikely(bytes_copied == -1)) { + } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) { + goto raise_overflow; + } else { + ret = 0; + } +#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)x, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *v; + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (likely(PyLong_CheckExact(x))) { + v = __Pyx_NewRef(x); + } else { + v = PyNumber_Long(x); + if (unlikely(!v)) return (long) -1; + assert(PyLong_CheckExact(v)); + } + { + int result = PyObject_RichCompareBool(v, Py_False, Py_LT); + if (unlikely(result < 0)) { + Py_DECREF(v); + return (long) -1; + } + is_negative = result == 1; + } + if (is_unsigned && unlikely(is_negative)) { + Py_DECREF(v); + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + Py_DECREF(v); + if (unlikely(!stepval)) + return (long) -1; + } else { + stepval = v; + } + v = NULL; + val = (long) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(long) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + long idigit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + val |= ((long) idigit) << bits; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + } + Py_DECREF(shift); shift = NULL; + Py_DECREF(mask); mask = NULL; + { + long idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(long) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((long) idigit) << bits; + } + if (!is_unsigned) { + if (unlikely(val & (((long) 1) << (sizeof(long) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + if (unlikely(ret)) + return (long) -1; + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyLong_As_int(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (unlikely(!PyLong_Check(x))) { + int val; + PyObject *tmp = __Pyx_PyNumber_Long(x); + if (!tmp) return (int) -1; + val = __Pyx_PyLong_As_int(tmp); + Py_DECREF(tmp); + return val; + } + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 2 * PyLong_SHIFT)) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 3 * PyLong_SHIFT)) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 4 * PyLong_SHIFT)) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(int) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) + } else if ((sizeof(int) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(int) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(int) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) + } else if ((sizeof(int) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) + } + } + { + int val; + int ret = -1; +#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API + Py_ssize_t bytes_copied = PyLong_AsNativeBytes( + x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0)); + if (unlikely(bytes_copied == -1)) { + } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) { + goto raise_overflow; + } else { + ret = 0; + } +#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)x, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *v; + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (likely(PyLong_CheckExact(x))) { + v = __Pyx_NewRef(x); + } else { + v = PyNumber_Long(x); + if (unlikely(!v)) return (int) -1; + assert(PyLong_CheckExact(v)); + } + { + int result = PyObject_RichCompareBool(v, Py_False, Py_LT); + if (unlikely(result < 0)) { + Py_DECREF(v); + return (int) -1; + } + is_negative = result == 1; + } + if (is_unsigned && unlikely(is_negative)) { + Py_DECREF(v); + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + Py_DECREF(v); + if (unlikely(!stepval)) + return (int) -1; + } else { + stepval = v; + } + v = NULL; + val = (int) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(int) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + long idigit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + val |= ((int) idigit) << bits; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + } + Py_DECREF(shift); shift = NULL; + Py_DECREF(mask); mask = NULL; + { + long idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(int) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((int) idigit) << bits; + } + if (!is_unsigned) { + if (unlikely(val & (((int) 1) << (sizeof(int) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + if (unlikely(ret)) + return (int) -1; + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = __Pyx_PyType_GetSlot(a, tp_base, PyTypeObject*); + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (cls == a || cls == b) return 1; + mro = cls->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + PyObject *base = PyTuple_GET_ITEM(mro, i); + if (base == (PyObject *)a || base == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(cls, a) || __Pyx_InBases(cls, b); +} +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + if (exc_type1) { + return __Pyx_IsAnySubtype2((PyTypeObject*)err, (PyTypeObject*)exc_type1, (PyTypeObject*)exc_type2); + } else { + return __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } +} +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); + for (i=0; i>= 8; + ++i; + } + __Pyx_cached_runtime_version = version; + } +} +#endif +static unsigned long __Pyx_get_runtime_version(void) { +#if __PYX_LIMITED_VERSION_HEX >= 0x030b0000 + return Py_Version & ~0xFFUL; +#else + return __Pyx_cached_runtime_version; +#endif +} + +/* CheckBinaryVersion */ +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer) { + const unsigned long MAJOR_MINOR = 0xFFFF0000UL; + if ((rt_version & MAJOR_MINOR) == (ct_version & MAJOR_MINOR)) + return 0; + if (likely(allow_newer && (rt_version & MAJOR_MINOR) > (ct_version & MAJOR_MINOR))) + return 1; + { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compile time Python version %d.%d " + "of module '%.100s' " + "%s " + "runtime version %d.%d", + (int) (ct_version >> 24), (int) ((ct_version >> 16) & 0xFF), + __Pyx_MODULE_NAME, + (allow_newer) ? "was newer than" : "does not match", + (int) (rt_version >> 24), (int) ((rt_version >> 16) & 0xFF) + ); + return PyErr_WarnEx(NULL, message, 1); + } +} + +/* NewCodeObj */ +#if CYTHON_COMPILING_IN_LIMITED_API + static PyObject* __Pyx__PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyObject *exception_table = NULL; + PyObject *types_module=NULL, *code_type=NULL, *result=NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030b0000 + PyObject *version_info; + PyObject *py_minor_version = NULL; + #endif + long minor_version = 0; + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + #if __PYX_LIMITED_VERSION_HEX >= 0x030b0000 + minor_version = 11; + #else + if (!(version_info = PySys_GetObject("version_info"))) goto end; + if (!(py_minor_version = PySequence_GetItem(version_info, 1))) goto end; + minor_version = PyLong_AsLong(py_minor_version); + Py_DECREF(py_minor_version); + if (minor_version == -1 && PyErr_Occurred()) goto end; + #endif + if (!(types_module = PyImport_ImportModule("types"))) goto end; + if (!(code_type = PyObject_GetAttrString(types_module, "CodeType"))) goto end; + if (minor_version <= 7) { + (void)p; + result = PyObject_CallFunction(code_type, "iiiiiOOOOOOiOOO", a, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else if (minor_version <= 10) { + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOiOOO", a,p, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else { + if (!(exception_table = PyBytes_FromStringAndSize(NULL, 0))) goto end; + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOOiOOOO", a,p, k, l, s, f, code, + c, n, v, fn, name, name, fline, lnos, exception_table, fv, cell); + } + end: + Py_XDECREF(code_type); + Py_XDECREF(exception_table); + Py_XDECREF(types_module); + if (type) { + PyErr_Restore(type, value, traceback); + } + return result; + } +#elif PY_VERSION_HEX >= 0x030B0000 + static PyCodeObject* __Pyx__PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyCodeObject *result; + result = + #if PY_VERSION_HEX >= 0x030C0000 + PyUnstable_Code_NewWithPosOnlyArgs + #else + PyCode_NewWithPosOnlyArgs + #endif + (a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, __pyx_mstate_global->__pyx_empty_bytes); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030c00A1 + if (likely(result)) + result->_co_firsttraceable = 0; + #endif + return result; + } +#elif !CYTHON_COMPILING_IN_PYPY + #define __Pyx__PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_NewWithPosOnlyArgs(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx__PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif +static PyObject* __Pyx_PyCode_New( + const __Pyx_PyCode_New_function_description descr, + PyObject * const *varnames, + PyObject *filename, + PyObject *funcname, + PyObject *line_table, + PyObject *tuple_dedup_map +) { + PyObject *code_obj = NULL, *varnames_tuple_dedup = NULL, *code_bytes = NULL; + Py_ssize_t var_count = (Py_ssize_t) descr.nlocals; + PyObject *varnames_tuple = PyTuple_New(var_count); + if (unlikely(!varnames_tuple)) return NULL; + for (Py_ssize_t i=0; i < var_count; i++) { + Py_INCREF(varnames[i]); + if (__Pyx_PyTuple_SET_ITEM(varnames_tuple, i, varnames[i]) != (0)) goto done; + } + #if CYTHON_COMPILING_IN_LIMITED_API + varnames_tuple_dedup = PyDict_GetItem(tuple_dedup_map, varnames_tuple); + if (!varnames_tuple_dedup) { + if (unlikely(PyDict_SetItem(tuple_dedup_map, varnames_tuple, varnames_tuple) < 0)) goto done; + varnames_tuple_dedup = varnames_tuple; + } + #else + varnames_tuple_dedup = PyDict_SetDefault(tuple_dedup_map, varnames_tuple, varnames_tuple); + if (unlikely(!varnames_tuple_dedup)) goto done; + #endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(varnames_tuple_dedup); + #endif + if (__PYX_LIMITED_VERSION_HEX >= (0x030b0000) && line_table != NULL && !CYTHON_COMPILING_IN_GRAAL) { + Py_ssize_t line_table_length = __Pyx_PyBytes_GET_SIZE(line_table); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(line_table_length == -1)) goto done; + #endif + Py_ssize_t code_len = (line_table_length * 2 + 4) & ~3LL; + code_bytes = PyBytes_FromStringAndSize(NULL, code_len); + if (unlikely(!code_bytes)) goto done; + char* c_code_bytes = PyBytes_AsString(code_bytes); + if (unlikely(!c_code_bytes)) goto done; + memset(c_code_bytes, 0, (size_t) code_len); + } + code_obj = (PyObject*) __Pyx__PyCode_New( + (int) descr.argcount, + (int) descr.num_posonly_args, + (int) descr.num_kwonly_args, + (int) descr.nlocals, + 0, + (int) descr.flags, + code_bytes ? code_bytes : __pyx_mstate_global->__pyx_empty_bytes, + __pyx_mstate_global->__pyx_empty_tuple, + __pyx_mstate_global->__pyx_empty_tuple, + varnames_tuple_dedup, + __pyx_mstate_global->__pyx_empty_tuple, + __pyx_mstate_global->__pyx_empty_tuple, + filename, + funcname, + (int) descr.first_line, + (__PYX_LIMITED_VERSION_HEX >= (0x030b0000) && line_table) ? line_table : __pyx_mstate_global->__pyx_empty_bytes + ); +done: + Py_XDECREF(code_bytes); + #if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(varnames_tuple_dedup); + #endif + Py_DECREF(varnames_tuple); + return code_obj; +} + +/* DecompressString */ +static PyObject *__Pyx_DecompressString(const char *s, Py_ssize_t length, int algo) { + PyObject *module, *decompress, *compressed_bytes, *decompressed; + const char* module_name = algo == 3 ? "compression.zstd" : algo == 2 ? "bz2" : "zlib"; + PyObject *methodname = PyUnicode_FromString("decompress"); + if (unlikely(!methodname)) return NULL; + #if __PYX_LIMITED_VERSION_HEX >= 0x030e0000 + if (algo == 3) { + PyObject *fromlist = Py_BuildValue("[O]", methodname); + if (unlikely(!fromlist)) return NULL; + module = PyImport_ImportModuleLevel("compression.zstd", NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + } else + #endif + module = PyImport_ImportModule(module_name); + if (unlikely(!module)) goto import_failed; + decompress = PyObject_GetAttr(module, methodname); + if (unlikely(!decompress)) goto import_failed; + { + #ifdef __cplusplus + char *memview_bytes = const_cast(s); + #else + #if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wcast-qual" + #elif !defined(__INTEL_COMPILER) && defined(__GNUC__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-qual" + #endif + char *memview_bytes = (char*) s; + #if defined(__clang__) + #pragma clang diagnostic pop + #elif !defined(__INTEL_COMPILER) && defined(__GNUC__) + #pragma GCC diagnostic pop + #endif + #endif + #if CYTHON_COMPILING_IN_LIMITED_API && !defined(PyBUF_READ) + int memview_flags = 0x100; + #else + int memview_flags = PyBUF_READ; + #endif + compressed_bytes = PyMemoryView_FromMemory(memview_bytes, length, memview_flags); + } + if (unlikely(!compressed_bytes)) { + Py_DECREF(decompress); + goto bad; + } + decompressed = PyObject_CallFunctionObjArgs(decompress, compressed_bytes, NULL); + Py_DECREF(compressed_bytes); + Py_DECREF(decompress); + Py_DECREF(module); + Py_DECREF(methodname); + return decompressed; +import_failed: + PyErr_Format(PyExc_ImportError, + "Failed to import '%.20s.decompress' - cannot initialise module strings. " + "String compression was configured with the C macro 'CYTHON_COMPRESS_STRINGS=%d'.", + module_name, algo); +bad: + Py_XDECREF(module); + Py_DECREF(methodname); + return NULL; +} + +#include +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s) { + size_t len = strlen(s); + if (unlikely(len > (size_t) PY_SSIZE_T_MAX)) { + PyErr_SetString(PyExc_OverflowError, "byte string is too long"); + return -1; + } + return (Py_ssize_t) len; +} +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return __Pyx_PyUnicode_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return PyByteArray_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + { + const char* result; + Py_ssize_t unicode_length; + CYTHON_MAYBE_UNUSED_VAR(unicode_length); // only for __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + #if __PYX_LIMITED_VERSION_HEX < 0x030A0000 + if (unlikely(PyArg_Parse(o, "s#", &result, length) < 0)) return NULL; + #else + result = PyUnicode_AsUTF8AndSize(o, length); + #endif + #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + unicode_length = PyUnicode_GetLength(o); + if (unlikely(unicode_length < 0)) return NULL; + if (unlikely(unicode_length != *length)) { + PyUnicode_AsASCIIString(o); + return NULL; + } + #endif + return result; + } +#else +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +#endif +} +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 + if (PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif + if (PyByteArray_Check(o)) { +#if (CYTHON_ASSUME_SAFE_SIZE && CYTHON_ASSUME_SAFE_MACROS) || (CYTHON_COMPILING_IN_PYPY && (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE))) + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); +#else + *length = PyByteArray_Size(o); + if (*length == -1) return NULL; + return PyByteArray_AsString(o); +#endif + } else + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_LongWrongResultType(PyObject* result) { + __Pyx_TypeName result_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(result)); + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME "). " + "The ability to return an instance of a strict subclass of int is deprecated, " + "and may be removed in a future version of Python.", + result_type_name)) { + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; + } + __Pyx_DECREF_TypeName(result_type_name); + return result; + } + PyErr_Format(PyExc_TypeError, + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME ")", + result_type_name); + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_Long(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + PyObject *res = NULL; + if (likely(PyLong_Check(x))) + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + if (likely(m && m->nb_int)) { + res = m->nb_int(x); + } +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Long(x); + } +#endif + if (likely(res)) { + if (unlikely(!PyLong_CheckExact(res))) { + return __Pyx_PyNumber_LongWrongResultType(res); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(__Pyx_PyLong_IsCompact(b))) { + return __Pyx_PyLong_CompactValue(b); + } else { + const digit* digits = __Pyx_PyLong_Digits(b); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(b); + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyLong_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) { + if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) { + return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o); + } else { + Py_ssize_t ival; + PyObject *x; + x = PyNumber_Index(o); + if (!x) return -1; + ival = PyLong_AsLong(x); + Py_DECREF(x); + return ival; + } +} +static CYTHON_INLINE PyObject *__Pyx_Owned_Py_None(int b) { + CYTHON_UNUSED_VAR(b); + return __Pyx_NewRef(Py_None); +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return __Pyx_NewRef(b ? Py_True: Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyLong_FromSize_t(size_t ival) { + return PyLong_FromSize_t(ival); +} + + +/* MultiPhaseInitModuleState */ +#if CYTHON_PEP489_MULTI_PHASE_INIT && CYTHON_USE_MODULE_STATE +#ifndef CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +#if (CYTHON_COMPILING_IN_LIMITED_API || PY_VERSION_HEX >= 0x030C0000) + #define CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE 1 +#else + #define CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE 0 +#endif +#endif +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE && !CYTHON_ATOMICS +#error "Module state with PEP489 requires atomics. Currently that's one of\ + C11, C++11, gcc atomic intrinsics or MSVC atomic intrinsics" +#endif +#if !CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +#define __Pyx_ModuleStateLookup_Lock() +#define __Pyx_ModuleStateLookup_Unlock() +#elif !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d0000 +static PyMutex __Pyx_ModuleStateLookup_mutex = {0}; +#define __Pyx_ModuleStateLookup_Lock() PyMutex_Lock(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() PyMutex_Unlock(&__Pyx_ModuleStateLookup_mutex) +#elif defined(__cplusplus) && __cplusplus >= 201103L +#include +static std::mutex __Pyx_ModuleStateLookup_mutex; +#define __Pyx_ModuleStateLookup_Lock() __Pyx_ModuleStateLookup_mutex.lock() +#define __Pyx_ModuleStateLookup_Unlock() __Pyx_ModuleStateLookup_mutex.unlock() +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201112L) && !defined(__STDC_NO_THREADS__) +#include +static mtx_t __Pyx_ModuleStateLookup_mutex; +static once_flag __Pyx_ModuleStateLookup_mutex_once_flag = ONCE_FLAG_INIT; +static void __Pyx_ModuleStateLookup_initialize_mutex(void) { + mtx_init(&__Pyx_ModuleStateLookup_mutex, mtx_plain); +} +#define __Pyx_ModuleStateLookup_Lock()\ + call_once(&__Pyx_ModuleStateLookup_mutex_once_flag, __Pyx_ModuleStateLookup_initialize_mutex);\ + mtx_lock(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() mtx_unlock(&__Pyx_ModuleStateLookup_mutex) +#elif defined(HAVE_PTHREAD_H) +#include +static pthread_mutex_t __Pyx_ModuleStateLookup_mutex = PTHREAD_MUTEX_INITIALIZER; +#define __Pyx_ModuleStateLookup_Lock() pthread_mutex_lock(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() pthread_mutex_unlock(&__Pyx_ModuleStateLookup_mutex) +#elif defined(_WIN32) +#include // synchapi.h on its own doesn't work +static SRWLOCK __Pyx_ModuleStateLookup_mutex = SRWLOCK_INIT; +#define __Pyx_ModuleStateLookup_Lock() AcquireSRWLockExclusive(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() ReleaseSRWLockExclusive(&__Pyx_ModuleStateLookup_mutex) +#else +#error "No suitable lock available for CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE.\ + Requires C standard >= C11, or C++ standard >= C++11,\ + or pthreads, or the Windows 32 API, or Python >= 3.13." +#endif +typedef struct { + int64_t id; + PyObject *module; +} __Pyx_InterpreterIdAndModule; +typedef struct { + char interpreter_id_as_index; + Py_ssize_t count; + Py_ssize_t allocated; + __Pyx_InterpreterIdAndModule table[1]; +} __Pyx_ModuleStateLookupData; +#define __PYX_MODULE_STATE_LOOKUP_SMALL_SIZE 32 +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +static __pyx_atomic_int_type __Pyx_ModuleStateLookup_read_counter = 0; +#endif +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +static __pyx_atomic_ptr_type __Pyx_ModuleStateLookup_data = 0; +#else +static __Pyx_ModuleStateLookupData* __Pyx_ModuleStateLookup_data = NULL; +#endif +static __Pyx_InterpreterIdAndModule* __Pyx_State_FindModuleStateLookupTableLowerBound( + __Pyx_InterpreterIdAndModule* table, + Py_ssize_t count, + int64_t interpreterId) { + __Pyx_InterpreterIdAndModule* begin = table; + __Pyx_InterpreterIdAndModule* end = begin + count; + if (begin->id == interpreterId) { + return begin; + } + while ((end - begin) > __PYX_MODULE_STATE_LOOKUP_SMALL_SIZE) { + __Pyx_InterpreterIdAndModule* halfway = begin + (end - begin)/2; + if (halfway->id == interpreterId) { + return halfway; + } + if (halfway->id < interpreterId) { + begin = halfway; + } else { + end = halfway; + } + } + for (; begin < end; ++begin) { + if (begin->id >= interpreterId) return begin; + } + return begin; +} +static PyObject *__Pyx_State_FindModule(CYTHON_UNUSED void* dummy) { + int64_t interpreter_id = PyInterpreterState_GetID(__Pyx_PyInterpreterState_Get()); + if (interpreter_id == -1) return NULL; +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __Pyx_ModuleStateLookupData* data = (__Pyx_ModuleStateLookupData*)__pyx_atomic_pointer_load_relaxed(&__Pyx_ModuleStateLookup_data); + { + __pyx_atomic_incr_acq_rel(&__Pyx_ModuleStateLookup_read_counter); + if (likely(data)) { + __Pyx_ModuleStateLookupData* new_data = (__Pyx_ModuleStateLookupData*)__pyx_atomic_pointer_load_acquire(&__Pyx_ModuleStateLookup_data); + if (likely(data == new_data)) { + goto read_finished; + } + } + __pyx_atomic_decr_acq_rel(&__Pyx_ModuleStateLookup_read_counter); + __Pyx_ModuleStateLookup_Lock(); + __pyx_atomic_incr_relaxed(&__Pyx_ModuleStateLookup_read_counter); + data = (__Pyx_ModuleStateLookupData*)__pyx_atomic_pointer_load_relaxed(&__Pyx_ModuleStateLookup_data); + __Pyx_ModuleStateLookup_Unlock(); + } + read_finished:; +#else + __Pyx_ModuleStateLookupData* data = __Pyx_ModuleStateLookup_data; +#endif + __Pyx_InterpreterIdAndModule* found = NULL; + if (unlikely(!data)) goto end; + if (data->interpreter_id_as_index) { + if (interpreter_id < data->count) { + found = data->table+interpreter_id; + } + } else { + found = __Pyx_State_FindModuleStateLookupTableLowerBound( + data->table, data->count, interpreter_id); + } + end: + { + PyObject *result=NULL; + if (found && found->id == interpreter_id) { + result = found->module; + } +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __pyx_atomic_decr_acq_rel(&__Pyx_ModuleStateLookup_read_counter); +#endif + return result; + } +} +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +static void __Pyx_ModuleStateLookup_wait_until_no_readers(void) { + while (__pyx_atomic_load(&__Pyx_ModuleStateLookup_read_counter) != 0); +} +#else +#define __Pyx_ModuleStateLookup_wait_until_no_readers() +#endif +static int __Pyx_State_AddModuleInterpIdAsIndex(__Pyx_ModuleStateLookupData **old_data, PyObject* module, int64_t interpreter_id) { + Py_ssize_t to_allocate = (*old_data)->allocated; + while (to_allocate <= interpreter_id) { + if (to_allocate == 0) to_allocate = 1; + else to_allocate *= 2; + } + __Pyx_ModuleStateLookupData *new_data = *old_data; + if (to_allocate != (*old_data)->allocated) { + new_data = (__Pyx_ModuleStateLookupData *)realloc( + *old_data, + sizeof(__Pyx_ModuleStateLookupData)+(to_allocate-1)*sizeof(__Pyx_InterpreterIdAndModule)); + if (!new_data) { + PyErr_NoMemory(); + return -1; + } + for (Py_ssize_t i = new_data->allocated; i < to_allocate; ++i) { + new_data->table[i].id = i; + new_data->table[i].module = NULL; + } + new_data->allocated = to_allocate; + } + new_data->table[interpreter_id].module = module; + if (new_data->count < interpreter_id+1) { + new_data->count = interpreter_id+1; + } + *old_data = new_data; + return 0; +} +static void __Pyx_State_ConvertFromInterpIdAsIndex(__Pyx_ModuleStateLookupData *data) { + __Pyx_InterpreterIdAndModule *read = data->table; + __Pyx_InterpreterIdAndModule *write = data->table; + __Pyx_InterpreterIdAndModule *end = read + data->count; + for (; readmodule) { + write->id = read->id; + write->module = read->module; + ++write; + } + } + data->count = write - data->table; + for (; writeid = 0; + write->module = NULL; + } + data->interpreter_id_as_index = 0; +} +static int __Pyx_State_AddModule(PyObject* module, CYTHON_UNUSED void* dummy) { + int64_t interpreter_id = PyInterpreterState_GetID(__Pyx_PyInterpreterState_Get()); + if (interpreter_id == -1) return -1; + int result = 0; + __Pyx_ModuleStateLookup_Lock(); +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __Pyx_ModuleStateLookupData *old_data = (__Pyx_ModuleStateLookupData *) + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, 0); +#else + __Pyx_ModuleStateLookupData *old_data = __Pyx_ModuleStateLookup_data; +#endif + __Pyx_ModuleStateLookupData *new_data = old_data; + if (!new_data) { + new_data = (__Pyx_ModuleStateLookupData *)calloc(1, sizeof(__Pyx_ModuleStateLookupData)); + if (!new_data) { + result = -1; + PyErr_NoMemory(); + goto end; + } + new_data->allocated = 1; + new_data->interpreter_id_as_index = 1; + } + __Pyx_ModuleStateLookup_wait_until_no_readers(); + if (new_data->interpreter_id_as_index) { + if (interpreter_id < __PYX_MODULE_STATE_LOOKUP_SMALL_SIZE) { + result = __Pyx_State_AddModuleInterpIdAsIndex(&new_data, module, interpreter_id); + goto end; + } + __Pyx_State_ConvertFromInterpIdAsIndex(new_data); + } + { + Py_ssize_t insert_at = 0; + { + __Pyx_InterpreterIdAndModule* lower_bound = __Pyx_State_FindModuleStateLookupTableLowerBound( + new_data->table, new_data->count, interpreter_id); + assert(lower_bound); + insert_at = lower_bound - new_data->table; + if (unlikely(insert_at < new_data->count && lower_bound->id == interpreter_id)) { + lower_bound->module = module; + goto end; // already in table, nothing more to do + } + } + if (new_data->count+1 >= new_data->allocated) { + Py_ssize_t to_allocate = (new_data->count+1)*2; + new_data = + (__Pyx_ModuleStateLookupData*)realloc( + new_data, + sizeof(__Pyx_ModuleStateLookupData) + + (to_allocate-1)*sizeof(__Pyx_InterpreterIdAndModule)); + if (!new_data) { + result = -1; + new_data = old_data; + PyErr_NoMemory(); + goto end; + } + new_data->allocated = to_allocate; + } + ++new_data->count; + int64_t last_id = interpreter_id; + PyObject *last_module = module; + for (Py_ssize_t i=insert_at; icount; ++i) { + int64_t current_id = new_data->table[i].id; + new_data->table[i].id = last_id; + last_id = current_id; + PyObject *current_module = new_data->table[i].module; + new_data->table[i].module = last_module; + last_module = current_module; + } + } + end: +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, new_data); +#else + __Pyx_ModuleStateLookup_data = new_data; +#endif + __Pyx_ModuleStateLookup_Unlock(); + return result; +} +static int __Pyx_State_RemoveModule(CYTHON_UNUSED void* dummy) { + int64_t interpreter_id = PyInterpreterState_GetID(__Pyx_PyInterpreterState_Get()); + if (interpreter_id == -1) return -1; + __Pyx_ModuleStateLookup_Lock(); +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __Pyx_ModuleStateLookupData *data = (__Pyx_ModuleStateLookupData *) + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, 0); +#else + __Pyx_ModuleStateLookupData *data = __Pyx_ModuleStateLookup_data; +#endif + if (data->interpreter_id_as_index) { + if (interpreter_id < data->count) { + data->table[interpreter_id].module = NULL; + } + goto done; + } + { + __Pyx_ModuleStateLookup_wait_until_no_readers(); + __Pyx_InterpreterIdAndModule* lower_bound = __Pyx_State_FindModuleStateLookupTableLowerBound( + data->table, data->count, interpreter_id); + if (!lower_bound) goto done; + if (lower_bound->id != interpreter_id) goto done; + __Pyx_InterpreterIdAndModule *end = data->table+data->count; + for (;lower_boundid = (lower_bound+1)->id; + lower_bound->module = (lower_bound+1)->module; + } + } + --data->count; + if (data->count == 0) { + free(data); + data = NULL; + } + done: +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, data); +#else + __Pyx_ModuleStateLookup_data = data; +#endif + __Pyx_ModuleStateLookup_Unlock(); + return 0; +} +#endif + +/* #### Code section: utility_code_pragmas_end ### */ +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + + + +/* #### Code section: end ### */ +#endif /* Py_PYTHON_H */ diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/momentsPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/momentsPen.py new file mode 100644 index 0000000000000000000000000000000000000000..77ead9fc31ca8830807b6dd2dde97bd462987819 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/momentsPen.py @@ -0,0 +1,879 @@ +from fontTools.pens.basePen import BasePen, OpenContourError + +try: + import cython +except (AttributeError, ImportError): + # if cython not installed, use mock module with no-op decorators and types + from fontTools.misc import cython +COMPILED = cython.compiled + + +__all__ = ["MomentsPen"] + + +class MomentsPen(BasePen): + + def __init__(self, glyphset=None): + BasePen.__init__(self, glyphset) + + self.area = 0 + self.momentX = 0 + self.momentY = 0 + self.momentXX = 0 + self.momentXY = 0 + self.momentYY = 0 + + def _moveTo(self, p0): + self._startPoint = p0 + + def _closePath(self): + p0 = self._getCurrentPoint() + if p0 != self._startPoint: + self._lineTo(self._startPoint) + + def _endPath(self): + p0 = self._getCurrentPoint() + if p0 != self._startPoint: + raise OpenContourError("Glyph statistics is not defined on open contours.") + + @cython.locals(r0=cython.double) + @cython.locals(r1=cython.double) + @cython.locals(r2=cython.double) + @cython.locals(r3=cython.double) + @cython.locals(r4=cython.double) + @cython.locals(r5=cython.double) + @cython.locals(r6=cython.double) + @cython.locals(r7=cython.double) + @cython.locals(r8=cython.double) + @cython.locals(r9=cython.double) + @cython.locals(r10=cython.double) + @cython.locals(r11=cython.double) + @cython.locals(r12=cython.double) + @cython.locals(x0=cython.double, y0=cython.double) + @cython.locals(x1=cython.double, y1=cython.double) + def _lineTo(self, p1): + x0, y0 = self._getCurrentPoint() + x1, y1 = p1 + + r0 = x1 * y0 + r1 = x1 * y1 + r2 = x1**2 + r3 = r2 * y1 + r4 = y0 - y1 + r5 = r4 * x0 + r6 = x0**2 + r7 = 2 * y0 + r8 = y0**2 + r9 = y1**2 + r10 = x1**3 + r11 = y0**3 + r12 = y1**3 + + self.area += -r0 / 2 - r1 / 2 + x0 * (y0 + y1) / 2 + self.momentX += -r2 * y0 / 6 - r3 / 3 - r5 * x1 / 6 + r6 * (r7 + y1) / 6 + self.momentY += ( + -r0 * y1 / 6 - r8 * x1 / 6 - r9 * x1 / 6 + x0 * (r8 + r9 + y0 * y1) / 6 + ) + self.momentXX += ( + -r10 * y0 / 12 + - r10 * y1 / 4 + - r2 * r5 / 12 + - r4 * r6 * x1 / 12 + + x0**3 * (3 * y0 + y1) / 12 + ) + self.momentXY += ( + -r2 * r8 / 24 + - r2 * r9 / 8 + - r3 * r7 / 24 + + r6 * (r7 * y1 + 3 * r8 + r9) / 24 + - x0 * x1 * (r8 - r9) / 12 + ) + self.momentYY += ( + -r0 * r9 / 12 + - r1 * r8 / 12 + - r11 * x1 / 12 + - r12 * x1 / 12 + + x0 * (r11 + r12 + r8 * y1 + r9 * y0) / 12 + ) + + @cython.locals(r0=cython.double) + @cython.locals(r1=cython.double) + @cython.locals(r2=cython.double) + @cython.locals(r3=cython.double) + @cython.locals(r4=cython.double) + @cython.locals(r5=cython.double) + @cython.locals(r6=cython.double) + @cython.locals(r7=cython.double) + @cython.locals(r8=cython.double) + @cython.locals(r9=cython.double) + @cython.locals(r10=cython.double) + @cython.locals(r11=cython.double) + @cython.locals(r12=cython.double) + @cython.locals(r13=cython.double) + @cython.locals(r14=cython.double) + @cython.locals(r15=cython.double) + @cython.locals(r16=cython.double) + @cython.locals(r17=cython.double) + @cython.locals(r18=cython.double) + @cython.locals(r19=cython.double) + @cython.locals(r20=cython.double) + @cython.locals(r21=cython.double) + @cython.locals(r22=cython.double) + @cython.locals(r23=cython.double) + @cython.locals(r24=cython.double) + @cython.locals(r25=cython.double) + @cython.locals(r26=cython.double) + @cython.locals(r27=cython.double) + @cython.locals(r28=cython.double) + @cython.locals(r29=cython.double) + @cython.locals(r30=cython.double) + @cython.locals(r31=cython.double) + @cython.locals(r32=cython.double) + @cython.locals(r33=cython.double) + @cython.locals(r34=cython.double) + @cython.locals(r35=cython.double) + @cython.locals(r36=cython.double) + @cython.locals(r37=cython.double) + @cython.locals(r38=cython.double) + @cython.locals(r39=cython.double) + @cython.locals(r40=cython.double) + @cython.locals(r41=cython.double) + @cython.locals(r42=cython.double) + @cython.locals(r43=cython.double) + @cython.locals(r44=cython.double) + @cython.locals(r45=cython.double) + @cython.locals(r46=cython.double) + @cython.locals(r47=cython.double) + @cython.locals(r48=cython.double) + @cython.locals(r49=cython.double) + @cython.locals(r50=cython.double) + @cython.locals(r51=cython.double) + @cython.locals(r52=cython.double) + @cython.locals(r53=cython.double) + @cython.locals(x0=cython.double, y0=cython.double) + @cython.locals(x1=cython.double, y1=cython.double) + @cython.locals(x2=cython.double, y2=cython.double) + def _qCurveToOne(self, p1, p2): + x0, y0 = self._getCurrentPoint() + x1, y1 = p1 + x2, y2 = p2 + + r0 = 2 * y1 + r1 = r0 * x2 + r2 = x2 * y2 + r3 = 3 * r2 + r4 = 2 * x1 + r5 = 3 * y0 + r6 = x1**2 + r7 = x2**2 + r8 = 4 * y1 + r9 = 10 * y2 + r10 = 2 * y2 + r11 = r4 * x2 + r12 = x0**2 + r13 = 10 * y0 + r14 = r4 * y2 + r15 = x2 * y0 + r16 = 4 * x1 + r17 = r0 * x1 + r2 + r18 = r2 * r8 + r19 = y1**2 + r20 = 2 * r19 + r21 = y2**2 + r22 = r21 * x2 + r23 = 5 * r22 + r24 = y0**2 + r25 = y0 * y2 + r26 = 5 * r24 + r27 = x1**3 + r28 = x2**3 + r29 = 30 * y1 + r30 = 6 * y1 + r31 = 10 * r7 * x1 + r32 = 5 * y2 + r33 = 12 * r6 + r34 = 30 * x1 + r35 = x1 * y1 + r36 = r3 + 20 * r35 + r37 = 12 * x1 + r38 = 20 * r6 + r39 = 8 * r6 * y1 + r40 = r32 * r7 + r41 = 60 * y1 + r42 = 20 * r19 + r43 = 4 * r19 + r44 = 15 * r21 + r45 = 12 * x2 + r46 = 12 * y2 + r47 = 6 * x1 + r48 = 8 * r19 * x1 + r23 + r49 = 8 * y1**3 + r50 = y2**3 + r51 = y0**3 + r52 = 10 * y1 + r53 = 12 * y1 + + self.area += ( + -r1 / 6 + - r3 / 6 + + x0 * (r0 + r5 + y2) / 6 + + x1 * y2 / 3 + - y0 * (r4 + x2) / 6 + ) + self.momentX += ( + -r11 * (-r10 + y1) / 30 + + r12 * (r13 + r8 + y2) / 30 + + r6 * y2 / 15 + - r7 * r8 / 30 + - r7 * r9 / 30 + + x0 * (r14 - r15 - r16 * y0 + r17) / 30 + - y0 * (r11 + 2 * r6 + r7) / 30 + ) + self.momentY += ( + -r18 / 30 + - r20 * x2 / 30 + - r23 / 30 + - r24 * (r16 + x2) / 30 + + x0 * (r0 * y2 + r20 + r21 + r25 + r26 + r8 * y0) / 30 + + x1 * y2 * (r10 + y1) / 15 + - y0 * (r1 + r17) / 30 + ) + self.momentXX += ( + r12 * (r1 - 5 * r15 - r34 * y0 + r36 + r9 * x1) / 420 + + 2 * r27 * y2 / 105 + - r28 * r29 / 420 + - r28 * y2 / 4 + - r31 * (r0 - 3 * y2) / 420 + - r6 * x2 * (r0 - r32) / 105 + + x0**3 * (r30 + 21 * y0 + y2) / 84 + - x0 + * ( + r0 * r7 + + r15 * r37 + - r2 * r37 + - r33 * y2 + + r38 * y0 + - r39 + - r40 + + r5 * r7 + ) + / 420 + - y0 * (8 * r27 + 5 * r28 + r31 + r33 * x2) / 420 + ) + self.momentXY += ( + r12 * (r13 * y2 + 3 * r21 + 105 * r24 + r41 * y0 + r42 + r46 * y1) / 840 + - r16 * x2 * (r43 - r44) / 840 + - r21 * r7 / 8 + - r24 * (r38 + r45 * x1 + 3 * r7) / 840 + - r41 * r7 * y2 / 840 + - r42 * r7 / 840 + + r6 * y2 * (r32 + r8) / 210 + + x0 + * ( + -r15 * r8 + + r16 * r25 + + r18 + + r21 * r47 + - r24 * r34 + - r26 * x2 + + r35 * r46 + + r48 + ) + / 420 + - y0 * (r16 * r2 + r30 * r7 + r35 * r45 + r39 + r40) / 420 + ) + self.momentYY += ( + -r2 * r42 / 420 + - r22 * r29 / 420 + - r24 * (r14 + r36 + r52 * x2) / 420 + - r49 * x2 / 420 + - r50 * x2 / 12 + - r51 * (r47 + x2) / 84 + + x0 + * ( + r19 * r46 + + r21 * r5 + + r21 * r52 + + r24 * r29 + + r25 * r53 + + r26 * y2 + + r42 * y0 + + r49 + + 5 * r50 + + 35 * r51 + ) + / 420 + + x1 * y2 * (r43 + r44 + r9 * y1) / 210 + - y0 * (r19 * r45 + r2 * r53 - r21 * r4 + r48) / 420 + ) + + @cython.locals(r0=cython.double) + @cython.locals(r1=cython.double) + @cython.locals(r2=cython.double) + @cython.locals(r3=cython.double) + @cython.locals(r4=cython.double) + @cython.locals(r5=cython.double) + @cython.locals(r6=cython.double) + @cython.locals(r7=cython.double) + @cython.locals(r8=cython.double) + @cython.locals(r9=cython.double) + @cython.locals(r10=cython.double) + @cython.locals(r11=cython.double) + @cython.locals(r12=cython.double) + @cython.locals(r13=cython.double) + @cython.locals(r14=cython.double) + @cython.locals(r15=cython.double) + @cython.locals(r16=cython.double) + @cython.locals(r17=cython.double) + @cython.locals(r18=cython.double) + @cython.locals(r19=cython.double) + @cython.locals(r20=cython.double) + @cython.locals(r21=cython.double) + @cython.locals(r22=cython.double) + @cython.locals(r23=cython.double) + @cython.locals(r24=cython.double) + @cython.locals(r25=cython.double) + @cython.locals(r26=cython.double) + @cython.locals(r27=cython.double) + @cython.locals(r28=cython.double) + @cython.locals(r29=cython.double) + @cython.locals(r30=cython.double) + @cython.locals(r31=cython.double) + @cython.locals(r32=cython.double) + @cython.locals(r33=cython.double) + @cython.locals(r34=cython.double) + @cython.locals(r35=cython.double) + @cython.locals(r36=cython.double) + @cython.locals(r37=cython.double) + @cython.locals(r38=cython.double) + @cython.locals(r39=cython.double) + @cython.locals(r40=cython.double) + @cython.locals(r41=cython.double) + @cython.locals(r42=cython.double) + @cython.locals(r43=cython.double) + @cython.locals(r44=cython.double) + @cython.locals(r45=cython.double) + @cython.locals(r46=cython.double) + @cython.locals(r47=cython.double) + @cython.locals(r48=cython.double) + @cython.locals(r49=cython.double) + @cython.locals(r50=cython.double) + @cython.locals(r51=cython.double) + @cython.locals(r52=cython.double) + @cython.locals(r53=cython.double) + @cython.locals(r54=cython.double) + @cython.locals(r55=cython.double) + @cython.locals(r56=cython.double) + @cython.locals(r57=cython.double) + @cython.locals(r58=cython.double) + @cython.locals(r59=cython.double) + @cython.locals(r60=cython.double) + @cython.locals(r61=cython.double) + @cython.locals(r62=cython.double) + @cython.locals(r63=cython.double) + @cython.locals(r64=cython.double) + @cython.locals(r65=cython.double) + @cython.locals(r66=cython.double) + @cython.locals(r67=cython.double) + @cython.locals(r68=cython.double) + @cython.locals(r69=cython.double) + @cython.locals(r70=cython.double) + @cython.locals(r71=cython.double) + @cython.locals(r72=cython.double) + @cython.locals(r73=cython.double) + @cython.locals(r74=cython.double) + @cython.locals(r75=cython.double) + @cython.locals(r76=cython.double) + @cython.locals(r77=cython.double) + @cython.locals(r78=cython.double) + @cython.locals(r79=cython.double) + @cython.locals(r80=cython.double) + @cython.locals(r81=cython.double) + @cython.locals(r82=cython.double) + @cython.locals(r83=cython.double) + @cython.locals(r84=cython.double) + @cython.locals(r85=cython.double) + @cython.locals(r86=cython.double) + @cython.locals(r87=cython.double) + @cython.locals(r88=cython.double) + @cython.locals(r89=cython.double) + @cython.locals(r90=cython.double) + @cython.locals(r91=cython.double) + @cython.locals(r92=cython.double) + @cython.locals(r93=cython.double) + @cython.locals(r94=cython.double) + @cython.locals(r95=cython.double) + @cython.locals(r96=cython.double) + @cython.locals(r97=cython.double) + @cython.locals(r98=cython.double) + @cython.locals(r99=cython.double) + @cython.locals(r100=cython.double) + @cython.locals(r101=cython.double) + @cython.locals(r102=cython.double) + @cython.locals(r103=cython.double) + @cython.locals(r104=cython.double) + @cython.locals(r105=cython.double) + @cython.locals(r106=cython.double) + @cython.locals(r107=cython.double) + @cython.locals(r108=cython.double) + @cython.locals(r109=cython.double) + @cython.locals(r110=cython.double) + @cython.locals(r111=cython.double) + @cython.locals(r112=cython.double) + @cython.locals(r113=cython.double) + @cython.locals(r114=cython.double) + @cython.locals(r115=cython.double) + @cython.locals(r116=cython.double) + @cython.locals(r117=cython.double) + @cython.locals(r118=cython.double) + @cython.locals(r119=cython.double) + @cython.locals(r120=cython.double) + @cython.locals(r121=cython.double) + @cython.locals(r122=cython.double) + @cython.locals(r123=cython.double) + @cython.locals(r124=cython.double) + @cython.locals(r125=cython.double) + @cython.locals(r126=cython.double) + @cython.locals(r127=cython.double) + @cython.locals(r128=cython.double) + @cython.locals(r129=cython.double) + @cython.locals(r130=cython.double) + @cython.locals(r131=cython.double) + @cython.locals(r132=cython.double) + @cython.locals(x0=cython.double, y0=cython.double) + @cython.locals(x1=cython.double, y1=cython.double) + @cython.locals(x2=cython.double, y2=cython.double) + @cython.locals(x3=cython.double, y3=cython.double) + def _curveToOne(self, p1, p2, p3): + x0, y0 = self._getCurrentPoint() + x1, y1 = p1 + x2, y2 = p2 + x3, y3 = p3 + + r0 = 6 * y2 + r1 = r0 * x3 + r2 = 10 * y3 + r3 = r2 * x3 + r4 = 3 * y1 + r5 = 6 * x1 + r6 = 3 * x2 + r7 = 6 * y1 + r8 = 3 * y2 + r9 = x2**2 + r10 = 45 * r9 + r11 = r10 * y3 + r12 = x3**2 + r13 = r12 * y2 + r14 = r12 * y3 + r15 = 7 * y3 + r16 = 15 * x3 + r17 = r16 * x2 + r18 = x1**2 + r19 = 9 * r18 + r20 = x0**2 + r21 = 21 * y1 + r22 = 9 * r9 + r23 = r7 * x3 + r24 = 9 * y2 + r25 = r24 * x2 + r3 + r26 = 9 * x2 + r27 = x2 * y3 + r28 = -r26 * y1 + 15 * r27 + r29 = 3 * x1 + r30 = 45 * x1 + r31 = 12 * x3 + r32 = 45 * r18 + r33 = 5 * r12 + r34 = r8 * x3 + r35 = 105 * y0 + r36 = 30 * y0 + r37 = r36 * x2 + r38 = 5 * x3 + r39 = 15 * y3 + r40 = 5 * y3 + r41 = r40 * x3 + r42 = x2 * y2 + r43 = 18 * r42 + r44 = 45 * y1 + r45 = r41 + r43 + r44 * x1 + r46 = y2 * y3 + r47 = r46 * x3 + r48 = y2**2 + r49 = 45 * r48 + r50 = r49 * x3 + r51 = y3**2 + r52 = r51 * x3 + r53 = y1**2 + r54 = 9 * r53 + r55 = y0**2 + r56 = 21 * x1 + r57 = 6 * x2 + r58 = r16 * y2 + r59 = r39 * y2 + r60 = 9 * r48 + r61 = r6 * y3 + r62 = 3 * y3 + r63 = r36 * y2 + r64 = y1 * y3 + r65 = 45 * r53 + r66 = 5 * r51 + r67 = x2**3 + r68 = x3**3 + r69 = 630 * y2 + r70 = 126 * x3 + r71 = x1**3 + r72 = 126 * x2 + r73 = 63 * r9 + r74 = r73 * x3 + r75 = r15 * x3 + 15 * r42 + r76 = 630 * x1 + r77 = 14 * x3 + r78 = 21 * r27 + r79 = 42 * x1 + r80 = 42 * x2 + r81 = x1 * y2 + r82 = 63 * r42 + r83 = x1 * y1 + r84 = r41 + r82 + 378 * r83 + r85 = x2 * x3 + r86 = r85 * y1 + r87 = r27 * x3 + r88 = 27 * r9 + r89 = r88 * y2 + r90 = 42 * r14 + r91 = 90 * x1 + r92 = 189 * r18 + r93 = 378 * r18 + r94 = r12 * y1 + r95 = 252 * x1 * x2 + r96 = r79 * x3 + r97 = 30 * r85 + r98 = r83 * x3 + r99 = 30 * x3 + r100 = 42 * x3 + r101 = r42 * x1 + r102 = r10 * y2 + 14 * r14 + 126 * r18 * y1 + r81 * r99 + r103 = 378 * r48 + r104 = 18 * y1 + r105 = r104 * y2 + r106 = y0 * y1 + r107 = 252 * y2 + r108 = r107 * y0 + r109 = y0 * y3 + r110 = 42 * r64 + r111 = 378 * r53 + r112 = 63 * r48 + r113 = 27 * x2 + r114 = r27 * y2 + r115 = r113 * r48 + 42 * r52 + r116 = x3 * y3 + r117 = 54 * r42 + r118 = r51 * x1 + r119 = r51 * x2 + r120 = r48 * x1 + r121 = 21 * x3 + r122 = r64 * x1 + r123 = r81 * y3 + r124 = 30 * r27 * y1 + r49 * x2 + 14 * r52 + 126 * r53 * x1 + r125 = y2**3 + r126 = y3**3 + r127 = y1**3 + r128 = y0**3 + r129 = r51 * y2 + r130 = r112 * y3 + r21 * r51 + r131 = 189 * r53 + r132 = 90 * y2 + + self.area += ( + -r1 / 20 + - r3 / 20 + - r4 * (x2 + x3) / 20 + + x0 * (r7 + r8 + 10 * y0 + y3) / 20 + + 3 * x1 * (y2 + y3) / 20 + + 3 * x2 * y3 / 10 + - y0 * (r5 + r6 + x3) / 20 + ) + self.momentX += ( + r11 / 840 + - r13 / 8 + - r14 / 3 + - r17 * (-r15 + r8) / 840 + + r19 * (r8 + 2 * y3) / 840 + + r20 * (r0 + r21 + 56 * y0 + y3) / 168 + + r29 * (-r23 + r25 + r28) / 840 + - r4 * (10 * r12 + r17 + r22) / 840 + + x0 + * ( + 12 * r27 + + r30 * y2 + + r34 + - r35 * x1 + - r37 + - r38 * y0 + + r39 * x1 + - r4 * x3 + + r45 + ) + / 840 + - y0 * (r17 + r30 * x2 + r31 * x1 + r32 + r33 + 18 * r9) / 840 + ) + self.momentY += ( + -r4 * (r25 + r58) / 840 + - r47 / 8 + - r50 / 840 + - r52 / 6 + - r54 * (r6 + 2 * x3) / 840 + - r55 * (r56 + r57 + x3) / 168 + + x0 + * ( + r35 * y1 + + r40 * y0 + + r44 * y2 + + 18 * r48 + + 140 * r55 + + r59 + + r63 + + 12 * r64 + + r65 + + r66 + ) + / 840 + + x1 * (r24 * y1 + 10 * r51 + r59 + r60 + r7 * y3) / 280 + + x2 * y3 * (r15 + r8) / 56 + - y0 * (r16 * y1 + r31 * y2 + r44 * x2 + r45 + r61 - r62 * x1) / 840 + ) + self.momentXX += ( + -r12 * r72 * (-r40 + r8) / 9240 + + 3 * r18 * (r28 + r34 - r38 * y1 + r75) / 3080 + + r20 + * ( + r24 * x3 + - r72 * y0 + - r76 * y0 + - r77 * y0 + + r78 + + r79 * y3 + + r80 * y1 + + 210 * r81 + + r84 + ) + / 9240 + - r29 + * ( + r12 * r21 + + 14 * r13 + + r44 * r9 + - r73 * y3 + + 54 * r86 + - 84 * r87 + - r89 + - r90 + ) + / 9240 + - r4 * (70 * r12 * x2 + 27 * r67 + 42 * r68 + r74) / 9240 + + 3 * r67 * y3 / 220 + - r68 * r69 / 9240 + - r68 * y3 / 4 + - r70 * r9 * (-r62 + y2) / 9240 + + 3 * r71 * (r24 + r40) / 3080 + + x0**3 * (r24 + r44 + 165 * y0 + y3) / 660 + + x0 + * ( + r100 * r27 + + 162 * r101 + + r102 + + r11 + + 63 * r18 * y3 + + r27 * r91 + - r33 * y0 + - r37 * x3 + + r43 * x3 + - r73 * y0 + - r88 * y1 + + r92 * y2 + - r93 * y0 + - 9 * r94 + - r95 * y0 + - r96 * y0 + - r97 * y1 + - 18 * r98 + + r99 * x1 * y3 + ) + / 9240 + - y0 + * ( + r12 * r56 + + r12 * r80 + + r32 * x3 + + 45 * r67 + + 14 * r68 + + 126 * r71 + + r74 + + r85 * r91 + + 135 * r9 * x1 + + r92 * x2 + ) + / 9240 + ) + self.momentXY += ( + -r103 * r12 / 18480 + - r12 * r51 / 8 + - 3 * r14 * y2 / 44 + + 3 * r18 * (r105 + r2 * y1 + 18 * r46 + 15 * r48 + 7 * r51) / 6160 + + r20 + * ( + 1260 * r106 + + r107 * y1 + + r108 + + 28 * r109 + + r110 + + r111 + + r112 + + 30 * r46 + + 2310 * r55 + + r66 + ) + / 18480 + - r54 * (7 * r12 + 18 * r85 + 15 * r9) / 18480 + - r55 * (r33 + r73 + r93 + r95 + r96 + r97) / 18480 + - r7 * (42 * r13 + r82 * x3 + 28 * r87 + r89 + r90) / 18480 + - 3 * r85 * (r48 - r66) / 220 + + 3 * r9 * y3 * (r62 + 2 * y2) / 440 + + x0 + * ( + -r1 * y0 + - 84 * r106 * x2 + + r109 * r56 + + 54 * r114 + + r117 * y1 + + 15 * r118 + + 21 * r119 + + 81 * r120 + + r121 * r46 + + 54 * r122 + + 60 * r123 + + r124 + - r21 * x3 * y0 + + r23 * y3 + - r54 * x3 + - r55 * r72 + - r55 * r76 + - r55 * r77 + + r57 * y0 * y3 + + r60 * x3 + + 84 * r81 * y0 + + 189 * r81 * y1 + ) + / 9240 + + x1 + * ( + r104 * r27 + - r105 * x3 + - r113 * r53 + + 63 * r114 + + r115 + - r16 * r53 + + 28 * r47 + + r51 * r80 + ) + / 3080 + - y0 + * ( + 54 * r101 + + r102 + + r116 * r5 + + r117 * x3 + + 21 * r13 + - r19 * y3 + + r22 * y3 + + r78 * x3 + + 189 * r83 * x2 + + 60 * r86 + + 81 * r9 * y1 + + 15 * r94 + + 54 * r98 + ) + / 9240 + ) + self.momentYY += ( + -r103 * r116 / 9240 + - r125 * r70 / 9240 + - r126 * x3 / 12 + - 3 * r127 * (r26 + r38) / 3080 + - r128 * (r26 + r30 + x3) / 660 + - r4 * (r112 * x3 + r115 - 14 * r119 + 84 * r47) / 9240 + - r52 * r69 / 9240 + - r54 * (r58 + r61 + r75) / 9240 + - r55 + * (r100 * y1 + r121 * y2 + r26 * y3 + r79 * y2 + r84 + 210 * x2 * y1) + / 9240 + + x0 + * ( + r108 * y1 + + r110 * y0 + + r111 * y0 + + r112 * y0 + + 45 * r125 + + 14 * r126 + + 126 * r127 + + 770 * r128 + + 42 * r129 + + r130 + + r131 * y2 + + r132 * r64 + + 135 * r48 * y1 + + 630 * r55 * y1 + + 126 * r55 * y2 + + 14 * r55 * y3 + + r63 * y3 + + r65 * y3 + + r66 * y0 + ) + / 9240 + + x1 + * ( + 27 * r125 + + 42 * r126 + + 70 * r129 + + r130 + + r39 * r53 + + r44 * r48 + + 27 * r53 * y2 + + 54 * r64 * y2 + ) + / 3080 + + 3 * x2 * y3 * (r48 + r66 + r8 * y3) / 220 + - y0 + * ( + r100 * r46 + + 18 * r114 + - 9 * r118 + - 27 * r120 + - 18 * r122 + - 30 * r123 + + r124 + + r131 * x2 + + r132 * x3 * y1 + + 162 * r42 * y1 + + r50 + + 63 * r53 * x3 + + r64 * r99 + ) + / 9240 + ) + + +if __name__ == "__main__": + from fontTools.misc.symfont import x, y, printGreenPen + + printGreenPen( + "MomentsPen", + [ + ("area", 1), + ("momentX", x), + ("momentY", y), + ("momentXX", x**2), + ("momentXY", x * y), + ("momentYY", y**2), + ], + ) diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/perimeterPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/perimeterPen.py new file mode 100644 index 0000000000000000000000000000000000000000..efb2b2d14cc46dc51ff795cf7a1fb95bd6d63673 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/perimeterPen.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +"""Calculate the perimeter of a glyph.""" + +from fontTools.pens.basePen import BasePen +from fontTools.misc.bezierTools import ( + approximateQuadraticArcLengthC, + calcQuadraticArcLengthC, + approximateCubicArcLengthC, + calcCubicArcLengthC, +) +import math + + +__all__ = ["PerimeterPen"] + + +def _distance(p0, p1): + return math.hypot(p0[0] - p1[0], p0[1] - p1[1]) + + +class PerimeterPen(BasePen): + def __init__(self, glyphset=None, tolerance=0.005): + BasePen.__init__(self, glyphset) + self.value = 0 + self.tolerance = tolerance + + # Choose which algorithm to use for quadratic and for cubic. + # Quadrature is faster but has fixed error characteristic with no strong + # error bound. The cutoff points are derived empirically. + self._addCubic = ( + self._addCubicQuadrature if tolerance >= 0.0015 else self._addCubicRecursive + ) + self._addQuadratic = ( + self._addQuadraticQuadrature + if tolerance >= 0.00075 + else self._addQuadraticExact + ) + + def _moveTo(self, p0): + self.__startPoint = p0 + + def _closePath(self): + p0 = self._getCurrentPoint() + if p0 != self.__startPoint: + self._lineTo(self.__startPoint) + + def _lineTo(self, p1): + p0 = self._getCurrentPoint() + self.value += _distance(p0, p1) + + def _addQuadraticExact(self, c0, c1, c2): + self.value += calcQuadraticArcLengthC(c0, c1, c2) + + def _addQuadraticQuadrature(self, c0, c1, c2): + self.value += approximateQuadraticArcLengthC(c0, c1, c2) + + def _qCurveToOne(self, p1, p2): + p0 = self._getCurrentPoint() + self._addQuadratic(complex(*p0), complex(*p1), complex(*p2)) + + def _addCubicRecursive(self, c0, c1, c2, c3): + self.value += calcCubicArcLengthC(c0, c1, c2, c3, self.tolerance) + + def _addCubicQuadrature(self, c0, c1, c2, c3): + self.value += approximateCubicArcLengthC(c0, c1, c2, c3) + + def _curveToOne(self, p1, p2, p3): + p0 = self._getCurrentPoint() + self._addCubic(complex(*p0), complex(*p1), complex(*p2), complex(*p3)) diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/pointInsidePen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/pointInsidePen.py new file mode 100644 index 0000000000000000000000000000000000000000..0c022d31bc2131761bf9cffd55f850a27db820b6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/pointInsidePen.py @@ -0,0 +1,192 @@ +"""fontTools.pens.pointInsidePen -- Pen implementing "point inside" testing +for shapes. +""" + +from fontTools.pens.basePen import BasePen +from fontTools.misc.bezierTools import solveQuadratic, solveCubic + + +__all__ = ["PointInsidePen"] + + +class PointInsidePen(BasePen): + """This pen implements "point inside" testing: to test whether + a given point lies inside the shape (black) or outside (white). + Instances of this class can be recycled, as long as the + setTestPoint() method is used to set the new point to test. + + :Example: + .. code-block:: + + pen = PointInsidePen(glyphSet, (100, 200)) + outline.draw(pen) + isInside = pen.getResult() + + Both the even-odd algorithm and the non-zero-winding-rule + algorithm are implemented. The latter is the default, specify + True for the evenOdd argument of __init__ or setTestPoint + to use the even-odd algorithm. + """ + + # This class implements the classical "shoot a ray from the test point + # to infinity and count how many times it intersects the outline" (as well + # as the non-zero variant, where the counter is incremented if the outline + # intersects the ray in one direction and decremented if it intersects in + # the other direction). + # I found an amazingly clear explanation of the subtleties involved in + # implementing this correctly for polygons here: + # http://graphics.cs.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html + # I extended the principles outlined on that page to curves. + + def __init__(self, glyphSet, testPoint, evenOdd=False): + BasePen.__init__(self, glyphSet) + self.setTestPoint(testPoint, evenOdd) + + def setTestPoint(self, testPoint, evenOdd=False): + """Set the point to test. Call this _before_ the outline gets drawn.""" + self.testPoint = testPoint + self.evenOdd = evenOdd + self.firstPoint = None + self.intersectionCount = 0 + + def getWinding(self): + if self.firstPoint is not None: + # always make sure the sub paths are closed; the algorithm only works + # for closed paths. + self.closePath() + return self.intersectionCount + + def getResult(self): + """After the shape has been drawn, getResult() returns True if the test + point lies within the (black) shape, and False if it doesn't. + """ + winding = self.getWinding() + if self.evenOdd: + result = winding % 2 + else: # non-zero + result = self.intersectionCount != 0 + return not not result + + def _addIntersection(self, goingUp): + if self.evenOdd or goingUp: + self.intersectionCount += 1 + else: + self.intersectionCount -= 1 + + def _moveTo(self, point): + if self.firstPoint is not None: + # always make sure the sub paths are closed; the algorithm only works + # for closed paths. + self.closePath() + self.firstPoint = point + + def _lineTo(self, point): + x, y = self.testPoint + x1, y1 = self._getCurrentPoint() + x2, y2 = point + + if x1 < x and x2 < x: + return + if y1 < y and y2 < y: + return + if y1 >= y and y2 >= y: + return + + dx = x2 - x1 + dy = y2 - y1 + t = (y - y1) / dy + ix = dx * t + x1 + if ix < x: + return + self._addIntersection(y2 > y1) + + def _curveToOne(self, bcp1, bcp2, point): + x, y = self.testPoint + x1, y1 = self._getCurrentPoint() + x2, y2 = bcp1 + x3, y3 = bcp2 + x4, y4 = point + + if x1 < x and x2 < x and x3 < x and x4 < x: + return + if y1 < y and y2 < y and y3 < y and y4 < y: + return + if y1 >= y and y2 >= y and y3 >= y and y4 >= y: + return + + dy = y1 + cy = (y2 - dy) * 3.0 + by = (y3 - y2) * 3.0 - cy + ay = y4 - dy - cy - by + solutions = sorted(solveCubic(ay, by, cy, dy - y)) + solutions = [t for t in solutions if -0.0 <= t <= 1.0] + if not solutions: + return + + dx = x1 + cx = (x2 - dx) * 3.0 + bx = (x3 - x2) * 3.0 - cx + ax = x4 - dx - cx - bx + + above = y1 >= y + lastT = None + for t in solutions: + if t == lastT: + continue + lastT = t + t2 = t * t + t3 = t2 * t + + direction = 3 * ay * t2 + 2 * by * t + cy + incomingGoingUp = outgoingGoingUp = direction > 0.0 + if direction == 0.0: + direction = 6 * ay * t + 2 * by + outgoingGoingUp = direction > 0.0 + incomingGoingUp = not outgoingGoingUp + if direction == 0.0: + direction = ay + incomingGoingUp = outgoingGoingUp = direction > 0.0 + + xt = ax * t3 + bx * t2 + cx * t + dx + if xt < x: + continue + + if t in (0.0, -0.0): + if not outgoingGoingUp: + self._addIntersection(outgoingGoingUp) + elif t == 1.0: + if incomingGoingUp: + self._addIntersection(incomingGoingUp) + else: + if incomingGoingUp == outgoingGoingUp: + self._addIntersection(outgoingGoingUp) + # else: + # we're not really intersecting, merely touching + + def _qCurveToOne_unfinished(self, bcp, point): + # XXX need to finish this, for now doing it through a cubic + # (BasePen implements _qCurveTo in terms of a cubic) will + # have to do. + x, y = self.testPoint + x1, y1 = self._getCurrentPoint() + x2, y2 = bcp + x3, y3 = point + c = y1 + b = (y2 - c) * 2.0 + a = y3 - c - b + solutions = sorted(solveQuadratic(a, b, c - y)) + solutions = [ + t for t in solutions if ZERO_MINUS_EPSILON <= t <= ONE_PLUS_EPSILON + ] + if not solutions: + return + # XXX + + def _closePath(self): + if self._getCurrentPoint() != self.firstPoint: + self.lineTo(self.firstPoint) + self.firstPoint = None + + def _endPath(self): + """Insideness is not defined for open contours.""" + raise NotImplementedError diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/pointPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/pointPen.py new file mode 100644 index 0000000000000000000000000000000000000000..3091b86921b706c97435fabe6c5e8a4ebd4be64f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/pointPen.py @@ -0,0 +1,643 @@ +""" +========= +PointPens +========= + +Where **SegmentPens** have an intuitive approach to drawing +(if you're familiar with postscript anyway), the **PointPen** +is geared towards accessing all the data in the contours of +the glyph. A PointPen has a very simple interface, it just +steps through all the points in a call from glyph.drawPoints(). +This allows the caller to provide more data for each point. +For instance, whether or not a point is smooth, and its name. +""" + +from __future__ import annotations + +import math +from typing import Any, Dict, List, Optional, Tuple + +from fontTools.misc.enumTools import StrEnum +from fontTools.misc.loggingTools import LogMixin +from fontTools.misc.transform import DecomposedTransform, Identity +from fontTools.pens.basePen import AbstractPen, MissingComponentError, PenError + +__all__ = [ + "AbstractPointPen", + "BasePointToSegmentPen", + "PointToSegmentPen", + "SegmentToPointPen", + "GuessSmoothPointPen", + "ReverseContourPointPen", + "ReverseFlipped", +] + +# Some type aliases to make it easier below +Point = Tuple[float, float] +PointName = Optional[str] +# [(pt, smooth, name, kwargs)] +SegmentPointList = List[Tuple[Optional[Point], bool, PointName, Any]] +SegmentType = Optional[str] +SegmentList = List[Tuple[SegmentType, SegmentPointList]] + + +class ReverseFlipped(StrEnum): + """How to handle flipped components during decomposition. + + NO: Don't reverse flipped components + KEEP_START: Reverse flipped components, keeping original starting point + ON_CURVE_FIRST: Reverse flipped components, ensuring first point is on-curve + """ + + NO = "no" + KEEP_START = "keep_start" + ON_CURVE_FIRST = "on_curve_first" + + +class AbstractPointPen: + """Baseclass for all PointPens.""" + + def beginPath(self, identifier: Optional[str] = None, **kwargs: Any) -> None: + """Start a new sub path.""" + raise NotImplementedError + + def endPath(self) -> None: + """End the current sub path.""" + raise NotImplementedError + + def addPoint( + self, + pt: Tuple[float, float], + segmentType: Optional[str] = None, + smooth: bool = False, + name: Optional[str] = None, + identifier: Optional[str] = None, + **kwargs: Any, + ) -> None: + """Add a point to the current sub path.""" + raise NotImplementedError + + def addComponent( + self, + baseGlyphName: str, + transformation: Tuple[float, float, float, float, float, float], + identifier: Optional[str] = None, + **kwargs: Any, + ) -> None: + """Add a sub glyph.""" + raise NotImplementedError + + def addVarComponent( + self, + glyphName: str, + transformation: DecomposedTransform, + location: Dict[str, float], + identifier: Optional[str] = None, + **kwargs: Any, + ) -> None: + """Add a VarComponent sub glyph. The 'transformation' argument + must be a DecomposedTransform from the fontTools.misc.transform module, + and the 'location' argument must be a dictionary mapping axis tags + to their locations. + """ + # ttGlyphSet decomposes for us + raise AttributeError + + +class BasePointToSegmentPen(AbstractPointPen): + """ + Base class for retrieving the outline in a segment-oriented + way. The PointPen protocol is simple yet also a little tricky, + so when you need an outline presented as segments but you have + as points, do use this base implementation as it properly takes + care of all the edge cases. + """ + + def __init__(self) -> None: + self.currentPath = None + + def beginPath(self, identifier=None, **kwargs): + if self.currentPath is not None: + raise PenError("Path already begun.") + self.currentPath = [] + + def _flushContour(self, segments: SegmentList) -> None: + """Override this method. + + It will be called for each non-empty sub path with a list + of segments: the 'segments' argument. + + The segments list contains tuples of length 2: + (segmentType, points) + + segmentType is one of "move", "line", "curve" or "qcurve". + "move" may only occur as the first segment, and it signifies + an OPEN path. A CLOSED path does NOT start with a "move", in + fact it will not contain a "move" at ALL. + + The 'points' field in the 2-tuple is a list of point info + tuples. The list has 1 or more items, a point tuple has + four items: + (point, smooth, name, kwargs) + 'point' is an (x, y) coordinate pair. + + For a closed path, the initial moveTo point is defined as + the last point of the last segment. + + The 'points' list of "move" and "line" segments always contains + exactly one point tuple. + """ + raise NotImplementedError + + def endPath(self) -> None: + if self.currentPath is None: + raise PenError("Path not begun.") + points = self.currentPath + self.currentPath = None + if not points: + return + if len(points) == 1: + # Not much more we can do than output a single move segment. + pt, segmentType, smooth, name, kwargs = points[0] + segments: SegmentList = [("move", [(pt, smooth, name, kwargs)])] + self._flushContour(segments) + return + segments = [] + if points[0][1] == "move": + # It's an open contour, insert a "move" segment for the first + # point and remove that first point from the point list. + pt, segmentType, smooth, name, kwargs = points[0] + segments.append(("move", [(pt, smooth, name, kwargs)])) + points.pop(0) + else: + # It's a closed contour. Locate the first on-curve point, and + # rotate the point list so that it _ends_ with an on-curve + # point. + firstOnCurve = None + for i in range(len(points)): + segmentType = points[i][1] + if segmentType is not None: + firstOnCurve = i + break + if firstOnCurve is None: + # Special case for quadratics: a contour with no on-curve + # points. Add a "None" point. (See also the Pen protocol's + # qCurveTo() method and fontTools.pens.basePen.py.) + points.append((None, "qcurve", None, None, None)) + else: + points = points[firstOnCurve + 1 :] + points[: firstOnCurve + 1] + + currentSegment: SegmentPointList = [] + for pt, segmentType, smooth, name, kwargs in points: + currentSegment.append((pt, smooth, name, kwargs)) + if segmentType is None: + continue + segments.append((segmentType, currentSegment)) + currentSegment = [] + + self._flushContour(segments) + + def addPoint( + self, pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs + ): + if self.currentPath is None: + raise PenError("Path not begun") + self.currentPath.append((pt, segmentType, smooth, name, kwargs)) + + +class PointToSegmentPen(BasePointToSegmentPen): + """ + Adapter class that converts the PointPen protocol to the + (Segment)Pen protocol. + + NOTE: The segment pen does not support and will drop point names, identifiers + and kwargs. + """ + + def __init__(self, segmentPen, outputImpliedClosingLine: bool = False) -> None: + BasePointToSegmentPen.__init__(self) + self.pen = segmentPen + self.outputImpliedClosingLine = outputImpliedClosingLine + + def _flushContour(self, segments): + if not segments: + raise PenError("Must have at least one segment.") + pen = self.pen + if segments[0][0] == "move": + # It's an open path. + closed = False + points = segments[0][1] + if len(points) != 1: + raise PenError(f"Illegal move segment point count: {len(points)}") + movePt, _, _, _ = points[0] + del segments[0] + else: + # It's a closed path, do a moveTo to the last + # point of the last segment. + closed = True + segmentType, points = segments[-1] + movePt, _, _, _ = points[-1] + if movePt is None: + # quad special case: a contour with no on-curve points contains + # one "qcurve" segment that ends with a point that's None. We + # must not output a moveTo() in that case. + pass + else: + pen.moveTo(movePt) + outputImpliedClosingLine = self.outputImpliedClosingLine + nSegments = len(segments) + lastPt = movePt + for i in range(nSegments): + segmentType, points = segments[i] + points = [pt for pt, _, _, _ in points] + if segmentType == "line": + if len(points) != 1: + raise PenError(f"Illegal line segment point count: {len(points)}") + pt = points[0] + # For closed contours, a 'lineTo' is always implied from the last oncurve + # point to the starting point, thus we can omit it when the last and + # starting point don't overlap. + # However, when the last oncurve point is a "line" segment and has same + # coordinates as the starting point of a closed contour, we need to output + # the closing 'lineTo' explicitly (regardless of the value of the + # 'outputImpliedClosingLine' option) in order to disambiguate this case from + # the implied closing 'lineTo', otherwise the duplicate point would be lost. + # See https://github.com/googlefonts/fontmake/issues/572. + if ( + i + 1 != nSegments + or outputImpliedClosingLine + or not closed + or pt == lastPt + ): + pen.lineTo(pt) + lastPt = pt + elif segmentType == "curve": + pen.curveTo(*points) + lastPt = points[-1] + elif segmentType == "qcurve": + pen.qCurveTo(*points) + lastPt = points[-1] + else: + raise PenError(f"Illegal segmentType: {segmentType}") + if closed: + pen.closePath() + else: + pen.endPath() + + def addComponent(self, glyphName, transform, identifier=None, **kwargs): + del identifier # unused + del kwargs # unused + self.pen.addComponent(glyphName, transform) + + +class SegmentToPointPen(AbstractPen): + """ + Adapter class that converts the (Segment)Pen protocol to the + PointPen protocol. + """ + + def __init__(self, pointPen, guessSmooth=True) -> None: + if guessSmooth: + self.pen = GuessSmoothPointPen(pointPen) + else: + self.pen = pointPen + self.contour: Optional[List[Tuple[Point, SegmentType]]] = None + + def _flushContour(self) -> None: + pen = self.pen + pen.beginPath() + for pt, segmentType in self.contour: + pen.addPoint(pt, segmentType=segmentType) + pen.endPath() + + def moveTo(self, pt): + self.contour = [] + self.contour.append((pt, "move")) + + def lineTo(self, pt): + if self.contour is None: + raise PenError("Contour missing required initial moveTo") + self.contour.append((pt, "line")) + + def curveTo(self, *pts): + if not pts: + raise TypeError("Must pass in at least one point") + if self.contour is None: + raise PenError("Contour missing required initial moveTo") + for pt in pts[:-1]: + self.contour.append((pt, None)) + self.contour.append((pts[-1], "curve")) + + def qCurveTo(self, *pts): + if not pts: + raise TypeError("Must pass in at least one point") + if pts[-1] is None: + self.contour = [] + else: + if self.contour is None: + raise PenError("Contour missing required initial moveTo") + for pt in pts[:-1]: + self.contour.append((pt, None)) + if pts[-1] is not None: + self.contour.append((pts[-1], "qcurve")) + + def closePath(self): + if self.contour is None: + raise PenError("Contour missing required initial moveTo") + if len(self.contour) > 1 and self.contour[0][0] == self.contour[-1][0]: + self.contour[0] = self.contour[-1] + del self.contour[-1] + else: + # There's an implied line at the end, replace "move" with "line" + # for the first point + pt, tp = self.contour[0] + if tp == "move": + self.contour[0] = pt, "line" + self._flushContour() + self.contour = None + + def endPath(self): + if self.contour is None: + raise PenError("Contour missing required initial moveTo") + self._flushContour() + self.contour = None + + def addComponent(self, glyphName, transform): + if self.contour is not None: + raise PenError("Components must be added before or after contours") + self.pen.addComponent(glyphName, transform) + + +class GuessSmoothPointPen(AbstractPointPen): + """ + Filtering PointPen that tries to determine whether an on-curve point + should be "smooth", ie. that it's a "tangent" point or a "curve" point. + """ + + def __init__(self, outPen, error=0.05): + self._outPen = outPen + self._error = error + self._points = None + + def _flushContour(self): + if self._points is None: + raise PenError("Path not begun") + points = self._points + nPoints = len(points) + if not nPoints: + return + if points[0][1] == "move": + # Open path. + indices = range(1, nPoints - 1) + elif nPoints > 1: + # Closed path. To avoid having to mod the contour index, we + # simply abuse Python's negative index feature, and start at -1 + indices = range(-1, nPoints - 1) + else: + # closed path containing 1 point (!), ignore. + indices = [] + for i in indices: + pt, segmentType, _, name, kwargs = points[i] + if segmentType is None: + continue + prev = i - 1 + next = i + 1 + if points[prev][1] is not None and points[next][1] is not None: + continue + # At least one of our neighbors is an off-curve point + pt = points[i][0] + prevPt = points[prev][0] + nextPt = points[next][0] + if pt != prevPt and pt != nextPt: + dx1, dy1 = pt[0] - prevPt[0], pt[1] - prevPt[1] + dx2, dy2 = nextPt[0] - pt[0], nextPt[1] - pt[1] + a1 = math.atan2(dy1, dx1) + a2 = math.atan2(dy2, dx2) + if abs(a1 - a2) < self._error: + points[i] = pt, segmentType, True, name, kwargs + + for pt, segmentType, smooth, name, kwargs in points: + self._outPen.addPoint(pt, segmentType, smooth, name, **kwargs) + + def beginPath(self, identifier=None, **kwargs): + if self._points is not None: + raise PenError("Path already begun") + self._points = [] + if identifier is not None: + kwargs["identifier"] = identifier + self._outPen.beginPath(**kwargs) + + def endPath(self): + self._flushContour() + self._outPen.endPath() + self._points = None + + def addPoint( + self, pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs + ): + if self._points is None: + raise PenError("Path not begun") + if identifier is not None: + kwargs["identifier"] = identifier + self._points.append((pt, segmentType, False, name, kwargs)) + + def addComponent(self, glyphName, transformation, identifier=None, **kwargs): + if self._points is not None: + raise PenError("Components must be added before or after contours") + if identifier is not None: + kwargs["identifier"] = identifier + self._outPen.addComponent(glyphName, transformation, **kwargs) + + def addVarComponent( + self, glyphName, transformation, location, identifier=None, **kwargs + ): + if self._points is not None: + raise PenError("VarComponents must be added before or after contours") + if identifier is not None: + kwargs["identifier"] = identifier + self._outPen.addVarComponent(glyphName, transformation, location, **kwargs) + + +class ReverseContourPointPen(AbstractPointPen): + """ + This is a PointPen that passes outline data to another PointPen, but + reversing the winding direction of all contours. Components are simply + passed through unchanged. + + Closed contours are reversed in such a way that the first point remains + the first point. + """ + + def __init__(self, outputPointPen): + self.pen = outputPointPen + # a place to store the points for the current sub path + self.currentContour = None + + def _flushContour(self): + pen = self.pen + contour = self.currentContour + if not contour: + pen.beginPath(identifier=self.currentContourIdentifier) + pen.endPath() + return + + closed = contour[0][1] != "move" + if not closed: + lastSegmentType = "move" + else: + # Remove the first point and insert it at the end. When + # the list of points gets reversed, this point will then + # again be at the start. In other words, the following + # will hold: + # for N in range(len(originalContour)): + # originalContour[N] == reversedContour[-N] + contour.append(contour.pop(0)) + # Find the first on-curve point. + firstOnCurve = None + for i in range(len(contour)): + if contour[i][1] is not None: + firstOnCurve = i + break + if firstOnCurve is None: + # There are no on-curve points, be basically have to + # do nothing but contour.reverse(). + lastSegmentType = None + else: + lastSegmentType = contour[firstOnCurve][1] + + contour.reverse() + if not closed: + # Open paths must start with a move, so we simply dump + # all off-curve points leading up to the first on-curve. + while contour[0][1] is None: + contour.pop(0) + pen.beginPath(identifier=self.currentContourIdentifier) + for pt, nextSegmentType, smooth, name, kwargs in contour: + if nextSegmentType is not None: + segmentType = lastSegmentType + lastSegmentType = nextSegmentType + else: + segmentType = None + pen.addPoint( + pt, segmentType=segmentType, smooth=smooth, name=name, **kwargs + ) + pen.endPath() + + def beginPath(self, identifier=None, **kwargs): + if self.currentContour is not None: + raise PenError("Path already begun") + self.currentContour = [] + self.currentContourIdentifier = identifier + self.onCurve = [] + + def endPath(self): + if self.currentContour is None: + raise PenError("Path not begun") + self._flushContour() + self.currentContour = None + + def addPoint( + self, pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs + ): + if self.currentContour is None: + raise PenError("Path not begun") + if identifier is not None: + kwargs["identifier"] = identifier + self.currentContour.append((pt, segmentType, smooth, name, kwargs)) + + def addComponent(self, glyphName, transform, identifier=None, **kwargs): + if self.currentContour is not None: + raise PenError("Components must be added before or after contours") + self.pen.addComponent(glyphName, transform, identifier=identifier, **kwargs) + + +class DecomposingPointPen(LogMixin, AbstractPointPen): + """Implements a 'addComponent' method that decomposes components + (i.e. draws them onto self as simple contours). + It can also be used as a mixin class (e.g. see DecomposingRecordingPointPen). + + You must override beginPath, addPoint, endPath. You may + additionally override addVarComponent and addComponent. + + By default a warning message is logged when a base glyph is missing; + set the class variable ``skipMissingComponents`` to False if you want + all instances of a sub-class to raise a :class:`MissingComponentError` + exception by default. + """ + + skipMissingComponents = True + # alias error for convenience + MissingComponentError = MissingComponentError + + def __init__( + self, + glyphSet, + *args, + skipMissingComponents=None, + reverseFlipped: bool | ReverseFlipped = False, + **kwargs, + ): + """Takes a 'glyphSet' argument (dict), in which the glyphs that are referenced + as components are looked up by their name. + + If the optional 'reverseFlipped' argument is True or a ReverseFlipped enum value, + components whose transformation matrix has a negative determinant will be decomposed + with a reversed path direction to compensate for the flip. + + The reverseFlipped parameter can be: + - False or ReverseFlipped.NO: Don't reverse flipped components + - True or ReverseFlipped.KEEP_START: Reverse, keeping original starting point + - ReverseFlipped.ON_CURVE_FIRST: Reverse, ensuring first point is on-curve + + The optional 'skipMissingComponents' argument can be set to True/False to + override the homonymous class attribute for a given pen instance. + """ + super().__init__(*args, **kwargs) + self.glyphSet = glyphSet + self.skipMissingComponents = ( + self.__class__.skipMissingComponents + if skipMissingComponents is None + else skipMissingComponents + ) + # Handle backward compatibility and validate string inputs + if reverseFlipped is False: + self.reverseFlipped = ReverseFlipped.NO + elif reverseFlipped is True: + self.reverseFlipped = ReverseFlipped.KEEP_START + else: + self.reverseFlipped = ReverseFlipped(reverseFlipped) + + def addComponent(self, baseGlyphName, transformation, identifier=None, **kwargs): + """Transform the points of the base glyph and draw it onto self. + + The `identifier` parameter and any extra kwargs are ignored. + """ + from fontTools.pens.transformPen import TransformPointPen + + try: + glyph = self.glyphSet[baseGlyphName] + except KeyError: + if not self.skipMissingComponents: + raise MissingComponentError(baseGlyphName) + self.log.warning( + "glyph '%s' is missing from glyphSet; skipped" % baseGlyphName + ) + else: + pen = self + if transformation != Identity: + pen = TransformPointPen(pen, transformation) + if self.reverseFlipped != ReverseFlipped.NO: + # if the transformation has a negative determinant, it will + # reverse the contour direction of the component + a, b, c, d = transformation[:4] + if a * d - b * c < 0: + pen = ReverseContourPointPen(pen) + + if self.reverseFlipped == ReverseFlipped.ON_CURVE_FIRST: + from fontTools.pens.filterPen import OnCurveFirstPointPen + + # Ensure the starting point is an on-curve. + # Wrap last so this filter runs first during drawPoints + pen = OnCurveFirstPointPen(pen) + + glyph.drawPoints(pen) diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/qtPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/qtPen.py new file mode 100644 index 0000000000000000000000000000000000000000..eb13d03d2f611de4ce0b29ce3995f85e8f9e491a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/qtPen.py @@ -0,0 +1,29 @@ +from fontTools.pens.basePen import BasePen + + +__all__ = ["QtPen"] + + +class QtPen(BasePen): + def __init__(self, glyphSet, path=None): + BasePen.__init__(self, glyphSet) + if path is None: + from PyQt5.QtGui import QPainterPath + + path = QPainterPath() + self.path = path + + def _moveTo(self, p): + self.path.moveTo(*p) + + def _lineTo(self, p): + self.path.lineTo(*p) + + def _curveToOne(self, p1, p2, p3): + self.path.cubicTo(*p1, *p2, *p3) + + def _qCurveToOne(self, p1, p2): + self.path.quadTo(*p1, *p2) + + def _closePath(self): + self.path.closeSubpath() diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/qu2cuPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/qu2cuPen.py new file mode 100644 index 0000000000000000000000000000000000000000..7e400f98c45cb7fdbbba00df009b7819adffec4c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/qu2cuPen.py @@ -0,0 +1,105 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# Copyright 2023 Behdad Esfahbod. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from fontTools.qu2cu import quadratic_to_curves +from fontTools.pens.filterPen import ContourFilterPen +from fontTools.pens.reverseContourPen import ReverseContourPen +import math + + +class Qu2CuPen(ContourFilterPen): + """A filter pen to convert quadratic bezier splines to cubic curves + using the FontTools SegmentPen protocol. + + Args: + + other_pen: another SegmentPen used to draw the transformed outline. + max_err: maximum approximation error in font units. For optimal results, + if you know the UPEM of the font, we recommend setting this to a + value equal, or close to UPEM / 1000. + reverse_direction: flip the contours' direction but keep starting point. + stats: a dictionary counting the point numbers of cubic segments. + """ + + def __init__( + self, + other_pen, + max_err, + all_cubic=False, + reverse_direction=False, + stats=None, + ): + if reverse_direction: + other_pen = ReverseContourPen(other_pen) + super().__init__(other_pen) + self.all_cubic = all_cubic + self.max_err = max_err + self.stats = stats + + def _quadratics_to_curve(self, q): + curves = quadratic_to_curves(q, self.max_err, all_cubic=self.all_cubic) + if self.stats is not None: + for curve in curves: + n = str(len(curve) - 2) + self.stats[n] = self.stats.get(n, 0) + 1 + for curve in curves: + if len(curve) == 4: + yield ("curveTo", curve[1:]) + else: + yield ("qCurveTo", curve[1:]) + + def filterContour(self, contour): + quadratics = [] + currentPt = None + newContour = [] + for op, args in contour: + if op == "qCurveTo" and ( + self.all_cubic or (len(args) > 2 and args[-1] is not None) + ): + if args[-1] is None: + raise NotImplementedError( + "oncurve-less contours with all_cubic not implemented" + ) + quadratics.append((currentPt,) + args) + else: + if quadratics: + newContour.extend(self._quadratics_to_curve(quadratics)) + quadratics = [] + newContour.append((op, args)) + currentPt = args[-1] if args else None + if quadratics: + newContour.extend(self._quadratics_to_curve(quadratics)) + + if not self.all_cubic: + # Add back implicit oncurve points + contour = newContour + newContour = [] + for op, args in contour: + if op == "qCurveTo" and newContour and newContour[-1][0] == "qCurveTo": + pt0 = newContour[-1][1][-2] + pt1 = newContour[-1][1][-1] + pt2 = args[0] + if ( + pt1 is not None + and math.isclose(pt2[0] - pt1[0], pt1[0] - pt0[0]) + and math.isclose(pt2[1] - pt1[1], pt1[1] - pt0[1]) + ): + newArgs = newContour[-1][1][:-1] + args + newContour[-1] = (op, newArgs) + continue + + newContour.append((op, args)) + + return newContour diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/quartzPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/quartzPen.py new file mode 100644 index 0000000000000000000000000000000000000000..2b8a927dc4fcc49707f958e445cea80319619e6e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/quartzPen.py @@ -0,0 +1,43 @@ +from fontTools.pens.basePen import BasePen + +from Quartz.CoreGraphics import CGPathCreateMutable, CGPathMoveToPoint +from Quartz.CoreGraphics import CGPathAddLineToPoint, CGPathAddCurveToPoint +from Quartz.CoreGraphics import CGPathAddQuadCurveToPoint, CGPathCloseSubpath + + +__all__ = ["QuartzPen"] + + +class QuartzPen(BasePen): + """A pen that creates a CGPath + + Parameters + - path: an optional CGPath to add to + - xform: an optional CGAffineTransform to apply to the path + """ + + def __init__(self, glyphSet, path=None, xform=None): + BasePen.__init__(self, glyphSet) + if path is None: + path = CGPathCreateMutable() + self.path = path + self.xform = xform + + def _moveTo(self, pt): + x, y = pt + CGPathMoveToPoint(self.path, self.xform, x, y) + + def _lineTo(self, pt): + x, y = pt + CGPathAddLineToPoint(self.path, self.xform, x, y) + + def _curveToOne(self, p1, p2, p3): + (x1, y1), (x2, y2), (x3, y3) = p1, p2, p3 + CGPathAddCurveToPoint(self.path, self.xform, x1, y1, x2, y2, x3, y3) + + def _qCurveToOne(self, p1, p2): + (x1, y1), (x2, y2) = p1, p2 + CGPathAddQuadCurveToPoint(self.path, self.xform, x1, y1, x2, y2) + + def _closePath(self): + CGPathCloseSubpath(self.path) diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/recordingPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/recordingPen.py new file mode 100644 index 0000000000000000000000000000000000000000..b8a817ccf46b70c7dab0d0e94344310e566b714f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/recordingPen.py @@ -0,0 +1,335 @@ +"""Pen recording operations that can be accessed or replayed.""" + +from fontTools.pens.basePen import AbstractPen, DecomposingPen +from fontTools.pens.pointPen import AbstractPointPen, DecomposingPointPen + + +__all__ = [ + "replayRecording", + "RecordingPen", + "DecomposingRecordingPen", + "DecomposingRecordingPointPen", + "RecordingPointPen", + "lerpRecordings", +] + + +def replayRecording(recording, pen): + """Replay a recording, as produced by RecordingPen or DecomposingRecordingPen, + to a pen. + + Note that recording does not have to be produced by those pens. + It can be any iterable of tuples of method name and tuple-of-arguments. + Likewise, pen can be any objects receiving those method calls. + """ + for operator, operands in recording: + getattr(pen, operator)(*operands) + + +class RecordingPen(AbstractPen): + """Pen recording operations that can be accessed or replayed. + + The recording can be accessed as pen.value; or replayed using + pen.replay(otherPen). + + :Example: + .. code-block:: + + from fontTools.ttLib import TTFont + from fontTools.pens.recordingPen import RecordingPen + + glyph_name = 'dollar' + font_path = 'MyFont.otf' + + font = TTFont(font_path) + glyphset = font.getGlyphSet() + glyph = glyphset[glyph_name] + + pen = RecordingPen() + glyph.draw(pen) + print(pen.value) + """ + + def __init__(self): + self.value = [] + + def moveTo(self, p0): + self.value.append(("moveTo", (p0,))) + + def lineTo(self, p1): + self.value.append(("lineTo", (p1,))) + + def qCurveTo(self, *points): + self.value.append(("qCurveTo", points)) + + def curveTo(self, *points): + self.value.append(("curveTo", points)) + + def closePath(self): + self.value.append(("closePath", ())) + + def endPath(self): + self.value.append(("endPath", ())) + + def addComponent(self, glyphName, transformation): + self.value.append(("addComponent", (glyphName, transformation))) + + def addVarComponent(self, glyphName, transformation, location): + self.value.append(("addVarComponent", (glyphName, transformation, location))) + + def replay(self, pen): + replayRecording(self.value, pen) + + draw = replay + + +class DecomposingRecordingPen(DecomposingPen, RecordingPen): + """Same as RecordingPen, except that it doesn't keep components + as references, but draws them decomposed as regular contours. + + The constructor takes a required 'glyphSet' positional argument, + a dictionary of glyph objects (i.e. with a 'draw' method) keyed + by thir name; other arguments are forwarded to the DecomposingPen's + constructor:: + + >>> class SimpleGlyph(object): + ... def draw(self, pen): + ... pen.moveTo((0, 0)) + ... pen.curveTo((1, 1), (2, 2), (3, 3)) + ... pen.closePath() + >>> class CompositeGlyph(object): + ... def draw(self, pen): + ... pen.addComponent('a', (1, 0, 0, 1, -1, 1)) + >>> class MissingComponent(object): + ... def draw(self, pen): + ... pen.addComponent('foobar', (1, 0, 0, 1, 0, 0)) + >>> class FlippedComponent(object): + ... def draw(self, pen): + ... pen.addComponent('a', (-1, 0, 0, 1, 0, 0)) + >>> glyphSet = { + ... 'a': SimpleGlyph(), + ... 'b': CompositeGlyph(), + ... 'c': MissingComponent(), + ... 'd': FlippedComponent(), + ... } + >>> for name, glyph in sorted(glyphSet.items()): + ... pen = DecomposingRecordingPen(glyphSet) + ... try: + ... glyph.draw(pen) + ... except pen.MissingComponentError: + ... pass + ... print("{}: {}".format(name, pen.value)) + a: [('moveTo', ((0, 0),)), ('curveTo', ((1, 1), (2, 2), (3, 3))), ('closePath', ())] + b: [('moveTo', ((-1, 1),)), ('curveTo', ((0, 2), (1, 3), (2, 4))), ('closePath', ())] + c: [] + d: [('moveTo', ((0, 0),)), ('curveTo', ((-1, 1), (-2, 2), (-3, 3))), ('closePath', ())] + + >>> for name, glyph in sorted(glyphSet.items()): + ... pen = DecomposingRecordingPen( + ... glyphSet, skipMissingComponents=True, reverseFlipped=True, + ... ) + ... glyph.draw(pen) + ... print("{}: {}".format(name, pen.value)) + a: [('moveTo', ((0, 0),)), ('curveTo', ((1, 1), (2, 2), (3, 3))), ('closePath', ())] + b: [('moveTo', ((-1, 1),)), ('curveTo', ((0, 2), (1, 3), (2, 4))), ('closePath', ())] + c: [] + d: [('moveTo', ((0, 0),)), ('lineTo', ((-3, 3),)), ('curveTo', ((-2, 2), (-1, 1), (0, 0))), ('closePath', ())] + """ + + # raises MissingComponentError(KeyError) if base glyph is not found in glyphSet + skipMissingComponents = False + + +class RecordingPointPen(AbstractPointPen): + """PointPen recording operations that can be accessed or replayed. + + The recording can be accessed as pen.value; or replayed using + pointPen.replay(otherPointPen). + + :Example: + .. code-block:: + + from defcon import Font + from fontTools.pens.recordingPen import RecordingPointPen + + glyph_name = 'a' + font_path = 'MyFont.ufo' + + font = Font(font_path) + glyph = font[glyph_name] + + pen = RecordingPointPen() + glyph.drawPoints(pen) + print(pen.value) + + new_glyph = font.newGlyph('b') + pen.replay(new_glyph.getPointPen()) + """ + + def __init__(self): + self.value = [] + + def beginPath(self, identifier=None, **kwargs): + if identifier is not None: + kwargs["identifier"] = identifier + self.value.append(("beginPath", (), kwargs)) + + def endPath(self): + self.value.append(("endPath", (), {})) + + def addPoint( + self, pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs + ): + if identifier is not None: + kwargs["identifier"] = identifier + self.value.append(("addPoint", (pt, segmentType, smooth, name), kwargs)) + + def addComponent(self, baseGlyphName, transformation, identifier=None, **kwargs): + if identifier is not None: + kwargs["identifier"] = identifier + self.value.append(("addComponent", (baseGlyphName, transformation), kwargs)) + + def addVarComponent( + self, baseGlyphName, transformation, location, identifier=None, **kwargs + ): + if identifier is not None: + kwargs["identifier"] = identifier + self.value.append( + ("addVarComponent", (baseGlyphName, transformation, location), kwargs) + ) + + def replay(self, pointPen): + for operator, args, kwargs in self.value: + getattr(pointPen, operator)(*args, **kwargs) + + drawPoints = replay + + +class DecomposingRecordingPointPen(DecomposingPointPen, RecordingPointPen): + """Same as RecordingPointPen, except that it doesn't keep components + as references, but draws them decomposed as regular contours. + + The constructor takes a required 'glyphSet' positional argument, + a dictionary of pointPen-drawable glyph objects (i.e. with a 'drawPoints' method) + keyed by thir name; other arguments are forwarded to the DecomposingPointPen's + constructor:: + + >>> from pprint import pprint + >>> class SimpleGlyph(object): + ... def drawPoints(self, pen): + ... pen.beginPath() + ... pen.addPoint((0, 0), "line") + ... pen.addPoint((1, 1)) + ... pen.addPoint((2, 2)) + ... pen.addPoint((3, 3), "curve") + ... pen.endPath() + >>> class CompositeGlyph(object): + ... def drawPoints(self, pen): + ... pen.addComponent('a', (1, 0, 0, 1, -1, 1)) + >>> class MissingComponent(object): + ... def drawPoints(self, pen): + ... pen.addComponent('foobar', (1, 0, 0, 1, 0, 0)) + >>> class FlippedComponent(object): + ... def drawPoints(self, pen): + ... pen.addComponent('a', (-1, 0, 0, 1, 0, 0)) + >>> glyphSet = { + ... 'a': SimpleGlyph(), + ... 'b': CompositeGlyph(), + ... 'c': MissingComponent(), + ... 'd': FlippedComponent(), + ... } + >>> for name, glyph in sorted(glyphSet.items()): + ... pen = DecomposingRecordingPointPen(glyphSet) + ... try: + ... glyph.drawPoints(pen) + ... except pen.MissingComponentError: + ... pass + ... pprint({name: pen.value}) + {'a': [('beginPath', (), {}), + ('addPoint', ((0, 0), 'line', False, None), {}), + ('addPoint', ((1, 1), None, False, None), {}), + ('addPoint', ((2, 2), None, False, None), {}), + ('addPoint', ((3, 3), 'curve', False, None), {}), + ('endPath', (), {})]} + {'b': [('beginPath', (), {}), + ('addPoint', ((-1, 1), 'line', False, None), {}), + ('addPoint', ((0, 2), None, False, None), {}), + ('addPoint', ((1, 3), None, False, None), {}), + ('addPoint', ((2, 4), 'curve', False, None), {}), + ('endPath', (), {})]} + {'c': []} + {'d': [('beginPath', (), {}), + ('addPoint', ((0, 0), 'line', False, None), {}), + ('addPoint', ((-1, 1), None, False, None), {}), + ('addPoint', ((-2, 2), None, False, None), {}), + ('addPoint', ((-3, 3), 'curve', False, None), {}), + ('endPath', (), {})]} + + >>> for name, glyph in sorted(glyphSet.items()): + ... pen = DecomposingRecordingPointPen( + ... glyphSet, skipMissingComponents=True, reverseFlipped=True, + ... ) + ... glyph.drawPoints(pen) + ... pprint({name: pen.value}) + {'a': [('beginPath', (), {}), + ('addPoint', ((0, 0), 'line', False, None), {}), + ('addPoint', ((1, 1), None, False, None), {}), + ('addPoint', ((2, 2), None, False, None), {}), + ('addPoint', ((3, 3), 'curve', False, None), {}), + ('endPath', (), {})]} + {'b': [('beginPath', (), {}), + ('addPoint', ((-1, 1), 'line', False, None), {}), + ('addPoint', ((0, 2), None, False, None), {}), + ('addPoint', ((1, 3), None, False, None), {}), + ('addPoint', ((2, 4), 'curve', False, None), {}), + ('endPath', (), {})]} + {'c': []} + {'d': [('beginPath', (), {}), + ('addPoint', ((0, 0), 'curve', False, None), {}), + ('addPoint', ((-3, 3), 'line', False, None), {}), + ('addPoint', ((-2, 2), None, False, None), {}), + ('addPoint', ((-1, 1), None, False, None), {}), + ('endPath', (), {})]} + """ + + # raises MissingComponentError(KeyError) if base glyph is not found in glyphSet + skipMissingComponents = False + + +def lerpRecordings(recording1, recording2, factor=0.5): + """Linearly interpolate between two recordings. The recordings + must be decomposed, i.e. they must not contain any components. + + Factor is typically between 0 and 1. 0 means the first recording, + 1 means the second recording, and 0.5 means the average of the + two recordings. Other values are possible, and can be useful to + extrapolate. Defaults to 0.5. + + Returns a generator with the new recording. + """ + if len(recording1) != len(recording2): + raise ValueError( + "Mismatched lengths: %d and %d" % (len(recording1), len(recording2)) + ) + for (op1, args1), (op2, args2) in zip(recording1, recording2): + if op1 != op2: + raise ValueError("Mismatched operations: %s, %s" % (op1, op2)) + if op1 == "addComponent": + raise ValueError("Cannot interpolate components") + else: + mid_args = [ + (x1 + (x2 - x1) * factor, y1 + (y2 - y1) * factor) + for (x1, y1), (x2, y2) in zip(args1, args2) + ] + yield (op1, mid_args) + + +if __name__ == "__main__": + pen = RecordingPen() + pen.moveTo((0, 0)) + pen.lineTo((0, 100)) + pen.curveTo((50, 75), (60, 50), (50, 25)) + pen.closePath() + from pprint import pprint + + pprint(pen.value) diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/reportLabPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/reportLabPen.py new file mode 100644 index 0000000000000000000000000000000000000000..20c9065c71c5a0897a44949f55b9367b974be3cc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/reportLabPen.py @@ -0,0 +1,79 @@ +from fontTools.pens.basePen import BasePen +from reportlab.graphics.shapes import Path + + +__all__ = ["ReportLabPen"] + + +class ReportLabPen(BasePen): + """A pen for drawing onto a ``reportlab.graphics.shapes.Path`` object.""" + + def __init__(self, glyphSet, path=None): + BasePen.__init__(self, glyphSet) + if path is None: + path = Path() + self.path = path + + def _moveTo(self, p): + (x, y) = p + self.path.moveTo(x, y) + + def _lineTo(self, p): + (x, y) = p + self.path.lineTo(x, y) + + def _curveToOne(self, p1, p2, p3): + (x1, y1) = p1 + (x2, y2) = p2 + (x3, y3) = p3 + self.path.curveTo(x1, y1, x2, y2, x3, y3) + + def _closePath(self): + self.path.closePath() + + +if __name__ == "__main__": + import sys + + if len(sys.argv) < 3: + print( + "Usage: reportLabPen.py []" + ) + print( + " If no image file name is created, by default .png is created." + ) + print(" example: reportLabPen.py Arial.TTF R test.png") + print( + " (The file format will be PNG, regardless of the image file name supplied)" + ) + sys.exit(0) + + from fontTools.ttLib import TTFont + from reportlab.lib import colors + + path = sys.argv[1] + glyphName = sys.argv[2] + if len(sys.argv) > 3: + imageFile = sys.argv[3] + else: + imageFile = "%s.png" % glyphName + + font = TTFont(path) # it would work just as well with fontTools.t1Lib.T1Font + gs = font.getGlyphSet() + pen = ReportLabPen(gs, Path(fillColor=colors.red, strokeWidth=5)) + g = gs[glyphName] + g.draw(pen) + + w, h = g.width, 1000 + from reportlab.graphics import renderPM + from reportlab.graphics.shapes import Group, Drawing, scale + + # Everything is wrapped in a group to allow transformations. + g = Group(pen.path) + g.translate(0, 200) + g.scale(0.3, 0.3) + + d = Drawing(w, h) + d.add(g) + + renderPM.drawToFile(d, imageFile, fmt="PNG") diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/reverseContourPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/reverseContourPen.py new file mode 100644 index 0000000000000000000000000000000000000000..a3756ab17af131329e88c7136a230a32e3e7a8d5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/reverseContourPen.py @@ -0,0 +1,96 @@ +from fontTools.misc.arrayTools import pairwise +from fontTools.pens.filterPen import ContourFilterPen + + +__all__ = ["reversedContour", "ReverseContourPen"] + + +class ReverseContourPen(ContourFilterPen): + """Filter pen that passes outline data to another pen, but reversing + the winding direction of all contours. Components are simply passed + through unchanged. + + Closed contours are reversed in such a way that the first point remains + the first point. + """ + + def __init__(self, outPen, outputImpliedClosingLine=False): + super().__init__(outPen) + self.outputImpliedClosingLine = outputImpliedClosingLine + + def filterContour(self, contour): + return reversedContour(contour, self.outputImpliedClosingLine) + + +def reversedContour(contour, outputImpliedClosingLine=False): + """Generator that takes a list of pen's (operator, operands) tuples, + and yields them with the winding direction reversed. + """ + if not contour: + return # nothing to do, stop iteration + + # valid contours must have at least a starting and ending command, + # can't have one without the other + assert len(contour) > 1, "invalid contour" + + # the type of the last command determines if the contour is closed + contourType = contour.pop()[0] + assert contourType in ("endPath", "closePath") + closed = contourType == "closePath" + + firstType, firstPts = contour.pop(0) + assert firstType in ("moveTo", "qCurveTo"), ( + "invalid initial segment type: %r" % firstType + ) + firstOnCurve = firstPts[-1] + if firstType == "qCurveTo": + # special case for TrueType paths contaning only off-curve points + assert firstOnCurve is None, "off-curve only paths must end with 'None'" + assert not contour, "only one qCurveTo allowed per off-curve path" + firstPts = (firstPts[0],) + tuple(reversed(firstPts[1:-1])) + (None,) + + if not contour: + # contour contains only one segment, nothing to reverse + if firstType == "moveTo": + closed = False # single-point paths can't be closed + else: + closed = True # off-curve paths are closed by definition + yield firstType, firstPts + else: + lastType, lastPts = contour[-1] + lastOnCurve = lastPts[-1] + if closed: + # for closed paths, we keep the starting point + yield firstType, firstPts + if firstOnCurve != lastOnCurve: + # emit an implied line between the last and first points + yield "lineTo", (lastOnCurve,) + contour[-1] = (lastType, tuple(lastPts[:-1]) + (firstOnCurve,)) + + if len(contour) > 1: + secondType, secondPts = contour[0] + else: + # contour has only two points, the second and last are the same + secondType, secondPts = lastType, lastPts + + if not outputImpliedClosingLine: + # if a lineTo follows the initial moveTo, after reversing it + # will be implied by the closePath, so we don't emit one; + # unless the lineTo and moveTo overlap, in which case we keep the + # duplicate points + if secondType == "lineTo" and firstPts != secondPts: + del contour[0] + if contour: + contour[-1] = (lastType, tuple(lastPts[:-1]) + secondPts) + else: + # for open paths, the last point will become the first + yield firstType, (lastOnCurve,) + contour[-1] = (lastType, tuple(lastPts[:-1]) + (firstOnCurve,)) + + # we iterate over all segment pairs in reverse order, and yield + # each one with the off-curve points reversed (if any), and + # with the on-curve point of the following segment + for (curType, curPts), (_, nextPts) in pairwise(contour, reverse=True): + yield curType, tuple(reversed(curPts[:-1])) + (nextPts[-1],) + + yield "closePath" if closed else "endPath", () diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/roundingPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/roundingPen.py new file mode 100644 index 0000000000000000000000000000000000000000..a47a3d3df740fbbaf2d6f9dbc7f251890c62a4f5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/roundingPen.py @@ -0,0 +1,130 @@ +from fontTools.misc.roundTools import noRound, otRound +from fontTools.misc.transform import Transform +from fontTools.pens.filterPen import FilterPen, FilterPointPen + + +__all__ = ["RoundingPen", "RoundingPointPen"] + + +class RoundingPen(FilterPen): + """ + Filter pen that rounds point coordinates and component XY offsets to integer. For + rounding the component transform values, a separate round function can be passed to + the pen. + + >>> from fontTools.pens.recordingPen import RecordingPen + >>> recpen = RecordingPen() + >>> roundpen = RoundingPen(recpen) + >>> roundpen.moveTo((0.4, 0.6)) + >>> roundpen.lineTo((1.6, 2.5)) + >>> roundpen.qCurveTo((2.4, 4.6), (3.3, 5.7), (4.9, 6.1)) + >>> roundpen.curveTo((6.4, 8.6), (7.3, 9.7), (8.9, 10.1)) + >>> roundpen.addComponent("a", (1.5, 0, 0, 1.5, 10.5, -10.5)) + >>> recpen.value == [ + ... ('moveTo', ((0, 1),)), + ... ('lineTo', ((2, 3),)), + ... ('qCurveTo', ((2, 5), (3, 6), (5, 6))), + ... ('curveTo', ((6, 9), (7, 10), (9, 10))), + ... ('addComponent', ('a', (1.5, 0, 0, 1.5, 11, -10))), + ... ] + True + """ + + def __init__(self, outPen, roundFunc=otRound, transformRoundFunc=noRound): + super().__init__(outPen) + self.roundFunc = roundFunc + self.transformRoundFunc = transformRoundFunc + + def moveTo(self, pt): + self._outPen.moveTo((self.roundFunc(pt[0]), self.roundFunc(pt[1]))) + + def lineTo(self, pt): + self._outPen.lineTo((self.roundFunc(pt[0]), self.roundFunc(pt[1]))) + + def curveTo(self, *points): + self._outPen.curveTo( + *((self.roundFunc(x), self.roundFunc(y)) for x, y in points) + ) + + def qCurveTo(self, *points): + self._outPen.qCurveTo( + *((self.roundFunc(x), self.roundFunc(y)) for x, y in points) + ) + + def addComponent(self, glyphName, transformation): + xx, xy, yx, yy, dx, dy = transformation + self._outPen.addComponent( + glyphName, + Transform( + self.transformRoundFunc(xx), + self.transformRoundFunc(xy), + self.transformRoundFunc(yx), + self.transformRoundFunc(yy), + self.roundFunc(dx), + self.roundFunc(dy), + ), + ) + + +class RoundingPointPen(FilterPointPen): + """ + Filter point pen that rounds point coordinates and component XY offsets to integer. + For rounding the component scale values, a separate round function can be passed to + the pen. + + >>> from fontTools.pens.recordingPen import RecordingPointPen + >>> recpen = RecordingPointPen() + >>> roundpen = RoundingPointPen(recpen) + >>> roundpen.beginPath() + >>> roundpen.addPoint((0.4, 0.6), 'line') + >>> roundpen.addPoint((1.6, 2.5), 'line') + >>> roundpen.addPoint((2.4, 4.6)) + >>> roundpen.addPoint((3.3, 5.7)) + >>> roundpen.addPoint((4.9, 6.1), 'qcurve') + >>> roundpen.endPath() + >>> roundpen.addComponent("a", (1.5, 0, 0, 1.5, 10.5, -10.5)) + >>> recpen.value == [ + ... ('beginPath', (), {}), + ... ('addPoint', ((0, 1), 'line', False, None), {}), + ... ('addPoint', ((2, 3), 'line', False, None), {}), + ... ('addPoint', ((2, 5), None, False, None), {}), + ... ('addPoint', ((3, 6), None, False, None), {}), + ... ('addPoint', ((5, 6), 'qcurve', False, None), {}), + ... ('endPath', (), {}), + ... ('addComponent', ('a', (1.5, 0, 0, 1.5, 11, -10)), {}), + ... ] + True + """ + + def __init__(self, outPen, roundFunc=otRound, transformRoundFunc=noRound): + super().__init__(outPen) + self.roundFunc = roundFunc + self.transformRoundFunc = transformRoundFunc + + def addPoint( + self, pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs + ): + self._outPen.addPoint( + (self.roundFunc(pt[0]), self.roundFunc(pt[1])), + segmentType=segmentType, + smooth=smooth, + name=name, + identifier=identifier, + **kwargs, + ) + + def addComponent(self, baseGlyphName, transformation, identifier=None, **kwargs): + xx, xy, yx, yy, dx, dy = transformation + self._outPen.addComponent( + baseGlyphName, + Transform( + self.transformRoundFunc(xx), + self.transformRoundFunc(xy), + self.transformRoundFunc(yx), + self.transformRoundFunc(yy), + self.roundFunc(dx), + self.roundFunc(dy), + ), + identifier=identifier, + **kwargs, + ) diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/statisticsPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/statisticsPen.py new file mode 100644 index 0000000000000000000000000000000000000000..874a3c5b8d9ccbfbd78c1ec8981d92f2cc829f80 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/statisticsPen.py @@ -0,0 +1,312 @@ +"""Pen calculating area, center of mass, variance and standard-deviation, +covariance and correlation, and slant, of glyph shapes.""" + +from math import sqrt, degrees, atan +from fontTools.pens.basePen import BasePen, OpenContourError +from fontTools.pens.momentsPen import MomentsPen + +__all__ = ["StatisticsPen", "StatisticsControlPen"] + + +class StatisticsBase: + def __init__(self): + self._zero() + + def _zero(self): + self.area = 0 + self.meanX = 0 + self.meanY = 0 + self.varianceX = 0 + self.varianceY = 0 + self.stddevX = 0 + self.stddevY = 0 + self.covariance = 0 + self.correlation = 0 + self.slant = 0 + + def _update(self): + # XXX The variance formulas should never produce a negative value, + # but due to reasons I don't understand, both of our pens do. + # So we take the absolute value here. + self.varianceX = abs(self.varianceX) + self.varianceY = abs(self.varianceY) + + self.stddevX = stddevX = sqrt(self.varianceX) + self.stddevY = stddevY = sqrt(self.varianceY) + + # Correlation(X,Y) = Covariance(X,Y) / ( stddev(X) * stddev(Y) ) + # https://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient + if stddevX * stddevY == 0: + correlation = float("NaN") + else: + # XXX The above formula should never produce a value outside + # the range [-1, 1], but due to reasons I don't understand, + # (probably the same issue as above), it does. So we clamp. + correlation = self.covariance / (stddevX * stddevY) + correlation = max(-1, min(1, correlation)) + self.correlation = correlation if abs(correlation) > 1e-3 else 0 + + slant = ( + self.covariance / self.varianceY if self.varianceY != 0 else float("NaN") + ) + self.slant = slant if abs(slant) > 1e-3 else 0 + + +class StatisticsPen(StatisticsBase, MomentsPen): + """Pen calculating area, center of mass, variance and + standard-deviation, covariance and correlation, and slant, + of glyph shapes. + + Note that if the glyph shape is self-intersecting, the values + are not correct (but well-defined). Moreover, area will be + negative if contour directions are clockwise.""" + + def __init__(self, glyphset=None): + MomentsPen.__init__(self, glyphset=glyphset) + StatisticsBase.__init__(self) + + def _closePath(self): + MomentsPen._closePath(self) + self._update() + + def _update(self): + area = self.area + if not area: + self._zero() + return + + # Center of mass + # https://en.wikipedia.org/wiki/Center_of_mass#A_continuous_volume + self.meanX = meanX = self.momentX / area + self.meanY = meanY = self.momentY / area + + # Var(X) = E[X^2] - E[X]^2 + self.varianceX = self.momentXX / area - meanX * meanX + self.varianceY = self.momentYY / area - meanY * meanY + + # Covariance(X,Y) = (E[X.Y] - E[X]E[Y]) + self.covariance = self.momentXY / area - meanX * meanY + + StatisticsBase._update(self) + + +class StatisticsControlPen(StatisticsBase, BasePen): + """Pen calculating area, center of mass, variance and + standard-deviation, covariance and correlation, and slant, + of glyph shapes, using the control polygon only. + + Note that if the glyph shape is self-intersecting, the values + are not correct (but well-defined). Moreover, area will be + negative if contour directions are clockwise.""" + + def __init__(self, glyphset=None): + BasePen.__init__(self, glyphset) + StatisticsBase.__init__(self) + self._nodes = [] + + def _moveTo(self, pt): + self._nodes.append(complex(*pt)) + self._startPoint = pt + + def _lineTo(self, pt): + self._nodes.append(complex(*pt)) + + def _qCurveToOne(self, pt1, pt2): + for pt in (pt1, pt2): + self._nodes.append(complex(*pt)) + + def _curveToOne(self, pt1, pt2, pt3): + for pt in (pt1, pt2, pt3): + self._nodes.append(complex(*pt)) + + def _closePath(self): + p0 = self._getCurrentPoint() + if p0 != self._startPoint: + self._lineTo(self._startPoint) + self._update() + + def _endPath(self): + p0 = self._getCurrentPoint() + if p0 != self._startPoint: + raise OpenContourError("Glyph statistics not defined on open contours.") + self._update() + + def _update(self): + nodes = self._nodes + n = len(nodes) + + # Triangle formula + self.area = ( + sum( + (p0.real * p1.imag - p1.real * p0.imag) + for p0, p1 in zip(nodes, nodes[1:] + nodes[:1]) + ) + / 2 + ) + + # Center of mass + # https://en.wikipedia.org/wiki/Center_of_mass#A_system_of_particles + sumNodes = sum(nodes) + self.meanX = meanX = sumNodes.real / n + self.meanY = meanY = sumNodes.imag / n + + if n > 1: + # Var(X) = (sum[X^2] - sum[X]^2 / n) / (n - 1) + # https://www.statisticshowto.com/probability-and-statistics/descriptive-statistics/sample-variance/ + self.varianceX = varianceX = ( + sum(p.real * p.real for p in nodes) + - (sumNodes.real * sumNodes.real) / n + ) / (n - 1) + self.varianceY = varianceY = ( + sum(p.imag * p.imag for p in nodes) + - (sumNodes.imag * sumNodes.imag) / n + ) / (n - 1) + + # Covariance(X,Y) = (sum[X.Y] - sum[X].sum[Y] / n) / (n - 1) + self.covariance = covariance = ( + sum(p.real * p.imag for p in nodes) + - (sumNodes.real * sumNodes.imag) / n + ) / (n - 1) + else: + self.varianceX = varianceX = 0 + self.varianceY = varianceY = 0 + self.covariance = covariance = 0 + + StatisticsBase._update(self) + + +def _test(glyphset, upem, glyphs, quiet=False, *, control=False): + from fontTools.pens.transformPen import TransformPen + from fontTools.misc.transform import Scale + + wght_sum = 0 + wght_sum_perceptual = 0 + wdth_sum = 0 + slnt_sum = 0 + slnt_sum_perceptual = 0 + for glyph_name in glyphs: + glyph = glyphset[glyph_name] + if control: + pen = StatisticsControlPen(glyphset=glyphset) + else: + pen = StatisticsPen(glyphset=glyphset) + transformer = TransformPen(pen, Scale(1.0 / upem)) + glyph.draw(transformer) + + area = abs(pen.area) + width = glyph.width + wght_sum += area + wght_sum_perceptual += pen.area * width + wdth_sum += width + slnt_sum += pen.slant + slnt_sum_perceptual += pen.slant * width + + if quiet: + continue + + print() + print("glyph:", glyph_name) + + for item in [ + "area", + "momentX", + "momentY", + "momentXX", + "momentYY", + "momentXY", + "meanX", + "meanY", + "varianceX", + "varianceY", + "stddevX", + "stddevY", + "covariance", + "correlation", + "slant", + ]: + print("%s: %g" % (item, getattr(pen, item))) + + if not quiet: + print() + print("font:") + + print("weight: %g" % (wght_sum * upem / wdth_sum)) + print("weight (perceptual): %g" % (wght_sum_perceptual / wdth_sum)) + print("width: %g" % (wdth_sum / upem / len(glyphs))) + slant = slnt_sum / len(glyphs) + print("slant: %g" % slant) + print("slant angle: %g" % -degrees(atan(slant))) + slant_perceptual = slnt_sum_perceptual / wdth_sum + print("slant (perceptual): %g" % slant_perceptual) + print("slant (perceptual) angle: %g" % -degrees(atan(slant_perceptual))) + + +def main(args): + """Report font glyph shape geometricsl statistics""" + + if args is None: + import sys + + args = sys.argv[1:] + + import argparse + + parser = argparse.ArgumentParser( + "fonttools pens.statisticsPen", + description="Report font glyph shape geometricsl statistics", + ) + parser.add_argument("font", metavar="font.ttf", help="Font file.") + parser.add_argument("glyphs", metavar="glyph-name", help="Glyph names.", nargs="*") + parser.add_argument( + "-y", + metavar="", + help="Face index into a collection to open. Zero based.", + ) + parser.add_argument( + "-c", + "--control", + action="store_true", + help="Use the control-box pen instead of the Green therem.", + ) + parser.add_argument( + "-q", "--quiet", action="store_true", help="Only report font-wide statistics." + ) + parser.add_argument( + "--variations", + metavar="AXIS=LOC", + default="", + help="List of space separated locations. A location consist in " + "the name of a variation axis, followed by '=' and a number. E.g.: " + "wght=700 wdth=80. The default is the location of the base master.", + ) + + options = parser.parse_args(args) + + glyphs = options.glyphs + fontNumber = int(options.y) if options.y is not None else 0 + + location = {} + for tag_v in options.variations.split(): + fields = tag_v.split("=") + tag = fields[0].strip() + v = int(fields[1]) + location[tag] = v + + from fontTools.ttLib import TTFont + + font = TTFont(options.font, fontNumber=fontNumber) + if not glyphs: + glyphs = font.getGlyphOrder() + _test( + font.getGlyphSet(location=location), + font["head"].unitsPerEm, + glyphs, + quiet=options.quiet, + control=options.control, + ) + + +if __name__ == "__main__": + import sys + + main(sys.argv[1:]) diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/svgPathPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/svgPathPen.py new file mode 100644 index 0000000000000000000000000000000000000000..29d128da36c9d2f752617dbc143325c27e20f621 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/svgPathPen.py @@ -0,0 +1,310 @@ +from typing import Callable +from fontTools.pens.basePen import BasePen + + +def pointToString(pt, ntos=str): + return " ".join(ntos(i) for i in pt) + + +class SVGPathPen(BasePen): + """Pen to draw SVG path d commands. + + Args: + glyphSet: a dictionary of drawable glyph objects keyed by name + used to resolve component references in composite glyphs. + ntos: a callable that takes a number and returns a string, to + customize how numbers are formatted (default: str). + + :Example: + .. code-block:: + + >>> pen = SVGPathPen(None) + >>> pen.moveTo((0, 0)) + >>> pen.lineTo((1, 1)) + >>> pen.curveTo((2, 2), (3, 3), (4, 4)) + >>> pen.closePath() + >>> pen.getCommands() + 'M0 0 1 1C2 2 3 3 4 4Z' + + Note: + Fonts have a coordinate system where Y grows up, whereas in SVG, + Y grows down. As such, rendering path data from this pen in + SVG typically results in upside-down glyphs. You can fix this + by wrapping the data from this pen in an SVG group element with + transform, or wrap this pen in a transform pen. For example: + .. code-block:: python + + spen = svgPathPen.SVGPathPen(glyphset) + pen= TransformPen(spen , (1, 0, 0, -1, 0, 0)) + glyphset[glyphname].draw(pen) + print(tpen.getCommands()) + """ + + def __init__(self, glyphSet, ntos: Callable[[float], str] = str): + BasePen.__init__(self, glyphSet) + self._commands = [] + self._lastCommand = None + self._lastX = None + self._lastY = None + self._ntos = ntos + + def _handleAnchor(self): + """ + >>> pen = SVGPathPen(None) + >>> pen.moveTo((0, 0)) + >>> pen.moveTo((10, 10)) + >>> pen._commands + ['M10 10'] + """ + if self._lastCommand == "M": + self._commands.pop(-1) + + def _moveTo(self, pt): + """ + >>> pen = SVGPathPen(None) + >>> pen.moveTo((0, 0)) + >>> pen._commands + ['M0 0'] + + >>> pen = SVGPathPen(None) + >>> pen.moveTo((10, 0)) + >>> pen._commands + ['M10 0'] + + >>> pen = SVGPathPen(None) + >>> pen.moveTo((0, 10)) + >>> pen._commands + ['M0 10'] + """ + self._handleAnchor() + t = "M%s" % (pointToString(pt, self._ntos)) + self._commands.append(t) + self._lastCommand = "M" + self._lastX, self._lastY = pt + + def _lineTo(self, pt): + """ + # duplicate point + >>> pen = SVGPathPen(None) + >>> pen.moveTo((10, 10)) + >>> pen.lineTo((10, 10)) + >>> pen._commands + ['M10 10'] + + # vertical line + >>> pen = SVGPathPen(None) + >>> pen.moveTo((10, 10)) + >>> pen.lineTo((10, 0)) + >>> pen._commands + ['M10 10', 'V0'] + + # horizontal line + >>> pen = SVGPathPen(None) + >>> pen.moveTo((10, 10)) + >>> pen.lineTo((0, 10)) + >>> pen._commands + ['M10 10', 'H0'] + + # basic + >>> pen = SVGPathPen(None) + >>> pen.lineTo((70, 80)) + >>> pen._commands + ['L70 80'] + + # basic following a moveto + >>> pen = SVGPathPen(None) + >>> pen.moveTo((0, 0)) + >>> pen.lineTo((10, 10)) + >>> pen._commands + ['M0 0', ' 10 10'] + """ + x, y = pt + # duplicate point + if x == self._lastX and y == self._lastY: + return + # vertical line + elif x == self._lastX: + cmd = "V" + pts = self._ntos(y) + # horizontal line + elif y == self._lastY: + cmd = "H" + pts = self._ntos(x) + # previous was a moveto + elif self._lastCommand == "M": + cmd = None + pts = " " + pointToString(pt, self._ntos) + # basic + else: + cmd = "L" + pts = pointToString(pt, self._ntos) + # write the string + t = "" + if cmd: + t += cmd + self._lastCommand = cmd + t += pts + self._commands.append(t) + # store for future reference + self._lastX, self._lastY = pt + + def _curveToOne(self, pt1, pt2, pt3): + """ + >>> pen = SVGPathPen(None) + >>> pen.curveTo((10, 20), (30, 40), (50, 60)) + >>> pen._commands + ['C10 20 30 40 50 60'] + """ + t = "C" + t += pointToString(pt1, self._ntos) + " " + t += pointToString(pt2, self._ntos) + " " + t += pointToString(pt3, self._ntos) + self._commands.append(t) + self._lastCommand = "C" + self._lastX, self._lastY = pt3 + + def _qCurveToOne(self, pt1, pt2): + """ + >>> pen = SVGPathPen(None) + >>> pen.qCurveTo((10, 20), (30, 40)) + >>> pen._commands + ['Q10 20 30 40'] + >>> from fontTools.misc.roundTools import otRound + >>> pen = SVGPathPen(None, ntos=lambda v: str(otRound(v))) + >>> pen.qCurveTo((3, 3), (7, 5), (11, 4)) + >>> pen._commands + ['Q3 3 5 4', 'Q7 5 11 4'] + """ + assert pt2 is not None + t = "Q" + t += pointToString(pt1, self._ntos) + " " + t += pointToString(pt2, self._ntos) + self._commands.append(t) + self._lastCommand = "Q" + self._lastX, self._lastY = pt2 + + def _closePath(self): + """ + >>> pen = SVGPathPen(None) + >>> pen.closePath() + >>> pen._commands + ['Z'] + """ + self._commands.append("Z") + self._lastCommand = "Z" + self._lastX = self._lastY = None + + def _endPath(self): + """ + >>> pen = SVGPathPen(None) + >>> pen.endPath() + >>> pen._commands + [] + """ + self._lastCommand = None + self._lastX = self._lastY = None + + def getCommands(self): + return "".join(self._commands) + + +def main(args=None): + """Generate per-character SVG from font and text""" + + if args is None: + import sys + + args = sys.argv[1:] + + from fontTools.ttLib import TTFont + import argparse + + parser = argparse.ArgumentParser( + "fonttools pens.svgPathPen", description="Generate SVG from text" + ) + parser.add_argument("font", metavar="font.ttf", help="Font file.") + parser.add_argument("text", metavar="text", nargs="?", help="Text string.") + parser.add_argument( + "-y", + metavar="", + help="Face index into a collection to open. Zero based.", + ) + parser.add_argument( + "--glyphs", + metavar="whitespace-separated list of glyph names", + type=str, + help="Glyphs to show. Exclusive with text option", + ) + parser.add_argument( + "--variations", + metavar="AXIS=LOC", + default="", + help="List of space separated locations. A location consist in " + "the name of a variation axis, followed by '=' and a number. E.g.: " + "wght=700 wdth=80. The default is the location of the base master.", + ) + + options = parser.parse_args(args) + + fontNumber = int(options.y) if options.y is not None else 0 + + font = TTFont(options.font, fontNumber=fontNumber) + text = options.text + glyphs = options.glyphs + + location = {} + for tag_v in options.variations.split(): + fields = tag_v.split("=") + tag = fields[0].strip() + v = float(fields[1]) + location[tag] = v + + hhea = font["hhea"] + ascent, descent = hhea.ascent, hhea.descent + + glyphset = font.getGlyphSet(location=location) + cmap = font["cmap"].getBestCmap() + + if glyphs is not None and text is not None: + raise ValueError("Options --glyphs and --text are exclusive") + + if glyphs is None: + glyphs = " ".join(cmap[ord(u)] for u in text) + + glyphs = glyphs.split() + + s = "" + width = 0 + for g in glyphs: + glyph = glyphset[g] + + pen = SVGPathPen(glyphset) + glyph.draw(pen) + commands = pen.getCommands() + + s += '\n' % ( + width, + ascent, + commands, + ) + + width += glyph.width + + print('') + print( + '' + % (width, ascent - descent) + ) + print(s, end="") + print("") + + +if __name__ == "__main__": + import sys + + if len(sys.argv) == 1: + import doctest + + sys.exit(doctest.testmod().failed) + + sys.exit(main()) diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/t2CharStringPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/t2CharStringPen.py new file mode 100644 index 0000000000000000000000000000000000000000..ddff2c93f0a16ffa33227b324d9c2654b5051dae --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/t2CharStringPen.py @@ -0,0 +1,88 @@ +# Copyright (c) 2009 Type Supply LLC +# Author: Tal Leming + +from __future__ import annotations + +from typing import Any, Dict, List, Tuple + +from fontTools.cffLib.specializer import commandsToProgram, specializeCommands +from fontTools.misc.psCharStrings import T2CharString +from fontTools.misc.roundTools import otRound, roundFunc +from fontTools.pens.basePen import BasePen + + +class T2CharStringPen(BasePen): + """Pen to draw Type 2 CharStrings. + + The 'roundTolerance' argument controls the rounding of point coordinates. + It is defined as the maximum absolute difference between the original + float and the rounded integer value. + The default tolerance of 0.5 means that all floats are rounded to integer; + a value of 0 disables rounding; values in between will only round floats + which are close to their integral part within the tolerated range. + """ + + def __init__( + self, + width: float | None, + glyphSet: Dict[str, Any] | None, + roundTolerance: float = 0.5, + CFF2: bool = False, + ) -> None: + super(T2CharStringPen, self).__init__(glyphSet) + self.round = roundFunc(roundTolerance) + self._CFF2 = CFF2 + self._width = width + self._commands: List[Tuple[str | bytes, List[float]]] = [] + self._p0 = (0, 0) + + def _p(self, pt: Tuple[float, float]) -> List[float]: + p0 = self._p0 + pt = self._p0 = (self.round(pt[0]), self.round(pt[1])) + return [pt[0] - p0[0], pt[1] - p0[1]] + + def _moveTo(self, pt: Tuple[float, float]) -> None: + self._commands.append(("rmoveto", self._p(pt))) + + def _lineTo(self, pt: Tuple[float, float]) -> None: + self._commands.append(("rlineto", self._p(pt))) + + def _curveToOne( + self, + pt1: Tuple[float, float], + pt2: Tuple[float, float], + pt3: Tuple[float, float], + ) -> None: + _p = self._p + self._commands.append(("rrcurveto", _p(pt1) + _p(pt2) + _p(pt3))) + + def _closePath(self) -> None: + pass + + def _endPath(self) -> None: + pass + + def getCharString( + self, + private: Dict | None = None, + globalSubrs: List | None = None, + optimize: bool = True, + ) -> T2CharString: + commands = self._commands + if optimize: + maxstack = 48 if not self._CFF2 else 513 + commands = specializeCommands( + commands, generalizeFirst=False, maxstack=maxstack + ) + program = commandsToProgram(commands) + if self._width is not None: + assert ( + not self._CFF2 + ), "CFF2 does not allow encoding glyph width in CharString." + program.insert(0, otRound(self._width)) + if not self._CFF2: + program.append("endchar") + charString = T2CharString( + program=program, private=private, globalSubrs=globalSubrs + ) + return charString diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/teePen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/teePen.py new file mode 100644 index 0000000000000000000000000000000000000000..939f049b9fb3b3cd4b825e6d69cb4bd5a8936c5c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/teePen.py @@ -0,0 +1,55 @@ +"""Pen multiplexing drawing to one or more pens.""" + +from fontTools.pens.basePen import AbstractPen + + +__all__ = ["TeePen"] + + +class TeePen(AbstractPen): + """Pen multiplexing drawing to one or more pens. + + Use either as TeePen(pen1, pen2, ...) or TeePen(iterableOfPens).""" + + def __init__(self, *pens): + if len(pens) == 1: + pens = pens[0] + self.pens = pens + + def moveTo(self, p0): + for pen in self.pens: + pen.moveTo(p0) + + def lineTo(self, p1): + for pen in self.pens: + pen.lineTo(p1) + + def qCurveTo(self, *points): + for pen in self.pens: + pen.qCurveTo(*points) + + def curveTo(self, *points): + for pen in self.pens: + pen.curveTo(*points) + + def closePath(self): + for pen in self.pens: + pen.closePath() + + def endPath(self): + for pen in self.pens: + pen.endPath() + + def addComponent(self, glyphName, transformation): + for pen in self.pens: + pen.addComponent(glyphName, transformation) + + +if __name__ == "__main__": + from fontTools.pens.basePen import _TestPen + + pen = TeePen(_TestPen(), _TestPen()) + pen.moveTo((0, 0)) + pen.lineTo((0, 100)) + pen.curveTo((50, 75), (60, 50), (50, 25)) + pen.closePath() diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/transformPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/transformPen.py new file mode 100644 index 0000000000000000000000000000000000000000..3db6efdf2f3b49773d09041d9e390406a21f1721 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/transformPen.py @@ -0,0 +1,115 @@ +from fontTools.pens.filterPen import FilterPen, FilterPointPen + + +__all__ = ["TransformPen", "TransformPointPen"] + + +class TransformPen(FilterPen): + """Pen that transforms all coordinates using a Affine transformation, + and passes them to another pen. + """ + + def __init__(self, outPen, transformation): + """The 'outPen' argument is another pen object. It will receive the + transformed coordinates. The 'transformation' argument can either + be a six-tuple, or a fontTools.misc.transform.Transform object. + """ + super(TransformPen, self).__init__(outPen) + if not hasattr(transformation, "transformPoint"): + from fontTools.misc.transform import Transform + + transformation = Transform(*transformation) + self._transformation = transformation + self._transformPoint = transformation.transformPoint + self._stack = [] + + def moveTo(self, pt): + self._outPen.moveTo(self._transformPoint(pt)) + + def lineTo(self, pt): + self._outPen.lineTo(self._transformPoint(pt)) + + def curveTo(self, *points): + self._outPen.curveTo(*self._transformPoints(points)) + + def qCurveTo(self, *points): + if points[-1] is None: + points = self._transformPoints(points[:-1]) + [None] + else: + points = self._transformPoints(points) + self._outPen.qCurveTo(*points) + + def _transformPoints(self, points): + transformPoint = self._transformPoint + return [transformPoint(pt) for pt in points] + + def closePath(self): + self._outPen.closePath() + + def endPath(self): + self._outPen.endPath() + + def addComponent(self, glyphName, transformation): + transformation = self._transformation.transform(transformation) + self._outPen.addComponent(glyphName, transformation) + + +class TransformPointPen(FilterPointPen): + """PointPen that transforms all coordinates using a Affine transformation, + and passes them to another PointPen. + + For example:: + + >>> from fontTools.pens.recordingPen import RecordingPointPen + >>> rec = RecordingPointPen() + >>> pen = TransformPointPen(rec, (2, 0, 0, 2, -10, 5)) + >>> v = iter(rec.value) + >>> pen.beginPath(identifier="contour-0") + >>> next(v) + ('beginPath', (), {'identifier': 'contour-0'}) + + >>> pen.addPoint((100, 100), "line") + >>> next(v) + ('addPoint', ((190, 205), 'line', False, None), {}) + + >>> pen.endPath() + >>> next(v) + ('endPath', (), {}) + + >>> pen.addComponent("a", (1, 0, 0, 1, -10, 5), identifier="component-0") + >>> next(v) + ('addComponent', ('a', ), {'identifier': 'component-0'}) + """ + + def __init__(self, outPointPen, transformation): + """The 'outPointPen' argument is another point pen object. + It will receive the transformed coordinates. + The 'transformation' argument can either be a six-tuple, or a + fontTools.misc.transform.Transform object. + """ + super().__init__(outPointPen) + if not hasattr(transformation, "transformPoint"): + from fontTools.misc.transform import Transform + + transformation = Transform(*transformation) + self._transformation = transformation + self._transformPoint = transformation.transformPoint + + def addPoint(self, pt, segmentType=None, smooth=False, name=None, **kwargs): + self._outPen.addPoint( + self._transformPoint(pt), segmentType, smooth, name, **kwargs + ) + + def addComponent(self, baseGlyphName, transformation, **kwargs): + transformation = self._transformation.transform(transformation) + self._outPen.addComponent(baseGlyphName, transformation, **kwargs) + + +if __name__ == "__main__": + from fontTools.pens.basePen import _TestPen + + pen = TransformPen(_TestPen(None), (2, 0, 0.5, 2, -10, 0)) + pen.moveTo((0, 0)) + pen.lineTo((0, 100)) + pen.curveTo((50, 75), (60, 50), (50, 25), (0, 0)) + pen.closePath() diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/ttGlyphPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/ttGlyphPen.py new file mode 100644 index 0000000000000000000000000000000000000000..de2ccaeeb45c18c80caae049f3bd26b4ff22e99e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/ttGlyphPen.py @@ -0,0 +1,335 @@ +from array import array +from typing import Any, Callable, Dict, Optional, Tuple +from fontTools.misc.fixedTools import MAX_F2DOT14, floatToFixedToFloat +from fontTools.misc.loggingTools import LogMixin +from fontTools.pens.pointPen import AbstractPointPen +from fontTools.misc.roundTools import otRound +from fontTools.pens.basePen import LoggingPen, PenError +from fontTools.pens.transformPen import TransformPen, TransformPointPen +from fontTools.ttLib.tables import ttProgram +from fontTools.ttLib.tables._g_l_y_f import flagOnCurve, flagCubic +from fontTools.ttLib.tables._g_l_y_f import Glyph +from fontTools.ttLib.tables._g_l_y_f import GlyphComponent +from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates +from fontTools.ttLib.tables._g_l_y_f import dropImpliedOnCurvePoints +import math + + +__all__ = ["TTGlyphPen", "TTGlyphPointPen"] + + +class _TTGlyphBasePen: + def __init__( + self, + glyphSet: Optional[Dict[str, Any]], + handleOverflowingTransforms: bool = True, + ) -> None: + """ + Construct a new pen. + + Args: + glyphSet (Dict[str, Any]): A glyphset object, used to resolve components. + handleOverflowingTransforms (bool): See below. + + If ``handleOverflowingTransforms`` is True, the components' transform values + are checked that they don't overflow the limits of a F2Dot14 number: + -2.0 <= v < +2.0. If any transform value exceeds these, the composite + glyph is decomposed. + + An exception to this rule is done for values that are very close to +2.0 + (both for consistency with the -2.0 case, and for the relative frequency + these occur in real fonts). When almost +2.0 values occur (and all other + values are within the range -2.0 <= x <= +2.0), they are clamped to the + maximum positive value that can still be encoded as an F2Dot14: i.e. + 1.99993896484375. + + If False, no check is done and all components are translated unmodified + into the glyf table, followed by an inevitable ``struct.error`` once an + attempt is made to compile them. + + If both contours and components are present in a glyph, the components + are decomposed. + """ + self.glyphSet = glyphSet + self.handleOverflowingTransforms = handleOverflowingTransforms + self.init() + + def _decompose( + self, + glyphName: str, + transformation: Tuple[float, float, float, float, float, float], + ): + tpen = self.transformPen(self, transformation) + getattr(self.glyphSet[glyphName], self.drawMethod)(tpen) + + def _isClosed(self): + """ + Check if the current path is closed. + """ + raise NotImplementedError + + def init(self) -> None: + self.points = [] + self.endPts = [] + self.types = [] + self.components = [] + + def addComponent( + self, + baseGlyphName: str, + transformation: Tuple[float, float, float, float, float, float], + identifier: Optional[str] = None, + **kwargs: Any, + ) -> None: + """ + Add a sub glyph. + """ + self.components.append((baseGlyphName, transformation)) + + def _buildComponents(self, componentFlags): + if self.handleOverflowingTransforms: + # we can't encode transform values > 2 or < -2 in F2Dot14, + # so we must decompose the glyph if any transform exceeds these + overflowing = any( + s > 2 or s < -2 + for (glyphName, transformation) in self.components + for s in transformation[:4] + ) + components = [] + for glyphName, transformation in self.components: + if glyphName not in self.glyphSet: + self.log.warning(f"skipped non-existing component '{glyphName}'") + continue + if self.points or (self.handleOverflowingTransforms and overflowing): + # can't have both coordinates and components, so decompose + self._decompose(glyphName, transformation) + continue + + component = GlyphComponent() + component.glyphName = glyphName + component.x, component.y = (otRound(v) for v in transformation[4:]) + # quantize floats to F2Dot14 so we get same values as when decompiled + # from a binary glyf table + transformation = tuple( + floatToFixedToFloat(v, 14) for v in transformation[:4] + ) + if transformation != (1, 0, 0, 1): + if self.handleOverflowingTransforms and any( + MAX_F2DOT14 < s <= 2 for s in transformation + ): + # clamp values ~= +2.0 so we can keep the component + transformation = tuple( + MAX_F2DOT14 if MAX_F2DOT14 < s <= 2 else s + for s in transformation + ) + component.transform = (transformation[:2], transformation[2:]) + component.flags = componentFlags + components.append(component) + return components + + def glyph( + self, + componentFlags: int = 0x04, + dropImpliedOnCurves: bool = False, + *, + round: Callable[[float], int] = otRound, + ) -> Glyph: + """ + Returns a :py:class:`~._g_l_y_f.Glyph` object representing the glyph. + + Args: + componentFlags: Flags to use for component glyphs. (default: 0x04) + + dropImpliedOnCurves: Whether to remove implied-oncurve points. (default: False) + """ + if not self._isClosed(): + raise PenError("Didn't close last contour.") + components = self._buildComponents(componentFlags) + + glyph = Glyph() + glyph.coordinates = GlyphCoordinates(self.points) + glyph.endPtsOfContours = self.endPts + glyph.flags = array("B", self.types) + self.init() + + if components: + # If both components and contours were present, they have by now + # been decomposed by _buildComponents. + glyph.components = components + glyph.numberOfContours = -1 + else: + glyph.numberOfContours = len(glyph.endPtsOfContours) + glyph.program = ttProgram.Program() + glyph.program.fromBytecode(b"") + if dropImpliedOnCurves: + dropImpliedOnCurvePoints(glyph) + glyph.coordinates.toInt(round=round) + + return glyph + + +class TTGlyphPen(_TTGlyphBasePen, LoggingPen): + """ + Pen used for drawing to a TrueType glyph. + + This pen can be used to construct or modify glyphs in a TrueType format + font. After using the pen to draw, use the ``.glyph()`` method to retrieve + a :py:class:`~._g_l_y_f.Glyph` object representing the glyph. + """ + + drawMethod = "draw" + transformPen = TransformPen + + def __init__( + self, + glyphSet: Optional[Dict[str, Any]] = None, + handleOverflowingTransforms: bool = True, + outputImpliedClosingLine: bool = False, + ) -> None: + super().__init__(glyphSet, handleOverflowingTransforms) + self.outputImpliedClosingLine = outputImpliedClosingLine + + def _addPoint(self, pt: Tuple[float, float], tp: int) -> None: + self.points.append(pt) + self.types.append(tp) + + def _popPoint(self) -> None: + self.points.pop() + self.types.pop() + + def _isClosed(self) -> bool: + return (not self.points) or ( + self.endPts and self.endPts[-1] == len(self.points) - 1 + ) + + def lineTo(self, pt: Tuple[float, float]) -> None: + self._addPoint(pt, flagOnCurve) + + def moveTo(self, pt: Tuple[float, float]) -> None: + if not self._isClosed(): + raise PenError('"move"-type point must begin a new contour.') + self._addPoint(pt, flagOnCurve) + + def curveTo(self, *points) -> None: + assert len(points) % 2 == 1 + for pt in points[:-1]: + self._addPoint(pt, flagCubic) + + # last point is None if there are no on-curve points + if points[-1] is not None: + self._addPoint(points[-1], 1) + + def qCurveTo(self, *points) -> None: + assert len(points) >= 1 + for pt in points[:-1]: + self._addPoint(pt, 0) + + # last point is None if there are no on-curve points + if points[-1] is not None: + self._addPoint(points[-1], 1) + + def closePath(self) -> None: + endPt = len(self.points) - 1 + + # ignore anchors (one-point paths) + if endPt == 0 or (self.endPts and endPt == self.endPts[-1] + 1): + self._popPoint() + return + + if not self.outputImpliedClosingLine: + # if first and last point on this path are the same, remove last + startPt = 0 + if self.endPts: + startPt = self.endPts[-1] + 1 + if self.points[startPt] == self.points[endPt]: + self._popPoint() + endPt -= 1 + + self.endPts.append(endPt) + + def endPath(self) -> None: + # TrueType contours are always "closed" + self.closePath() + + +class TTGlyphPointPen(_TTGlyphBasePen, LogMixin, AbstractPointPen): + """ + Point pen used for drawing to a TrueType glyph. + + This pen can be used to construct or modify glyphs in a TrueType format + font. After using the pen to draw, use the ``.glyph()`` method to retrieve + a :py:class:`~._g_l_y_f.Glyph` object representing the glyph. + """ + + drawMethod = "drawPoints" + transformPen = TransformPointPen + + def init(self) -> None: + super().init() + self._currentContourStartIndex = None + + def _isClosed(self) -> bool: + return self._currentContourStartIndex is None + + def beginPath(self, identifier: Optional[str] = None, **kwargs: Any) -> None: + """ + Start a new sub path. + """ + if not self._isClosed(): + raise PenError("Didn't close previous contour.") + self._currentContourStartIndex = len(self.points) + + def endPath(self) -> None: + """ + End the current sub path. + """ + # TrueType contours are always "closed" + if self._isClosed(): + raise PenError("Contour is already closed.") + if self._currentContourStartIndex == len(self.points): + # ignore empty contours + self._currentContourStartIndex = None + return + + contourStart = self.endPts[-1] + 1 if self.endPts else 0 + self.endPts.append(len(self.points) - 1) + self._currentContourStartIndex = None + + # Resolve types for any cubic segments + flags = self.types + for i in range(contourStart, len(flags)): + if flags[i] == "curve": + j = i - 1 + if j < contourStart: + j = len(flags) - 1 + while flags[j] == 0: + flags[j] = flagCubic + j -= 1 + flags[i] = flagOnCurve + + def addPoint( + self, + pt: Tuple[float, float], + segmentType: Optional[str] = None, + smooth: bool = False, + name: Optional[str] = None, + identifier: Optional[str] = None, + **kwargs: Any, + ) -> None: + """ + Add a point to the current sub path. + """ + if self._isClosed(): + raise PenError("Can't add a point to a closed contour.") + if segmentType is None: + self.types.append(0) + elif segmentType in ("line", "move"): + self.types.append(flagOnCurve) + elif segmentType == "qcurve": + self.types.append(flagOnCurve) + elif segmentType == "curve": + self.types.append("curve") + else: + raise AssertionError(segmentType) + + self.points.append(pt) diff --git a/.venv/lib/python3.13/site-packages/fontTools/pens/wxPen.py b/.venv/lib/python3.13/site-packages/fontTools/pens/wxPen.py new file mode 100644 index 0000000000000000000000000000000000000000..c790641a23c0950d492df2082b7a9b6a9d53cb53 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/pens/wxPen.py @@ -0,0 +1,29 @@ +from fontTools.pens.basePen import BasePen + + +__all__ = ["WxPen"] + + +class WxPen(BasePen): + def __init__(self, glyphSet, path=None): + BasePen.__init__(self, glyphSet) + if path is None: + import wx + + path = wx.GraphicsRenderer.GetDefaultRenderer().CreatePath() + self.path = path + + def _moveTo(self, p): + self.path.MoveToPoint(*p) + + def _lineTo(self, p): + self.path.AddLineToPoint(*p) + + def _curveToOne(self, p1, p2, p3): + self.path.AddCurveToPoint(*p1 + p2 + p3) + + def _qCurveToOne(self, p1, p2): + self.path.AddQuadCurveToPoint(*p1 + p2) + + def _closePath(self): + self.path.CloseSubpath() diff --git a/.venv/lib/python3.13/site-packages/fontTools/svgLib/__init__.py b/.venv/lib/python3.13/site-packages/fontTools/svgLib/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c049006bf2e58bed7786432e7ec84c8c8b40edf0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/svgLib/__init__.py @@ -0,0 +1,3 @@ +from .path import SVGPath, parse_path + +__all__ = ["SVGPath", "parse_path"] diff --git a/.venv/lib/python3.13/site-packages/fontTools/svgLib/path/__init__.py b/.venv/lib/python3.13/site-packages/fontTools/svgLib/path/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..043b4dbe1deb2d3a56e06fa43ed30694e7149544 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/svgLib/path/__init__.py @@ -0,0 +1,65 @@ +from fontTools.pens.transformPen import TransformPen +from fontTools.misc import etree +from fontTools.misc.textTools import tostr +from .parser import parse_path +from .shapes import PathBuilder + + +__all__ = [tostr(s) for s in ("SVGPath", "parse_path")] + + +class SVGPath(object): + """Parse SVG ``path`` elements from a file or string, and draw them + onto a glyph object that supports the FontTools Pen protocol. + + For example, reading from an SVG file and drawing to a Defcon Glyph: + + .. code-block:: + + import defcon + glyph = defcon.Glyph() + pen = glyph.getPen() + svg = SVGPath("path/to/a.svg") + svg.draw(pen) + + Or reading from a string containing SVG data, using the alternative + 'fromstring' (a class method): + + .. code-block:: + + data = ' 1: + rx *= sqrt(radii_scale) + ry *= sqrt(radii_scale) + self.rx, self.ry = rx, ry + + point_transform = Scale(1 / rx, 1 / ry).rotate(-self.angle) + + point1 = _map_point(point_transform, self.current_point) + point2 = _map_point(point_transform, self.target_point) + delta = point2 - point1 + + d = delta.real * delta.real + delta.imag * delta.imag + scale_factor_squared = max(1 / d - 0.25, 0.0) + + scale_factor = sqrt(scale_factor_squared) + if self.sweep == self.large: + scale_factor = -scale_factor + + delta *= scale_factor + center_point = (point1 + point2) * 0.5 + center_point += complex(-delta.imag, delta.real) + point1 -= center_point + point2 -= center_point + + theta1 = atan2(point1.imag, point1.real) + theta2 = atan2(point2.imag, point2.real) + + theta_arc = theta2 - theta1 + if theta_arc < 0 and self.sweep: + theta_arc += TWO_PI + elif theta_arc > 0 and not self.sweep: + theta_arc -= TWO_PI + + self.theta1 = theta1 + self.theta2 = theta1 + theta_arc + self.theta_arc = theta_arc + self.center_point = center_point + + return True + + def _decompose_to_cubic_curves(self): + if self.center_point is None and not self._parametrize(): + return + + point_transform = Identity.rotate(self.angle).scale(self.rx, self.ry) + + # Some results of atan2 on some platform implementations are not exact + # enough. So that we get more cubic curves than expected here. Adding 0.001f + # reduces the count of sgements to the correct count. + num_segments = int(ceil(fabs(self.theta_arc / (PI_OVER_TWO + 0.001)))) + for i in range(num_segments): + start_theta = self.theta1 + i * self.theta_arc / num_segments + end_theta = self.theta1 + (i + 1) * self.theta_arc / num_segments + + t = (4 / 3) * tan(0.25 * (end_theta - start_theta)) + if not isfinite(t): + return + + sin_start_theta = sin(start_theta) + cos_start_theta = cos(start_theta) + sin_end_theta = sin(end_theta) + cos_end_theta = cos(end_theta) + + point1 = complex( + cos_start_theta - t * sin_start_theta, + sin_start_theta + t * cos_start_theta, + ) + point1 += self.center_point + target_point = complex(cos_end_theta, sin_end_theta) + target_point += self.center_point + point2 = target_point + point2 += complex(t * sin_end_theta, -t * cos_end_theta) + + point1 = _map_point(point_transform, point1) + point2 = _map_point(point_transform, point2) + target_point = _map_point(point_transform, target_point) + + yield point1, point2, target_point + + def draw(self, pen): + for point1, point2, target_point in self._decompose_to_cubic_curves(): + pen.curveTo( + (point1.real, point1.imag), + (point2.real, point2.imag), + (target_point.real, target_point.imag), + ) diff --git a/.venv/lib/python3.13/site-packages/fontTools/svgLib/path/parser.py b/.venv/lib/python3.13/site-packages/fontTools/svgLib/path/parser.py new file mode 100644 index 0000000000000000000000000000000000000000..18c8e77f7f7e5636530fa4424083f97d4208d810 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/svgLib/path/parser.py @@ -0,0 +1,322 @@ +# SVG Path specification parser. +# This is an adaptation from 'svg.path' by Lennart Regebro (@regebro), +# modified so that the parser takes a FontTools Pen object instead of +# returning a list of svg.path Path objects. +# The original code can be found at: +# https://github.com/regebro/svg.path/blob/4f9b6e3/src/svg/path/parser.py +# Copyright (c) 2013-2014 Lennart Regebro +# License: MIT + +from .arc import EllipticalArc +import re + + +COMMANDS = set("MmZzLlHhVvCcSsQqTtAa") +ARC_COMMANDS = set("Aa") +UPPERCASE = set("MZLHVCSQTA") + +COMMAND_RE = re.compile("([MmZzLlHhVvCcSsQqTtAa])") + +# https://www.w3.org/TR/css-syntax-3/#number-token-diagram +# but -6.e-5 will be tokenized as "-6" then "-5" and confuse parsing +FLOAT_RE = re.compile( + r"[-+]?" # optional sign + r"(?:" + r"(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][-+]?[0-9]+)?" # int/float + r"|" + r"(?:\.[0-9]+(?:[eE][-+]?[0-9]+)?)" # float with leading dot (e.g. '.42') + r")" +) +BOOL_RE = re.compile("^[01]") +SEPARATOR_RE = re.compile(f"[, \t]") + + +def _tokenize_path(pathdef): + arc_cmd = None + for x in COMMAND_RE.split(pathdef): + if x in COMMANDS: + arc_cmd = x if x in ARC_COMMANDS else None + yield x + continue + + if arc_cmd: + try: + yield from _tokenize_arc_arguments(x) + except ValueError as e: + raise ValueError(f"Invalid arc command: '{arc_cmd}{x}'") from e + else: + for token in FLOAT_RE.findall(x): + yield token + + +ARC_ARGUMENT_TYPES = ( + ("rx", FLOAT_RE), + ("ry", FLOAT_RE), + ("x-axis-rotation", FLOAT_RE), + ("large-arc-flag", BOOL_RE), + ("sweep-flag", BOOL_RE), + ("x", FLOAT_RE), + ("y", FLOAT_RE), +) + + +def _tokenize_arc_arguments(arcdef): + raw_args = [s for s in SEPARATOR_RE.split(arcdef) if s] + if not raw_args: + raise ValueError(f"Not enough arguments: '{arcdef}'") + raw_args.reverse() + + i = 0 + while raw_args: + arg = raw_args.pop() + + name, pattern = ARC_ARGUMENT_TYPES[i] + match = pattern.search(arg) + if not match: + raise ValueError(f"Invalid argument for '{name}' parameter: {arg!r}") + + j, k = match.span() + yield arg[j:k] + arg = arg[k:] + + if arg: + raw_args.append(arg) + + # wrap around every 7 consecutive arguments + if i == 6: + i = 0 + else: + i += 1 + + if i != 0: + raise ValueError(f"Not enough arguments: '{arcdef}'") + + +def parse_path(pathdef, pen, current_pos=(0, 0), arc_class=EllipticalArc): + """Parse SVG path definition (i.e. "d" attribute of elements) + and call a 'pen' object's moveTo, lineTo, curveTo, qCurveTo and closePath + methods. + + If 'current_pos' (2-float tuple) is provided, the initial moveTo will + be relative to that instead being absolute. + + If the pen has an "arcTo" method, it is called with the original values + of the elliptical arc curve commands: + + .. code-block:: + + pen.arcTo(rx, ry, rotation, arc_large, arc_sweep, (x, y)) + + Otherwise, the arcs are approximated by series of cubic Bezier segments + ("curveTo"), one every 90 degrees. + """ + # In the SVG specs, initial movetos are absolute, even if + # specified as 'm'. This is the default behavior here as well. + # But if you pass in a current_pos variable, the initial moveto + # will be relative to that current_pos. This is useful. + current_pos = complex(*current_pos) + + elements = list(_tokenize_path(pathdef)) + # Reverse for easy use of .pop() + elements.reverse() + + start_pos = None + command = None + last_control = None + + have_arcTo = hasattr(pen, "arcTo") + + while elements: + if elements[-1] in COMMANDS: + # New command. + last_command = command # Used by S and T + command = elements.pop() + absolute = command in UPPERCASE + command = command.upper() + else: + # If this element starts with numbers, it is an implicit command + # and we don't change the command. Check that it's allowed: + if command is None: + raise ValueError( + "Unallowed implicit command in %s, position %s" + % (pathdef, len(pathdef.split()) - len(elements)) + ) + last_command = command # Used by S and T + + if command == "M": + # Moveto command. + x = elements.pop() + y = elements.pop() + pos = float(x) + float(y) * 1j + if absolute: + current_pos = pos + else: + current_pos += pos + + # M is not preceded by Z; it's an open subpath + if start_pos is not None: + pen.endPath() + + pen.moveTo((current_pos.real, current_pos.imag)) + + # when M is called, reset start_pos + # This behavior of Z is defined in svg spec: + # http://www.w3.org/TR/SVG/paths.html#PathDataClosePathCommand + start_pos = current_pos + + # Implicit moveto commands are treated as lineto commands. + # So we set command to lineto here, in case there are + # further implicit commands after this moveto. + command = "L" + + elif command == "Z": + # Close path + if current_pos != start_pos: + pen.lineTo((start_pos.real, start_pos.imag)) + pen.closePath() + current_pos = start_pos + start_pos = None + command = None # You can't have implicit commands after closing. + + elif command == "L": + x = elements.pop() + y = elements.pop() + pos = float(x) + float(y) * 1j + if not absolute: + pos += current_pos + pen.lineTo((pos.real, pos.imag)) + current_pos = pos + + elif command == "H": + x = elements.pop() + pos = float(x) + current_pos.imag * 1j + if not absolute: + pos += current_pos.real + pen.lineTo((pos.real, pos.imag)) + current_pos = pos + + elif command == "V": + y = elements.pop() + pos = current_pos.real + float(y) * 1j + if not absolute: + pos += current_pos.imag * 1j + pen.lineTo((pos.real, pos.imag)) + current_pos = pos + + elif command == "C": + control1 = float(elements.pop()) + float(elements.pop()) * 1j + control2 = float(elements.pop()) + float(elements.pop()) * 1j + end = float(elements.pop()) + float(elements.pop()) * 1j + + if not absolute: + control1 += current_pos + control2 += current_pos + end += current_pos + + pen.curveTo( + (control1.real, control1.imag), + (control2.real, control2.imag), + (end.real, end.imag), + ) + current_pos = end + last_control = control2 + + elif command == "S": + # Smooth curve. First control point is the "reflection" of + # the second control point in the previous path. + + if last_command not in "CS": + # If there is no previous command or if the previous command + # was not an C, c, S or s, assume the first control point is + # coincident with the current point. + control1 = current_pos + else: + # The first control point is assumed to be the reflection of + # the second control point on the previous command relative + # to the current point. + control1 = current_pos + current_pos - last_control + + control2 = float(elements.pop()) + float(elements.pop()) * 1j + end = float(elements.pop()) + float(elements.pop()) * 1j + + if not absolute: + control2 += current_pos + end += current_pos + + pen.curveTo( + (control1.real, control1.imag), + (control2.real, control2.imag), + (end.real, end.imag), + ) + current_pos = end + last_control = control2 + + elif command == "Q": + control = float(elements.pop()) + float(elements.pop()) * 1j + end = float(elements.pop()) + float(elements.pop()) * 1j + + if not absolute: + control += current_pos + end += current_pos + + pen.qCurveTo((control.real, control.imag), (end.real, end.imag)) + current_pos = end + last_control = control + + elif command == "T": + # Smooth curve. Control point is the "reflection" of + # the second control point in the previous path. + + if last_command not in "QT": + # If there is no previous command or if the previous command + # was not an Q, q, T or t, assume the first control point is + # coincident with the current point. + control = current_pos + else: + # The control point is assumed to be the reflection of + # the control point on the previous command relative + # to the current point. + control = current_pos + current_pos - last_control + + end = float(elements.pop()) + float(elements.pop()) * 1j + + if not absolute: + end += current_pos + + pen.qCurveTo((control.real, control.imag), (end.real, end.imag)) + current_pos = end + last_control = control + + elif command == "A": + rx = abs(float(elements.pop())) + ry = abs(float(elements.pop())) + rotation = float(elements.pop()) + arc_large = bool(int(elements.pop())) + arc_sweep = bool(int(elements.pop())) + end = float(elements.pop()) + float(elements.pop()) * 1j + + if not absolute: + end += current_pos + + # if the pen supports arcs, pass the values unchanged, otherwise + # approximate the arc with a series of cubic bezier curves + if have_arcTo: + pen.arcTo( + rx, + ry, + rotation, + arc_large, + arc_sweep, + (end.real, end.imag), + ) + else: + arc = arc_class( + current_pos, rx, ry, rotation, arc_large, arc_sweep, end + ) + arc.draw(pen) + + current_pos = end + + # no final Z command, it's an open path + if start_pos is not None: + pen.endPath() diff --git a/.venv/lib/python3.13/site-packages/fontTools/svgLib/path/shapes.py b/.venv/lib/python3.13/site-packages/fontTools/svgLib/path/shapes.py new file mode 100644 index 0000000000000000000000000000000000000000..3f22e6c6a3e4d24636e710f1920ebf04a822b159 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/svgLib/path/shapes.py @@ -0,0 +1,183 @@ +import re + + +def _prefer_non_zero(*args): + for arg in args: + if arg != 0: + return arg + return 0.0 + + +def _ntos(n): + # %f likes to add unnecessary 0's, %g isn't consistent about # decimals + return ("%.3f" % n).rstrip("0").rstrip(".") + + +def _strip_xml_ns(tag): + # ElementTree API doesn't provide a way to ignore XML namespaces in tags + # so we here strip them ourselves: cf. https://bugs.python.org/issue18304 + return tag.split("}", 1)[1] if "}" in tag else tag + + +def _transform(raw_value): + # TODO assumes a 'matrix' transform. + # No other transform functions are supported at the moment. + # https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform + # start simple: if you aren't exactly matrix(...) then no love + match = re.match(r"matrix\((.*)\)", raw_value) + if not match: + raise NotImplementedError + matrix = tuple(float(p) for p in re.split(r"\s+|,", match.group(1))) + if len(matrix) != 6: + raise ValueError("wrong # of terms in %s" % raw_value) + return matrix + + +class PathBuilder(object): + def __init__(self): + self.paths = [] + self.transforms = [] + + def _start_path(self, initial_path=""): + self.paths.append(initial_path) + self.transforms.append(None) + + def _end_path(self): + self._add("z") + + def _add(self, path_snippet): + path = self.paths[-1] + if path: + path += " " + path_snippet + else: + path = path_snippet + self.paths[-1] = path + + def _move(self, c, x, y): + self._add("%s%s,%s" % (c, _ntos(x), _ntos(y))) + + def M(self, x, y): + self._move("M", x, y) + + def m(self, x, y): + self._move("m", x, y) + + def _arc(self, c, rx, ry, x, y, large_arc): + self._add( + "%s%s,%s 0 %d 1 %s,%s" + % (c, _ntos(rx), _ntos(ry), large_arc, _ntos(x), _ntos(y)) + ) + + def A(self, rx, ry, x, y, large_arc=0): + self._arc("A", rx, ry, x, y, large_arc) + + def a(self, rx, ry, x, y, large_arc=0): + self._arc("a", rx, ry, x, y, large_arc) + + def _vhline(self, c, x): + self._add("%s%s" % (c, _ntos(x))) + + def H(self, x): + self._vhline("H", x) + + def h(self, x): + self._vhline("h", x) + + def V(self, y): + self._vhline("V", y) + + def v(self, y): + self._vhline("v", y) + + def _line(self, c, x, y): + self._add("%s%s,%s" % (c, _ntos(x), _ntos(y))) + + def L(self, x, y): + self._line("L", x, y) + + def l(self, x, y): + self._line("l", x, y) + + def _parse_line(self, line): + x1 = float(line.attrib.get("x1", 0)) + y1 = float(line.attrib.get("y1", 0)) + x2 = float(line.attrib.get("x2", 0)) + y2 = float(line.attrib.get("y2", 0)) + + self._start_path() + self.M(x1, y1) + self.L(x2, y2) + + def _parse_rect(self, rect): + x = float(rect.attrib.get("x", 0)) + y = float(rect.attrib.get("y", 0)) + w = float(rect.attrib.get("width")) + h = float(rect.attrib.get("height")) + rx = float(rect.attrib.get("rx", 0)) + ry = float(rect.attrib.get("ry", 0)) + + rx = _prefer_non_zero(rx, ry) + ry = _prefer_non_zero(ry, rx) + # TODO there are more rules for adjusting rx, ry + + self._start_path() + self.M(x + rx, y) + self.H(x + w - rx) + if rx > 0: + self.A(rx, ry, x + w, y + ry) + self.V(y + h - ry) + if rx > 0: + self.A(rx, ry, x + w - rx, y + h) + self.H(x + rx) + if rx > 0: + self.A(rx, ry, x, y + h - ry) + self.V(y + ry) + if rx > 0: + self.A(rx, ry, x + rx, y) + self._end_path() + + def _parse_path(self, path): + if "d" in path.attrib: + self._start_path(initial_path=path.attrib["d"]) + + def _parse_polygon(self, poly): + if "points" in poly.attrib: + self._start_path("M" + poly.attrib["points"]) + self._end_path() + + def _parse_polyline(self, poly): + if "points" in poly.attrib: + self._start_path("M" + poly.attrib["points"]) + + def _parse_circle(self, circle): + cx = float(circle.attrib.get("cx", 0)) + cy = float(circle.attrib.get("cy", 0)) + r = float(circle.attrib.get("r")) + + # arc doesn't seem to like being a complete shape, draw two halves + self._start_path() + self.M(cx - r, cy) + self.A(r, r, cx + r, cy, large_arc=1) + self.A(r, r, cx - r, cy, large_arc=1) + + def _parse_ellipse(self, ellipse): + cx = float(ellipse.attrib.get("cx", 0)) + cy = float(ellipse.attrib.get("cy", 0)) + rx = float(ellipse.attrib.get("rx")) + ry = float(ellipse.attrib.get("ry")) + + # arc doesn't seem to like being a complete shape, draw two halves + self._start_path() + self.M(cx - rx, cy) + self.A(rx, ry, cx + rx, cy, large_arc=1) + self.A(rx, ry, cx - rx, cy, large_arc=1) + + def add_path_from_element(self, el): + tag = _strip_xml_ns(el.tag) + parse_fn = getattr(self, "_parse_%s" % tag.lower(), None) + if not callable(parse_fn): + return False + parse_fn(el) + if "transform" in el.attrib: + self.transforms[-1] = _transform(el.attrib["transform"]) + return True diff --git a/.venv/lib/python3.13/site-packages/fontTools/t1Lib/__init__.py b/.venv/lib/python3.13/site-packages/fontTools/t1Lib/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0475881e91490fc1096a904688d09880758a46c1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/t1Lib/__init__.py @@ -0,0 +1,648 @@ +"""fontTools.t1Lib.py -- Tools for PostScript Type 1 fonts. + +Functions for reading and writing raw Type 1 data: + +read(path) + reads any Type 1 font file, returns the raw data and a type indicator: + 'LWFN', 'PFB' or 'OTHER', depending on the format of the file pointed + to by 'path'. + Raises an error when the file does not contain valid Type 1 data. + +write(path, data, kind='OTHER', dohex=False) + writes raw Type 1 data to the file pointed to by 'path'. + 'kind' can be one of 'LWFN', 'PFB' or 'OTHER'; it defaults to 'OTHER'. + 'dohex' is a flag which determines whether the eexec encrypted + part should be written as hexadecimal or binary, but only if kind + is 'OTHER'. +""" + +import fontTools +from fontTools.misc import eexec +from fontTools.misc.macCreatorType import getMacCreatorAndType +from fontTools.misc.textTools import bytechr, byteord, bytesjoin, tobytes +from fontTools.misc.psOperators import ( + _type1_pre_eexec_order, + _type1_fontinfo_order, + _type1_post_eexec_order, +) +from fontTools.encodings.StandardEncoding import StandardEncoding +import os +import re + +__author__ = "jvr" +__version__ = "1.0b3" +DEBUG = 0 + + +try: + try: + from Carbon import Res + except ImportError: + import Res # MacPython < 2.2 +except ImportError: + haveMacSupport = 0 +else: + haveMacSupport = 1 + + +class T1Error(Exception): + pass + + +class T1Font(object): + """Type 1 font class. + + Uses a minimal interpeter that supports just about enough PS to parse + Type 1 fonts. + """ + + def __init__(self, path, encoding="ascii", kind=None): + if kind is None: + self.data, _ = read(path) + elif kind == "LWFN": + self.data = readLWFN(path) + elif kind == "PFB": + self.data = readPFB(path) + elif kind == "OTHER": + self.data = readOther(path) + else: + raise ValueError(kind) + self.encoding = encoding + + def saveAs(self, path, type, dohex=False): + write(path, self.getData(), type, dohex) + + def getData(self): + if not hasattr(self, "data"): + self.data = self.createData() + return self.data + + def getGlyphSet(self): + """Return a generic GlyphSet, which is a dict-like object + mapping glyph names to glyph objects. The returned glyph objects + have a .draw() method that supports the Pen protocol, and will + have an attribute named 'width', but only *after* the .draw() method + has been called. + + In the case of Type 1, the GlyphSet is simply the CharStrings dict. + """ + return self["CharStrings"] + + def __getitem__(self, key): + if not hasattr(self, "font"): + self.parse() + return self.font[key] + + def parse(self): + from fontTools.misc import psLib + from fontTools.misc import psCharStrings + + self.font = psLib.suckfont(self.data, self.encoding) + charStrings = self.font["CharStrings"] + lenIV = self.font["Private"].get("lenIV", 4) + assert lenIV >= 0 + subrs = self.font["Private"]["Subrs"] + for glyphName, charString in charStrings.items(): + charString, R = eexec.decrypt(charString, 4330) + charStrings[glyphName] = psCharStrings.T1CharString( + charString[lenIV:], subrs=subrs + ) + for i in range(len(subrs)): + charString, R = eexec.decrypt(subrs[i], 4330) + subrs[i] = psCharStrings.T1CharString(charString[lenIV:], subrs=subrs) + del self.data + + def createData(self): + sf = self.font + + eexec_began = False + eexec_dict = {} + lines = [] + lines.extend( + [ + self._tobytes(f"%!FontType1-1.1: {sf['FontName']}"), + self._tobytes(f"%t1Font: ({fontTools.version})"), + self._tobytes(f"%%BeginResource: font {sf['FontName']}"), + ] + ) + # follow t1write.c:writeRegNameKeyedFont + size = 3 # Headroom for new key addition + size += 1 # FontMatrix is always counted + size += 1 + 1 # Private, CharStings + for key in font_dictionary_keys: + size += int(key in sf) + lines.append(self._tobytes(f"{size} dict dup begin")) + + for key, value in sf.items(): + if eexec_began: + eexec_dict[key] = value + continue + + if key == "FontInfo": + fi = sf["FontInfo"] + # follow t1write.c:writeFontInfoDict + size = 3 # Headroom for new key addition + for subkey in FontInfo_dictionary_keys: + size += int(subkey in fi) + lines.append(self._tobytes(f"/FontInfo {size} dict dup begin")) + + for subkey, subvalue in fi.items(): + lines.extend(self._make_lines(subkey, subvalue)) + lines.append(b"end def") + elif key in _type1_post_eexec_order: # usually 'Private' + eexec_dict[key] = value + eexec_began = True + else: + lines.extend(self._make_lines(key, value)) + lines.append(b"end") + eexec_portion = self.encode_eexec(eexec_dict) + lines.append(bytesjoin([b"currentfile eexec ", eexec_portion])) + + for _ in range(8): + lines.append(self._tobytes("0" * 64)) + lines.extend([b"cleartomark", b"%%EndResource", b"%%EOF"]) + + data = bytesjoin(lines, "\n") + return data + + def encode_eexec(self, eexec_dict): + lines = [] + + # '-|', '|-', '|' + RD_key, ND_key, NP_key = None, None, None + lenIV = 4 + subrs = std_subrs + + # Ensure we look at Private first, because we need RD_key, ND_key, NP_key and lenIV + sortedItems = sorted(eexec_dict.items(), key=lambda item: item[0] != "Private") + + for key, value in sortedItems: + if key == "Private": + pr = eexec_dict["Private"] + # follow t1write.c:writePrivateDict + size = 3 # for RD, ND, NP + for subkey in Private_dictionary_keys: + size += int(subkey in pr) + lines.append(b"dup /Private") + lines.append(self._tobytes(f"{size} dict dup begin")) + for subkey, subvalue in pr.items(): + if not RD_key and subvalue == RD_value: + RD_key = subkey + elif not ND_key and subvalue in ND_values: + ND_key = subkey + elif not NP_key and subvalue in PD_values: + NP_key = subkey + + if subkey == "lenIV": + lenIV = subvalue + + if subkey == "OtherSubrs": + # XXX: assert that no flex hint is used + lines.append(self._tobytes(hintothers)) + elif subkey == "Subrs": + for subr_bin in subvalue: + subr_bin.compile() + subrs = [subr_bin.bytecode for subr_bin in subvalue] + lines.append(f"/Subrs {len(subrs)} array".encode("ascii")) + for i, subr_bin in enumerate(subrs): + encrypted_subr, R = eexec.encrypt( + bytesjoin([char_IV[:lenIV], subr_bin]), 4330 + ) + lines.append( + bytesjoin( + [ + self._tobytes( + f"dup {i} {len(encrypted_subr)} {RD_key} " + ), + encrypted_subr, + self._tobytes(f" {NP_key}"), + ] + ) + ) + lines.append(b"def") + + lines.append(b"put") + else: + lines.extend(self._make_lines(subkey, subvalue)) + elif key == "CharStrings": + lines.append(b"dup /CharStrings") + lines.append( + self._tobytes(f"{len(eexec_dict['CharStrings'])} dict dup begin") + ) + for glyph_name, char_bin in eexec_dict["CharStrings"].items(): + char_bin.compile() + encrypted_char, R = eexec.encrypt( + bytesjoin([char_IV[:lenIV], char_bin.bytecode]), 4330 + ) + lines.append( + bytesjoin( + [ + self._tobytes( + f"/{glyph_name} {len(encrypted_char)} {RD_key} " + ), + encrypted_char, + self._tobytes(f" {ND_key}"), + ] + ) + ) + lines.append(b"end put") + else: + lines.extend(self._make_lines(key, value)) + + lines.extend( + [ + b"end", + b"dup /FontName get exch definefont pop", + b"mark", + b"currentfile closefile\n", + ] + ) + + eexec_portion = bytesjoin(lines, "\n") + encrypted_eexec, R = eexec.encrypt(bytesjoin([eexec_IV, eexec_portion]), 55665) + + return encrypted_eexec + + def _make_lines(self, key, value): + if key == "FontName": + return [self._tobytes(f"/{key} /{value} def")] + if key in ["isFixedPitch", "ForceBold", "RndStemUp"]: + return [self._tobytes(f"/{key} {'true' if value else 'false'} def")] + elif key == "Encoding": + if value == StandardEncoding: + return [self._tobytes(f"/{key} StandardEncoding def")] + else: + # follow fontTools.misc.psOperators._type1_Encoding_repr + lines = [] + lines.append(b"/Encoding 256 array") + lines.append(b"0 1 255 {1 index exch /.notdef put} for") + for i in range(256): + name = value[i] + if name != ".notdef": + lines.append(self._tobytes(f"dup {i} /{name} put")) + lines.append(b"def") + return lines + if isinstance(value, str): + return [self._tobytes(f"/{key} ({value}) def")] + elif isinstance(value, bool): + return [self._tobytes(f"/{key} {'true' if value else 'false'} def")] + elif isinstance(value, list): + return [self._tobytes(f"/{key} [{' '.join(str(v) for v in value)}] def")] + elif isinstance(value, tuple): + return [self._tobytes(f"/{key} {{{' '.join(str(v) for v in value)}}} def")] + else: + return [self._tobytes(f"/{key} {value} def")] + + def _tobytes(self, s, errors="strict"): + return tobytes(s, self.encoding, errors) + + +# low level T1 data read and write functions + + +def read(path, onlyHeader=False): + """reads any Type 1 font file, returns raw data""" + _, ext = os.path.splitext(path) + ext = ext.lower() + creator, typ = getMacCreatorAndType(path) + if typ == "LWFN": + return readLWFN(path, onlyHeader), "LWFN" + if ext == ".pfb": + return readPFB(path, onlyHeader), "PFB" + else: + return readOther(path), "OTHER" + + +def write(path, data, kind="OTHER", dohex=False): + assertType1(data) + kind = kind.upper() + try: + os.remove(path) + except os.error: + pass + err = 1 + try: + if kind == "LWFN": + writeLWFN(path, data) + elif kind == "PFB": + writePFB(path, data) + else: + writeOther(path, data, dohex) + err = 0 + finally: + if err and not DEBUG: + try: + os.remove(path) + except os.error: + pass + + +# -- internal -- + +LWFNCHUNKSIZE = 2000 +HEXLINELENGTH = 80 + + +def readLWFN(path, onlyHeader=False): + """reads an LWFN font file, returns raw data""" + from fontTools.misc.macRes import ResourceReader + + reader = ResourceReader(path) + try: + data = [] + for res in reader.get("POST", []): + code = byteord(res.data[0]) + if byteord(res.data[1]) != 0: + raise T1Error("corrupt LWFN file") + if code in [1, 2]: + if onlyHeader and code == 2: + break + data.append(res.data[2:]) + elif code in [3, 5]: + break + elif code == 4: + with open(path, "rb") as f: + data.append(f.read()) + elif code == 0: + pass # comment, ignore + else: + raise T1Error("bad chunk code: " + repr(code)) + finally: + reader.close() + data = bytesjoin(data) + assertType1(data) + return data + + +def readPFB(path, onlyHeader=False): + """reads a PFB font file, returns raw data""" + data = [] + with open(path, "rb") as f: + while True: + if f.read(1) != bytechr(128): + raise T1Error("corrupt PFB file") + code = byteord(f.read(1)) + if code in [1, 2]: + chunklen = stringToLong(f.read(4)) + chunk = f.read(chunklen) + assert len(chunk) == chunklen + data.append(chunk) + elif code == 3: + break + else: + raise T1Error("bad chunk code: " + repr(code)) + if onlyHeader: + break + data = bytesjoin(data) + assertType1(data) + return data + + +def readOther(path): + """reads any (font) file, returns raw data""" + with open(path, "rb") as f: + data = f.read() + assertType1(data) + chunks = findEncryptedChunks(data) + data = [] + for isEncrypted, chunk in chunks: + if isEncrypted and isHex(chunk[:4]): + data.append(deHexString(chunk)) + else: + data.append(chunk) + return bytesjoin(data) + + +# file writing tools + + +def writeLWFN(path, data): + # Res.FSpCreateResFile was deprecated in OS X 10.5 + Res.FSpCreateResFile(path, "just", "LWFN", 0) + resRef = Res.FSOpenResFile(path, 2) # write-only + try: + Res.UseResFile(resRef) + resID = 501 + chunks = findEncryptedChunks(data) + for isEncrypted, chunk in chunks: + if isEncrypted: + code = 2 + else: + code = 1 + while chunk: + res = Res.Resource(bytechr(code) + "\0" + chunk[: LWFNCHUNKSIZE - 2]) + res.AddResource("POST", resID, "") + chunk = chunk[LWFNCHUNKSIZE - 2 :] + resID = resID + 1 + res = Res.Resource(bytechr(5) + "\0") + res.AddResource("POST", resID, "") + finally: + Res.CloseResFile(resRef) + + +def writePFB(path, data): + chunks = findEncryptedChunks(data) + with open(path, "wb") as f: + for isEncrypted, chunk in chunks: + if isEncrypted: + code = 2 + else: + code = 1 + f.write(bytechr(128) + bytechr(code)) + f.write(longToString(len(chunk))) + f.write(chunk) + f.write(bytechr(128) + bytechr(3)) + + +def writeOther(path, data, dohex=False): + chunks = findEncryptedChunks(data) + with open(path, "wb") as f: + hexlinelen = HEXLINELENGTH // 2 + for isEncrypted, chunk in chunks: + if isEncrypted: + code = 2 + else: + code = 1 + if code == 2 and dohex: + while chunk: + f.write(eexec.hexString(chunk[:hexlinelen])) + f.write(b"\r") + chunk = chunk[hexlinelen:] + else: + f.write(chunk) + + +# decryption tools + +EEXECBEGIN = b"currentfile eexec" +# The spec allows for 512 ASCII zeros interrupted by arbitrary whitespace to +# follow eexec +EEXECEND = re.compile(b"(0[ \t\r\n]*){512}", flags=re.M) +EEXECINTERNALEND = b"currentfile closefile" +EEXECBEGINMARKER = b"%-- eexec start\r" +EEXECENDMARKER = b"%-- eexec end\r" + +_ishexRE = re.compile(b"[0-9A-Fa-f]*$") + + +def isHex(text): + return _ishexRE.match(text) is not None + + +def decryptType1(data): + chunks = findEncryptedChunks(data) + data = [] + for isEncrypted, chunk in chunks: + if isEncrypted: + if isHex(chunk[:4]): + chunk = deHexString(chunk) + decrypted, R = eexec.decrypt(chunk, 55665) + decrypted = decrypted[4:] + if ( + decrypted[-len(EEXECINTERNALEND) - 1 : -1] != EEXECINTERNALEND + and decrypted[-len(EEXECINTERNALEND) - 2 : -2] != EEXECINTERNALEND + ): + raise T1Error("invalid end of eexec part") + decrypted = decrypted[: -len(EEXECINTERNALEND) - 2] + b"\r" + data.append(EEXECBEGINMARKER + decrypted + EEXECENDMARKER) + else: + if chunk[-len(EEXECBEGIN) - 1 : -1] == EEXECBEGIN: + data.append(chunk[: -len(EEXECBEGIN) - 1]) + else: + data.append(chunk) + return bytesjoin(data) + + +def findEncryptedChunks(data): + chunks = [] + while True: + eBegin = data.find(EEXECBEGIN) + if eBegin < 0: + break + eBegin = eBegin + len(EEXECBEGIN) + 1 + endMatch = EEXECEND.search(data, eBegin) + if endMatch is None: + raise T1Error("can't find end of eexec part") + eEnd = endMatch.start() + cypherText = data[eBegin : eEnd + 2] + if isHex(cypherText[:4]): + cypherText = deHexString(cypherText) + plainText, R = eexec.decrypt(cypherText, 55665) + eEndLocal = plainText.find(EEXECINTERNALEND) + if eEndLocal < 0: + raise T1Error("can't find end of eexec part") + chunks.append((0, data[:eBegin])) + chunks.append((1, cypherText[: eEndLocal + len(EEXECINTERNALEND) + 1])) + data = data[eEnd:] + chunks.append((0, data)) + return chunks + + +def deHexString(hexstring): + return eexec.deHexString(bytesjoin(hexstring.split())) + + +# Type 1 assertion + +_fontType1RE = re.compile(rb"/FontType\s+1\s+def") + + +def assertType1(data): + for head in [b"%!PS-AdobeFont", b"%!FontType1"]: + if data[: len(head)] == head: + break + else: + raise T1Error("not a PostScript font") + if not _fontType1RE.search(data): + raise T1Error("not a Type 1 font") + if data.find(b"currentfile eexec") < 0: + raise T1Error("not an encrypted Type 1 font") + # XXX what else? + return data + + +# pfb helpers + + +def longToString(long): + s = b"" + for i in range(4): + s += bytechr((long & (0xFF << (i * 8))) >> i * 8) + return s + + +def stringToLong(s): + if len(s) != 4: + raise ValueError("string must be 4 bytes long") + l = 0 + for i in range(4): + l += byteord(s[i]) << (i * 8) + return l + + +# PS stream helpers + +font_dictionary_keys = list(_type1_pre_eexec_order) +# t1write.c:writeRegNameKeyedFont +# always counts following keys +font_dictionary_keys.remove("FontMatrix") + +FontInfo_dictionary_keys = list(_type1_fontinfo_order) +# extend because AFDKO tx may use following keys +FontInfo_dictionary_keys.extend( + [ + "FSType", + "Copyright", + ] +) + +Private_dictionary_keys = [ + # We don't know what names will be actually used. + # "RD", + # "ND", + # "NP", + "Subrs", + "OtherSubrs", + "UniqueID", + "BlueValues", + "OtherBlues", + "FamilyBlues", + "FamilyOtherBlues", + "BlueScale", + "BlueShift", + "BlueFuzz", + "StdHW", + "StdVW", + "StemSnapH", + "StemSnapV", + "ForceBold", + "LanguageGroup", + "password", + "lenIV", + "MinFeature", + "RndStemUp", +] + +# t1write_hintothers.h +hintothers = """/OtherSubrs[{}{}{}{systemdict/internaldict known not{pop 3}{1183615869 +systemdict/internaldict get exec dup/startlock known{/startlock get exec}{dup +/strtlck known{/strtlck get exec}{pop 3}ifelse}ifelse}ifelse}executeonly]def""" +# t1write.c:saveStdSubrs +std_subrs = [ + # 3 0 callother pop pop setcurrentpoint return + b"\x8e\x8b\x0c\x10\x0c\x11\x0c\x11\x0c\x21\x0b", + # 0 1 callother return + b"\x8b\x8c\x0c\x10\x0b", + # 0 2 callother return + b"\x8b\x8d\x0c\x10\x0b", + # return + b"\x0b", + # 3 1 3 callother pop callsubr return + b"\x8e\x8c\x8e\x0c\x10\x0c\x11\x0a\x0b", +] +# follow t1write.c:writeRegNameKeyedFont +eexec_IV = b"cccc" +char_IV = b"\x0c\x0c\x0c\x0c" +RD_value = ("string", "currentfile", "exch", "readstring", "pop") +ND_values = [("def",), ("noaccess", "def")] +PD_values = [("put",), ("noaccess", "put")] diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/B_A_S_E_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/B_A_S_E_.py new file mode 100644 index 0000000000000000000000000000000000000000..0f4b1c3c5a7a3fe53de316dfd9b23fe5096eeb37 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/B_A_S_E_.py @@ -0,0 +1,14 @@ +from .otBase import BaseTTXConverter + + +class table_B_A_S_E_(BaseTTXConverter): + """Baseline table + + The ``BASE`` table contains information needed to align glyphs in + different scripts, from different fonts, or at different sizes + within the same line of text. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/base + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/BitmapGlyphMetrics.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/BitmapGlyphMetrics.py new file mode 100644 index 0000000000000000000000000000000000000000..10b4f828213b8320d54eefed3d5e66f2ba532101 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/BitmapGlyphMetrics.py @@ -0,0 +1,64 @@ +# Since bitmap glyph metrics are shared between EBLC and EBDT +# this class gets its own python file. +from fontTools.misc import sstruct +from fontTools.misc.textTools import safeEval +import logging + + +log = logging.getLogger(__name__) + +bigGlyphMetricsFormat = """ + > # big endian + height: B + width: B + horiBearingX: b + horiBearingY: b + horiAdvance: B + vertBearingX: b + vertBearingY: b + vertAdvance: B +""" + +smallGlyphMetricsFormat = """ + > # big endian + height: B + width: B + BearingX: b + BearingY: b + Advance: B +""" + + +class BitmapGlyphMetrics(object): + def toXML(self, writer, ttFont): + writer.begintag(self.__class__.__name__) + writer.newline() + for metricName in sstruct.getformat(self.__class__.binaryFormat)[1]: + writer.simpletag(metricName, value=getattr(self, metricName)) + writer.newline() + writer.endtag(self.__class__.__name__) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + metricNames = set(sstruct.getformat(self.__class__.binaryFormat)[1]) + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + # Make sure this is a metric that is needed by GlyphMetrics. + if name in metricNames: + vars(self)[name] = safeEval(attrs["value"]) + else: + log.warning( + "unknown name '%s' being ignored in %s.", + name, + self.__class__.__name__, + ) + + +class BigGlyphMetrics(BitmapGlyphMetrics): + binaryFormat = bigGlyphMetricsFormat + + +class SmallGlyphMetrics(BitmapGlyphMetrics): + binaryFormat = smallGlyphMetricsFormat diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_B_D_T_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_B_D_T_.py new file mode 100644 index 0000000000000000000000000000000000000000..0f9924745ebb4519be2d0cdcddadb86cc741cf8b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_B_D_T_.py @@ -0,0 +1,113 @@ +# Copyright 2013 Google, Inc. All Rights Reserved. +# +# Google Author(s): Matt Fontaine + + +from fontTools.misc.textTools import bytesjoin +from fontTools.misc import sstruct +from . import E_B_D_T_ +from .BitmapGlyphMetrics import ( + BigGlyphMetrics, + bigGlyphMetricsFormat, + SmallGlyphMetrics, + smallGlyphMetricsFormat, +) +from .E_B_D_T_ import ( + BitmapGlyph, + BitmapPlusSmallMetricsMixin, + BitmapPlusBigMetricsMixin, +) +import struct + + +class table_C_B_D_T_(E_B_D_T_.table_E_B_D_T_): + """Color Bitmap Data table + + The ``CBDT`` table contains color bitmap data for glyphs. It must + be used in concert with the ``CBLC`` table. + + It is backwards-compatible with the monochrome/grayscale ``EBDT`` table. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/cbdt + """ + + # Change the data locator table being referenced. + locatorName = "CBLC" + + # Modify the format class accessor for color bitmap use. + def getImageFormatClass(self, imageFormat): + try: + return E_B_D_T_.table_E_B_D_T_.getImageFormatClass(self, imageFormat) + except KeyError: + return cbdt_bitmap_classes[imageFormat] + + +# Helper method for removing export features not supported by color bitmaps. +# Write data in the parent class will default to raw if an option is unsupported. +def _removeUnsupportedForColor(dataFunctions): + dataFunctions = dict(dataFunctions) + del dataFunctions["row"] + return dataFunctions + + +class ColorBitmapGlyph(BitmapGlyph): + fileExtension = ".png" + xmlDataFunctions = _removeUnsupportedForColor(BitmapGlyph.xmlDataFunctions) + + +class cbdt_bitmap_format_17(BitmapPlusSmallMetricsMixin, ColorBitmapGlyph): + def decompile(self): + self.metrics = SmallGlyphMetrics() + dummy, data = sstruct.unpack2(smallGlyphMetricsFormat, self.data, self.metrics) + (dataLen,) = struct.unpack(">L", data[:4]) + data = data[4:] + + # For the image data cut it to the size specified by dataLen. + assert dataLen <= len(data), "Data overun in format 17" + self.imageData = data[:dataLen] + + def compile(self, ttFont): + dataList = [] + dataList.append(sstruct.pack(smallGlyphMetricsFormat, self.metrics)) + dataList.append(struct.pack(">L", len(self.imageData))) + dataList.append(self.imageData) + return bytesjoin(dataList) + + +class cbdt_bitmap_format_18(BitmapPlusBigMetricsMixin, ColorBitmapGlyph): + def decompile(self): + self.metrics = BigGlyphMetrics() + dummy, data = sstruct.unpack2(bigGlyphMetricsFormat, self.data, self.metrics) + (dataLen,) = struct.unpack(">L", data[:4]) + data = data[4:] + + # For the image data cut it to the size specified by dataLen. + assert dataLen <= len(data), "Data overun in format 18" + self.imageData = data[:dataLen] + + def compile(self, ttFont): + dataList = [] + dataList.append(sstruct.pack(bigGlyphMetricsFormat, self.metrics)) + dataList.append(struct.pack(">L", len(self.imageData))) + dataList.append(self.imageData) + return bytesjoin(dataList) + + +class cbdt_bitmap_format_19(ColorBitmapGlyph): + def decompile(self): + (dataLen,) = struct.unpack(">L", self.data[:4]) + data = self.data[4:] + + assert dataLen <= len(data), "Data overun in format 19" + self.imageData = data[:dataLen] + + def compile(self, ttFont): + return struct.pack(">L", len(self.imageData)) + self.imageData + + +# Dict for CBDT extended formats. +cbdt_bitmap_classes = { + 17: cbdt_bitmap_format_17, + 18: cbdt_bitmap_format_18, + 19: cbdt_bitmap_format_19, +} diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_B_L_C_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_B_L_C_.py new file mode 100644 index 0000000000000000000000000000000000000000..0673fb7ed2215f481f303c5b98c9941accd916bf --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_B_L_C_.py @@ -0,0 +1,19 @@ +# Copyright 2013 Google, Inc. All Rights Reserved. +# +# Google Author(s): Matt Fontaine + +from . import E_B_L_C_ + + +class table_C_B_L_C_(E_B_L_C_.table_E_B_L_C_): + """Color Bitmap Location table + + The ``CBLC`` table contains the locations of color bitmaps for glyphs. It must + be used in concert with the ``CBDT`` table. + + It is backwards-compatible with the monochrome/grayscale ``EBLC`` table. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/cblc + """ + + dependencies = ["CBDT"] diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_F_F_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_F_F_.py new file mode 100644 index 0000000000000000000000000000000000000000..3d974ced88e9d9a1e9c0494c4d0eac996ec315b8 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_F_F_.py @@ -0,0 +1,61 @@ +from io import BytesIO +from fontTools import cffLib +from . import DefaultTable + + +class table_C_F_F_(DefaultTable.DefaultTable): + """Compact Font Format table (version 1) + + The ``CFF`` table embeds a CFF-formatted font. The CFF font format + predates OpenType and could be used as a standalone font file, but the + ``CFF`` table is also used to package CFF fonts into an OpenType + container. + + .. note:: + ``CFF`` has been succeeded by ``CFF2``, which eliminates much of + the redundancy incurred by embedding CFF version 1 in an OpenType + font. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/cff + """ + + def __init__(self, tag=None): + DefaultTable.DefaultTable.__init__(self, tag) + self.cff = cffLib.CFFFontSet() + self._gaveGlyphOrder = False + + def decompile(self, data, otFont): + self.cff.decompile(BytesIO(data), otFont, isCFF2=False) + assert len(self.cff) == 1, "can't deal with multi-font CFF tables." + + def compile(self, otFont): + f = BytesIO() + self.cff.compile(f, otFont, isCFF2=False) + return f.getvalue() + + def haveGlyphNames(self): + if hasattr(self.cff[self.cff.fontNames[0]], "ROS"): + return False # CID-keyed font + else: + return True + + def getGlyphOrder(self): + if self._gaveGlyphOrder: + from fontTools import ttLib + + raise ttLib.TTLibError("illegal use of getGlyphOrder()") + self._gaveGlyphOrder = True + return self.cff[self.cff.fontNames[0]].getGlyphOrder() + + def setGlyphOrder(self, glyphOrder): + pass + # XXX + # self.cff[self.cff.fontNames[0]].setGlyphOrder(glyphOrder) + + def toXML(self, writer, otFont): + self.cff.toXML(writer) + + def fromXML(self, name, attrs, content, otFont): + if not hasattr(self, "cff"): + self.cff = cffLib.CFFFontSet() + self.cff.fromXML(name, attrs, content, otFont) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_F_F__2.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_F_F__2.py new file mode 100644 index 0000000000000000000000000000000000000000..ff07682d24f0399b6579f529ae70cf4fd87abf21 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_F_F__2.py @@ -0,0 +1,26 @@ +from io import BytesIO +from fontTools.ttLib.tables.C_F_F_ import table_C_F_F_ + + +class table_C_F_F__2(table_C_F_F_): + """Compact Font Format version 2 table + + The ``CFF2`` table contains glyph data for a CFF2-flavored OpenType + font. + + .. note:: + ``CFF2`` is the successor to ``CFF``, and eliminates much of + the redundancy incurred by embedding CFF version 1 in an OpenType + font. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/cff2 + """ + + def decompile(self, data, otFont): + self.cff.decompile(BytesIO(data), otFont, isCFF2=True) + assert len(self.cff) == 1, "can't deal with multi-font CFF tables." + + def compile(self, otFont): + f = BytesIO() + self.cff.compile(f, otFont, isCFF2=True) + return f.getvalue() diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_O_L_R_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_O_L_R_.py new file mode 100644 index 0000000000000000000000000000000000000000..266a11c41dffc5eed42ee446c0268373104cbf7a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_O_L_R_.py @@ -0,0 +1,165 @@ +# Copyright 2013 Google, Inc. All Rights Reserved. +# +# Google Author(s): Behdad Esfahbod + +from fontTools.misc.textTools import safeEval +from . import DefaultTable + + +class table_C_O_L_R_(DefaultTable.DefaultTable): + """Color table + + The ``COLR`` table defines color presentation of outline glyphs. It must + be used in concert with the ``CPAL`` table, which contains the color + descriptors used. + + This table is structured so that you can treat it like a dictionary keyed by glyph name. + + ``ttFont['COLR'][]`` will return the color layers for any glyph. + + ``ttFont['COLR'][] = `` will set the color layers for any glyph. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/colr + """ + + @staticmethod + def _decompileColorLayersV0(table): + if not table.LayerRecordArray: + return {} + colorLayerLists = {} + layerRecords = table.LayerRecordArray.LayerRecord + numLayerRecords = len(layerRecords) + for baseRec in table.BaseGlyphRecordArray.BaseGlyphRecord: + baseGlyph = baseRec.BaseGlyph + firstLayerIndex = baseRec.FirstLayerIndex + numLayers = baseRec.NumLayers + assert firstLayerIndex + numLayers <= numLayerRecords + layers = [] + for i in range(firstLayerIndex, firstLayerIndex + numLayers): + layerRec = layerRecords[i] + layers.append(LayerRecord(layerRec.LayerGlyph, layerRec.PaletteIndex)) + colorLayerLists[baseGlyph] = layers + return colorLayerLists + + def _toOTTable(self, ttFont): + from . import otTables + from fontTools.colorLib.builder import populateCOLRv0 + + tableClass = getattr(otTables, self.tableTag) + table = tableClass() + table.Version = self.version + + populateCOLRv0( + table, + { + baseGlyph: [(layer.name, layer.colorID) for layer in layers] + for baseGlyph, layers in self.ColorLayers.items() + }, + glyphMap=ttFont.getReverseGlyphMap(rebuild=True), + ) + return table + + def decompile(self, data, ttFont): + from .otBase import OTTableReader + from . import otTables + + # We use otData to decompile, but we adapt the decompiled otTables to the + # existing COLR v0 API for backward compatibility. + reader = OTTableReader(data, tableTag=self.tableTag) + tableClass = getattr(otTables, self.tableTag) + table = tableClass() + table.decompile(reader, ttFont) + + self.version = table.Version + if self.version == 0: + self.ColorLayers = self._decompileColorLayersV0(table) + else: + # for new versions, keep the raw otTables around + self.table = table + + def compile(self, ttFont): + from .otBase import OTTableWriter + + if hasattr(self, "table"): + table = self.table + else: + table = self._toOTTable(ttFont) + + writer = OTTableWriter(tableTag=self.tableTag) + table.compile(writer, ttFont) + return writer.getAllData() + + def toXML(self, writer, ttFont): + if hasattr(self, "table"): + self.table.toXML2(writer, ttFont) + else: + writer.simpletag("version", value=self.version) + writer.newline() + for baseGlyph in sorted(self.ColorLayers.keys(), key=ttFont.getGlyphID): + writer.begintag("ColorGlyph", name=baseGlyph) + writer.newline() + for layer in self.ColorLayers[baseGlyph]: + layer.toXML(writer, ttFont) + writer.endtag("ColorGlyph") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "version": # old COLR v0 API + setattr(self, name, safeEval(attrs["value"])) + elif name == "ColorGlyph": + if not hasattr(self, "ColorLayers"): + self.ColorLayers = {} + glyphName = attrs["name"] + for element in content: + if isinstance(element, str): + continue + layers = [] + for element in content: + if isinstance(element, str): + continue + layer = LayerRecord() + layer.fromXML(element[0], element[1], element[2], ttFont) + layers.append(layer) + self.ColorLayers[glyphName] = layers + else: # new COLR v1 API + from . import otTables + + if not hasattr(self, "table"): + tableClass = getattr(otTables, self.tableTag) + self.table = tableClass() + self.table.fromXML(name, attrs, content, ttFont) + self.table.populateDefaults() + self.version = self.table.Version + + def __getitem__(self, glyphName): + if not isinstance(glyphName, str): + raise TypeError(f"expected str, found {type(glyphName).__name__}") + return self.ColorLayers[glyphName] + + def __setitem__(self, glyphName, value): + if not isinstance(glyphName, str): + raise TypeError(f"expected str, found {type(glyphName).__name__}") + if value is not None: + self.ColorLayers[glyphName] = value + elif glyphName in self.ColorLayers: + del self.ColorLayers[glyphName] + + def __delitem__(self, glyphName): + del self.ColorLayers[glyphName] + + +class LayerRecord(object): + def __init__(self, name=None, colorID=None): + self.name = name + self.colorID = colorID + + def toXML(self, writer, ttFont): + writer.simpletag("layer", name=self.name, colorID=self.colorID) + writer.newline() + + def fromXML(self, eltname, attrs, content, ttFont): + for name, value in attrs.items(): + if name == "name": + setattr(self, name, value) + else: + setattr(self, name, safeEval(value)) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_P_A_L_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_P_A_L_.py new file mode 100644 index 0000000000000000000000000000000000000000..5ec8c843c516f2ac31bbbc9ff2dd0166a3a0e159 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/C_P_A_L_.py @@ -0,0 +1,305 @@ +# Copyright 2013 Google, Inc. All Rights Reserved. +# +# Google Author(s): Behdad Esfahbod + +from fontTools.misc.textTools import bytesjoin, safeEval +from . import DefaultTable +import array +from collections import namedtuple +import struct +import sys + + +class table_C_P_A_L_(DefaultTable.DefaultTable): + """Color Palette table + + The ``CPAL`` table contains a set of one or more color palettes. The color + records in each palette can be referenced by the ``COLR`` table to specify + the colors used in a color glyph. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/cpal + """ + + NO_NAME_ID = 0xFFFF + DEFAULT_PALETTE_TYPE = 0 + + def __init__(self, tag=None): + DefaultTable.DefaultTable.__init__(self, tag) + self.palettes = [] + self.paletteTypes = [] + self.paletteLabels = [] + self.paletteEntryLabels = [] + + def decompile(self, data, ttFont): + ( + self.version, + self.numPaletteEntries, + numPalettes, + numColorRecords, + goffsetFirstColorRecord, + ) = struct.unpack(">HHHHL", data[:12]) + assert ( + self.version <= 1 + ), "Version of CPAL table is higher than I know how to handle" + self.palettes = [] + pos = 12 + for i in range(numPalettes): + startIndex = struct.unpack(">H", data[pos : pos + 2])[0] + assert startIndex + self.numPaletteEntries <= numColorRecords + pos += 2 + palette = [] + ppos = goffsetFirstColorRecord + startIndex * 4 + for j in range(self.numPaletteEntries): + palette.append(Color(*struct.unpack(">BBBB", data[ppos : ppos + 4]))) + ppos += 4 + self.palettes.append(palette) + if self.version == 0: + offsetToPaletteTypeArray = 0 + offsetToPaletteLabelArray = 0 + offsetToPaletteEntryLabelArray = 0 + else: + pos = 12 + numPalettes * 2 + ( + offsetToPaletteTypeArray, + offsetToPaletteLabelArray, + offsetToPaletteEntryLabelArray, + ) = struct.unpack(">LLL", data[pos : pos + 12]) + self.paletteTypes = self._decompileUInt32Array( + data, + offsetToPaletteTypeArray, + numPalettes, + default=self.DEFAULT_PALETTE_TYPE, + ) + self.paletteLabels = self._decompileUInt16Array( + data, offsetToPaletteLabelArray, numPalettes, default=self.NO_NAME_ID + ) + self.paletteEntryLabels = self._decompileUInt16Array( + data, + offsetToPaletteEntryLabelArray, + self.numPaletteEntries, + default=self.NO_NAME_ID, + ) + + def _decompileUInt16Array(self, data, offset, numElements, default=0): + if offset == 0: + return [default] * numElements + result = array.array("H", data[offset : offset + 2 * numElements]) + if sys.byteorder != "big": + result.byteswap() + assert len(result) == numElements, result + return result.tolist() + + def _decompileUInt32Array(self, data, offset, numElements, default=0): + if offset == 0: + return [default] * numElements + result = array.array("I", data[offset : offset + 4 * numElements]) + if sys.byteorder != "big": + result.byteswap() + assert len(result) == numElements, result + return result.tolist() + + def compile(self, ttFont): + colorRecordIndices, colorRecords = self._compileColorRecords() + paletteTypes = self._compilePaletteTypes() + paletteLabels = self._compilePaletteLabels() + paletteEntryLabels = self._compilePaletteEntryLabels() + numColorRecords = len(colorRecords) // 4 + offsetToFirstColorRecord = 12 + len(colorRecordIndices) + if self.version >= 1: + offsetToFirstColorRecord += 12 + header = struct.pack( + ">HHHHL", + self.version, + self.numPaletteEntries, + len(self.palettes), + numColorRecords, + offsetToFirstColorRecord, + ) + if self.version == 0: + dataList = [header, colorRecordIndices, colorRecords] + else: + pos = offsetToFirstColorRecord + len(colorRecords) + if len(paletteTypes) == 0: + offsetToPaletteTypeArray = 0 + else: + offsetToPaletteTypeArray = pos + pos += len(paletteTypes) + if len(paletteLabels) == 0: + offsetToPaletteLabelArray = 0 + else: + offsetToPaletteLabelArray = pos + pos += len(paletteLabels) + if len(paletteEntryLabels) == 0: + offsetToPaletteEntryLabelArray = 0 + else: + offsetToPaletteEntryLabelArray = pos + pos += len(paletteLabels) + header1 = struct.pack( + ">LLL", + offsetToPaletteTypeArray, + offsetToPaletteLabelArray, + offsetToPaletteEntryLabelArray, + ) + dataList = [ + header, + colorRecordIndices, + header1, + colorRecords, + paletteTypes, + paletteLabels, + paletteEntryLabels, + ] + return bytesjoin(dataList) + + def _compilePalette(self, palette): + assert len(palette) == self.numPaletteEntries + pack = lambda c: struct.pack(">BBBB", c.blue, c.green, c.red, c.alpha) + return bytesjoin([pack(color) for color in palette]) + + def _compileColorRecords(self): + colorRecords, colorRecordIndices, pool = [], [], {} + for palette in self.palettes: + packedPalette = self._compilePalette(palette) + if packedPalette in pool: + index = pool[packedPalette] + else: + index = len(colorRecords) + colorRecords.append(packedPalette) + pool[packedPalette] = index + colorRecordIndices.append(struct.pack(">H", index * self.numPaletteEntries)) + return bytesjoin(colorRecordIndices), bytesjoin(colorRecords) + + def _compilePaletteTypes(self): + if self.version == 0 or not any(self.paletteTypes): + return b"" + assert len(self.paletteTypes) == len(self.palettes) + result = bytesjoin([struct.pack(">I", ptype) for ptype in self.paletteTypes]) + assert len(result) == 4 * len(self.palettes) + return result + + def _compilePaletteLabels(self): + if self.version == 0 or all(l == self.NO_NAME_ID for l in self.paletteLabels): + return b"" + assert len(self.paletteLabels) == len(self.palettes) + result = bytesjoin([struct.pack(">H", label) for label in self.paletteLabels]) + assert len(result) == 2 * len(self.palettes) + return result + + def _compilePaletteEntryLabels(self): + if self.version == 0 or all( + l == self.NO_NAME_ID for l in self.paletteEntryLabels + ): + return b"" + assert len(self.paletteEntryLabels) == self.numPaletteEntries + result = bytesjoin( + [struct.pack(">H", label) for label in self.paletteEntryLabels] + ) + assert len(result) == 2 * self.numPaletteEntries + return result + + def toXML(self, writer, ttFont): + numPalettes = len(self.palettes) + paletteLabels = {i: nameID for (i, nameID) in enumerate(self.paletteLabels)} + paletteTypes = {i: typ for (i, typ) in enumerate(self.paletteTypes)} + writer.simpletag("version", value=self.version) + writer.newline() + writer.simpletag("numPaletteEntries", value=self.numPaletteEntries) + writer.newline() + for index, palette in enumerate(self.palettes): + attrs = {"index": index} + paletteType = paletteTypes.get(index, self.DEFAULT_PALETTE_TYPE) + paletteLabel = paletteLabels.get(index, self.NO_NAME_ID) + if self.version > 0 and paletteLabel != self.NO_NAME_ID: + attrs["label"] = paletteLabel + if self.version > 0 and paletteType != self.DEFAULT_PALETTE_TYPE: + attrs["type"] = paletteType + writer.begintag("palette", **attrs) + writer.newline() + if ( + self.version > 0 + and paletteLabel != self.NO_NAME_ID + and ttFont + and "name" in ttFont + ): + name = ttFont["name"].getDebugName(paletteLabel) + if name is not None: + writer.comment(name) + writer.newline() + assert len(palette) == self.numPaletteEntries + for cindex, color in enumerate(palette): + color.toXML(writer, ttFont, cindex) + writer.endtag("palette") + writer.newline() + if self.version > 0 and not all( + l == self.NO_NAME_ID for l in self.paletteEntryLabels + ): + writer.begintag("paletteEntryLabels") + writer.newline() + for index, label in enumerate(self.paletteEntryLabels): + if label != self.NO_NAME_ID: + writer.simpletag("label", index=index, value=label) + if self.version > 0 and label and ttFont and "name" in ttFont: + name = ttFont["name"].getDebugName(label) + if name is not None: + writer.comment(name) + writer.newline() + writer.endtag("paletteEntryLabels") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "palette": + self.paletteLabels.append(int(attrs.get("label", self.NO_NAME_ID))) + self.paletteTypes.append(int(attrs.get("type", self.DEFAULT_PALETTE_TYPE))) + palette = [] + for element in content: + if isinstance(element, str): + continue + attrs = element[1] + color = Color.fromHex(attrs["value"]) + palette.append(color) + self.palettes.append(palette) + elif name == "paletteEntryLabels": + colorLabels = {} + for element in content: + if isinstance(element, str): + continue + elementName, elementAttr, _ = element + if elementName == "label": + labelIndex = safeEval(elementAttr["index"]) + nameID = safeEval(elementAttr["value"]) + colorLabels[labelIndex] = nameID + self.paletteEntryLabels = [ + colorLabels.get(i, self.NO_NAME_ID) + for i in range(self.numPaletteEntries) + ] + elif "value" in attrs: + value = safeEval(attrs["value"]) + setattr(self, name, value) + if name == "numPaletteEntries": + self.paletteEntryLabels = [self.NO_NAME_ID] * self.numPaletteEntries + + +class Color(namedtuple("Color", "blue green red alpha")): + def hex(self): + return "#%02X%02X%02X%02X" % (self.red, self.green, self.blue, self.alpha) + + def __repr__(self): + return self.hex() + + def toXML(self, writer, ttFont, index=None): + writer.simpletag("color", value=self.hex(), index=index) + writer.newline() + + @classmethod + def fromHex(cls, value): + if value[0] == "#": + value = value[1:] + red = int(value[0:2], 16) + green = int(value[2:4], 16) + blue = int(value[4:6], 16) + alpha = int(value[6:8], 16) if len(value) >= 8 else 0xFF + return cls(red=red, green=green, blue=blue, alpha=alpha) + + @classmethod + def fromRGBA(cls, red, green, blue, alpha): + return cls(red=red, green=green, blue=blue, alpha=alpha) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/D_S_I_G_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/D_S_I_G_.py new file mode 100644 index 0000000000000000000000000000000000000000..f89cc29e49f6be5e88ebf7b6daa0139a7c5d2ae2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/D_S_I_G_.py @@ -0,0 +1,158 @@ +from fontTools.misc.textTools import bytesjoin, strjoin, tobytes, tostr, safeEval +from fontTools.misc import sstruct +from . import DefaultTable +import base64 + +DSIG_HeaderFormat = """ + > # big endian + ulVersion: L + usNumSigs: H + usFlag: H +""" +# followed by an array of usNumSigs DSIG_Signature records +DSIG_SignatureFormat = """ + > # big endian + ulFormat: L + ulLength: L # length includes DSIG_SignatureBlock header + ulOffset: L +""" +# followed by an array of usNumSigs DSIG_SignatureBlock records, +# each followed immediately by the pkcs7 bytes +DSIG_SignatureBlockFormat = """ + > # big endian + usReserved1: H + usReserved2: H + cbSignature: l # length of following raw pkcs7 data +""" + +# +# NOTE +# the DSIG table format allows for SignatureBlocks residing +# anywhere in the table and possibly in a different order as +# listed in the array after the first table header +# +# this implementation does not keep track of any gaps and/or data +# before or after the actual signature blocks while decompiling, +# and puts them in the same physical order as listed in the header +# on compilation with no padding whatsoever. +# + + +class table_D_S_I_G_(DefaultTable.DefaultTable): + """Digital Signature table + + The ``DSIG`` table contains cryptographic signatures for the font. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/dsig + """ + + def decompile(self, data, ttFont): + dummy, newData = sstruct.unpack2(DSIG_HeaderFormat, data, self) + assert self.ulVersion == 1, "DSIG ulVersion must be 1" + assert self.usFlag & ~1 == 0, "DSIG usFlag must be 0x1 or 0x0" + self.signatureRecords = sigrecs = [] + for n in range(self.usNumSigs): + sigrec, newData = sstruct.unpack2( + DSIG_SignatureFormat, newData, SignatureRecord() + ) + assert sigrec.ulFormat == 1, ( + "DSIG signature record #%d ulFormat must be 1" % n + ) + sigrecs.append(sigrec) + for sigrec in sigrecs: + dummy, newData = sstruct.unpack2( + DSIG_SignatureBlockFormat, data[sigrec.ulOffset :], sigrec + ) + assert sigrec.usReserved1 == 0, ( + "DSIG signature record #%d usReserverd1 must be 0" % n + ) + assert sigrec.usReserved2 == 0, ( + "DSIG signature record #%d usReserverd2 must be 0" % n + ) + sigrec.pkcs7 = newData[: sigrec.cbSignature] + + def compile(self, ttFont): + packed = sstruct.pack(DSIG_HeaderFormat, self) + headers = [packed] + offset = len(packed) + self.usNumSigs * sstruct.calcsize(DSIG_SignatureFormat) + data = [] + for sigrec in self.signatureRecords: + # first pack signature block + sigrec.cbSignature = len(sigrec.pkcs7) + packed = sstruct.pack(DSIG_SignatureBlockFormat, sigrec) + sigrec.pkcs7 + data.append(packed) + # update redundant length field + sigrec.ulLength = len(packed) + # update running table offset + sigrec.ulOffset = offset + headers.append(sstruct.pack(DSIG_SignatureFormat, sigrec)) + offset += sigrec.ulLength + if offset % 2: + # Pad to even bytes + data.append(b"\0") + return bytesjoin(headers + data) + + def toXML(self, xmlWriter, ttFont): + xmlWriter.comment( + "note that the Digital Signature will be invalid after recompilation!" + ) + xmlWriter.newline() + xmlWriter.simpletag( + "tableHeader", + version=self.ulVersion, + numSigs=self.usNumSigs, + flag="0x%X" % self.usFlag, + ) + for sigrec in self.signatureRecords: + xmlWriter.newline() + sigrec.toXML(xmlWriter, ttFont) + xmlWriter.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "tableHeader": + self.signatureRecords = [] + self.ulVersion = safeEval(attrs["version"]) + self.usNumSigs = safeEval(attrs["numSigs"]) + self.usFlag = safeEval(attrs["flag"]) + return + if name == "SignatureRecord": + sigrec = SignatureRecord() + sigrec.fromXML(name, attrs, content, ttFont) + self.signatureRecords.append(sigrec) + + +pem_spam = lambda l, spam={ + "-----BEGIN PKCS7-----": True, + "-----END PKCS7-----": True, + "": True, +}: not spam.get(l.strip()) + + +def b64encode(b): + s = base64.b64encode(b) + # Line-break at 76 chars. + items = [] + while s: + items.append(tostr(s[:76])) + items.append("\n") + s = s[76:] + return strjoin(items) + + +class SignatureRecord(object): + def __repr__(self): + return "<%s: %s>" % (self.__class__.__name__, self.__dict__) + + def toXML(self, writer, ttFont): + writer.begintag(self.__class__.__name__, format=self.ulFormat) + writer.newline() + writer.write_noindent("-----BEGIN PKCS7-----\n") + writer.write_noindent(b64encode(self.pkcs7)) + writer.write_noindent("-----END PKCS7-----\n") + writer.endtag(self.__class__.__name__) + + def fromXML(self, name, attrs, content, ttFont): + self.ulFormat = safeEval(attrs["format"]) + self.usReserved1 = safeEval(attrs.get("reserved1", "0")) + self.usReserved2 = safeEval(attrs.get("reserved2", "0")) + self.pkcs7 = base64.b64decode(tobytes(strjoin(filter(pem_spam, content)))) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/D__e_b_g.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/D__e_b_g.py new file mode 100644 index 0000000000000000000000000000000000000000..cb1653d79d4f99ad729b25c96346459c40a4681e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/D__e_b_g.py @@ -0,0 +1,35 @@ +import json +from textwrap import indent + +from . import DefaultTable +from fontTools.misc.textTools import tostr + + +class table_D__e_b_g(DefaultTable.DefaultTable): + def __init__(self, tag=None): + DefaultTable.DefaultTable.__init__(self, tag) + self.data = {} + + def decompile(self, data, ttFont): + self.data = json.loads(data) + + def compile(self, ttFont): + return json.dumps(self.data).encode("utf-8") + + def toXML(self, writer, ttFont): + # make sure json indentation inside CDATA block matches XMLWriter's + data = json.dumps(self.data, indent=len(writer.indentwhite)) + prefix = tostr(writer.indentwhite) * (writer.indentlevel + 1) + # but don't indent the first json line so it's adjacent to `" % (self.tableTag, id(self)) + + def __eq__(self, other): + if type(self) != type(other): + return NotImplemented + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + result = self.__eq__(other) + return result if result is NotImplemented else not result diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/E_B_D_T_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/E_B_D_T_.py new file mode 100644 index 0000000000000000000000000000000000000000..ea23e30f83d38f77587f29cf40b3eec41f715be7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/E_B_D_T_.py @@ -0,0 +1,835 @@ +from fontTools.misc import sstruct +from fontTools.misc.textTools import ( + bytechr, + byteord, + bytesjoin, + strjoin, + safeEval, + readHex, + hexStr, + deHexStr, +) +from .BitmapGlyphMetrics import ( + BigGlyphMetrics, + bigGlyphMetricsFormat, + SmallGlyphMetrics, + smallGlyphMetricsFormat, +) +from . import DefaultTable +import itertools +import os +import struct +import logging + + +log = logging.getLogger(__name__) + +ebdtTableVersionFormat = """ + > # big endian + version: 16.16F +""" + +ebdtComponentFormat = """ + > # big endian + glyphCode: H + xOffset: b + yOffset: b +""" + + +class table_E_B_D_T_(DefaultTable.DefaultTable): + """Embedded Bitmap Data table + + The ``EBDT`` table contains monochrome or grayscale bitmap data for + glyphs. It must be used in concert with the ``EBLC`` table. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/ebdt + """ + + # Keep a reference to the name of the data locator table. + locatorName = "EBLC" + + # This method can be overridden in subclasses to support new formats + # without changing the other implementation. Also can be used as a + # convenience method for coverting a font file to an alternative format. + def getImageFormatClass(self, imageFormat): + return ebdt_bitmap_classes[imageFormat] + + def decompile(self, data, ttFont): + # Get the version but don't advance the slice. + # Most of the lookup for this table is done relative + # to the begining so slice by the offsets provided + # in the EBLC table. + sstruct.unpack2(ebdtTableVersionFormat, data, self) + + # Keep a dict of glyphs that have been seen so they aren't remade. + # This dict maps intervals of data to the BitmapGlyph. + glyphDict = {} + + # Pull out the EBLC table and loop through glyphs. + # A strike is a concept that spans both tables. + # The actual bitmap data is stored in the EBDT. + locator = ttFont[self.__class__.locatorName] + self.strikeData = [] + for curStrike in locator.strikes: + bitmapGlyphDict = {} + self.strikeData.append(bitmapGlyphDict) + for indexSubTable in curStrike.indexSubTables: + dataIter = zip(indexSubTable.names, indexSubTable.locations) + for curName, curLoc in dataIter: + # Don't create duplicate data entries for the same glyphs. + # Instead just use the structures that already exist if they exist. + if curLoc in glyphDict: + curGlyph = glyphDict[curLoc] + else: + curGlyphData = data[slice(*curLoc)] + imageFormatClass = self.getImageFormatClass( + indexSubTable.imageFormat + ) + curGlyph = imageFormatClass(curGlyphData, ttFont) + glyphDict[curLoc] = curGlyph + bitmapGlyphDict[curName] = curGlyph + + def compile(self, ttFont): + dataList = [] + dataList.append(sstruct.pack(ebdtTableVersionFormat, self)) + dataSize = len(dataList[0]) + + # Keep a dict of glyphs that have been seen so they aren't remade. + # This dict maps the id of the BitmapGlyph to the interval + # in the data. + glyphDict = {} + + # Go through the bitmap glyph data. Just in case the data for a glyph + # changed the size metrics should be recalculated. There are a variety + # of formats and they get stored in the EBLC table. That is why + # recalculation is defered to the EblcIndexSubTable class and just + # pass what is known about bitmap glyphs from this particular table. + locator = ttFont[self.__class__.locatorName] + for curStrike, curGlyphDict in zip(locator.strikes, self.strikeData): + for curIndexSubTable in curStrike.indexSubTables: + dataLocations = [] + for curName in curIndexSubTable.names: + # Handle the data placement based on seeing the glyph or not. + # Just save a reference to the location if the glyph has already + # been saved in compile. This code assumes that glyphs will only + # be referenced multiple times from indexFormat5. By luck the + # code may still work when referencing poorly ordered fonts with + # duplicate references. If there is a font that is unlucky the + # respective compile methods for the indexSubTables will fail + # their assertions. All fonts seem to follow this assumption. + # More complicated packing may be needed if a counter-font exists. + glyph = curGlyphDict[curName] + objectId = id(glyph) + if objectId not in glyphDict: + data = glyph.compile(ttFont) + data = curIndexSubTable.padBitmapData(data) + startByte = dataSize + dataSize += len(data) + endByte = dataSize + dataList.append(data) + dataLoc = (startByte, endByte) + glyphDict[objectId] = dataLoc + else: + dataLoc = glyphDict[objectId] + dataLocations.append(dataLoc) + # Just use the new data locations in the indexSubTable. + # The respective compile implementations will take care + # of any of the problems in the convertion that may arise. + curIndexSubTable.locations = dataLocations + + return bytesjoin(dataList) + + def toXML(self, writer, ttFont): + # When exporting to XML if one of the data export formats + # requires metrics then those metrics may be in the locator. + # In this case populate the bitmaps with "export metrics". + if ttFont.bitmapGlyphDataFormat in ("row", "bitwise"): + locator = ttFont[self.__class__.locatorName] + for curStrike, curGlyphDict in zip(locator.strikes, self.strikeData): + for curIndexSubTable in curStrike.indexSubTables: + for curName in curIndexSubTable.names: + glyph = curGlyphDict[curName] + # I'm not sure which metrics have priority here. + # For now if both metrics exist go with glyph metrics. + if hasattr(glyph, "metrics"): + glyph.exportMetrics = glyph.metrics + else: + glyph.exportMetrics = curIndexSubTable.metrics + glyph.exportBitDepth = curStrike.bitmapSizeTable.bitDepth + + writer.simpletag("header", [("version", self.version)]) + writer.newline() + locator = ttFont[self.__class__.locatorName] + for strikeIndex, bitmapGlyphDict in enumerate(self.strikeData): + writer.begintag("strikedata", [("index", strikeIndex)]) + writer.newline() + for curName, curBitmap in bitmapGlyphDict.items(): + curBitmap.toXML(strikeIndex, curName, writer, ttFont) + writer.endtag("strikedata") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "header": + self.version = safeEval(attrs["version"]) + elif name == "strikedata": + if not hasattr(self, "strikeData"): + self.strikeData = [] + strikeIndex = safeEval(attrs["index"]) + + bitmapGlyphDict = {} + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name[4:].startswith(_bitmapGlyphSubclassPrefix[4:]): + imageFormat = safeEval(name[len(_bitmapGlyphSubclassPrefix) :]) + glyphName = attrs["name"] + imageFormatClass = self.getImageFormatClass(imageFormat) + curGlyph = imageFormatClass(None, None) + curGlyph.fromXML(name, attrs, content, ttFont) + assert glyphName not in bitmapGlyphDict, ( + "Duplicate glyphs with the same name '%s' in the same strike." + % glyphName + ) + bitmapGlyphDict[glyphName] = curGlyph + else: + log.warning("%s being ignored by %s", name, self.__class__.__name__) + + # Grow the strike data array to the appropriate size. The XML + # format allows the strike index value to be out of order. + if strikeIndex >= len(self.strikeData): + self.strikeData += [None] * (strikeIndex + 1 - len(self.strikeData)) + assert ( + self.strikeData[strikeIndex] is None + ), "Duplicate strike EBDT indices." + self.strikeData[strikeIndex] = bitmapGlyphDict + + +class EbdtComponent(object): + def toXML(self, writer, ttFont): + writer.begintag("ebdtComponent", [("name", self.name)]) + writer.newline() + for componentName in sstruct.getformat(ebdtComponentFormat)[1][1:]: + writer.simpletag(componentName, value=getattr(self, componentName)) + writer.newline() + writer.endtag("ebdtComponent") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + self.name = attrs["name"] + componentNames = set(sstruct.getformat(ebdtComponentFormat)[1][1:]) + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name in componentNames: + vars(self)[name] = safeEval(attrs["value"]) + else: + log.warning("unknown name '%s' being ignored by EbdtComponent.", name) + + +# Helper functions for dealing with binary. + + +def _data2binary(data, numBits): + binaryList = [] + for curByte in data: + value = byteord(curByte) + numBitsCut = min(8, numBits) + for i in range(numBitsCut): + if value & 0x1: + binaryList.append("1") + else: + binaryList.append("0") + value = value >> 1 + numBits -= numBitsCut + return strjoin(binaryList) + + +def _binary2data(binary): + byteList = [] + for bitLoc in range(0, len(binary), 8): + byteString = binary[bitLoc : bitLoc + 8] + curByte = 0 + for curBit in reversed(byteString): + curByte = curByte << 1 + if curBit == "1": + curByte |= 1 + byteList.append(bytechr(curByte)) + return bytesjoin(byteList) + + +def _memoize(f): + class memodict(dict): + def __missing__(self, key): + ret = f(key) + if isinstance(key, int) or len(key) == 1: + self[key] = ret + return ret + + return memodict().__getitem__ + + +# 00100111 -> 11100100 per byte, not to be confused with little/big endian. +# Bitmap data per byte is in the order that binary is written on the page +# with the least significant bit as far right as possible. This is the +# opposite of what makes sense algorithmically and hence this function. +@_memoize +def _reverseBytes(data): + r""" + >>> bin(ord(_reverseBytes(0b00100111))) + '0b11100100' + >>> _reverseBytes(b'\x00\xf0') + b'\x00\x0f' + """ + if isinstance(data, bytes) and len(data) != 1: + return bytesjoin(map(_reverseBytes, data)) + byte = byteord(data) + result = 0 + for i in range(8): + result = result << 1 + result |= byte & 1 + byte = byte >> 1 + return bytechr(result) + + +# This section of code is for reading and writing image data to/from XML. + + +def _writeRawImageData(strikeIndex, glyphName, bitmapObject, writer, ttFont): + writer.begintag("rawimagedata") + writer.newline() + writer.dumphex(bitmapObject.imageData) + writer.endtag("rawimagedata") + writer.newline() + + +def _readRawImageData(bitmapObject, name, attrs, content, ttFont): + bitmapObject.imageData = readHex(content) + + +def _writeRowImageData(strikeIndex, glyphName, bitmapObject, writer, ttFont): + metrics = bitmapObject.exportMetrics + del bitmapObject.exportMetrics + bitDepth = bitmapObject.exportBitDepth + del bitmapObject.exportBitDepth + + writer.begintag( + "rowimagedata", bitDepth=bitDepth, width=metrics.width, height=metrics.height + ) + writer.newline() + for curRow in range(metrics.height): + rowData = bitmapObject.getRow(curRow, bitDepth=bitDepth, metrics=metrics) + writer.simpletag("row", value=hexStr(rowData)) + writer.newline() + writer.endtag("rowimagedata") + writer.newline() + + +def _readRowImageData(bitmapObject, name, attrs, content, ttFont): + bitDepth = safeEval(attrs["bitDepth"]) + metrics = SmallGlyphMetrics() + metrics.width = safeEval(attrs["width"]) + metrics.height = safeEval(attrs["height"]) + + dataRows = [] + for element in content: + if not isinstance(element, tuple): + continue + name, attr, content = element + # Chop off 'imagedata' from the tag to get just the option. + if name == "row": + dataRows.append(deHexStr(attr["value"])) + bitmapObject.setRows(dataRows, bitDepth=bitDepth, metrics=metrics) + + +def _writeBitwiseImageData(strikeIndex, glyphName, bitmapObject, writer, ttFont): + metrics = bitmapObject.exportMetrics + del bitmapObject.exportMetrics + bitDepth = bitmapObject.exportBitDepth + del bitmapObject.exportBitDepth + + # A dict for mapping binary to more readable/artistic ASCII characters. + binaryConv = {"0": ".", "1": "@"} + + writer.begintag( + "bitwiseimagedata", + bitDepth=bitDepth, + width=metrics.width, + height=metrics.height, + ) + writer.newline() + for curRow in range(metrics.height): + rowData = bitmapObject.getRow( + curRow, bitDepth=1, metrics=metrics, reverseBytes=True + ) + rowData = _data2binary(rowData, metrics.width) + # Make the output a readable ASCII art form. + rowData = strjoin(map(binaryConv.get, rowData)) + writer.simpletag("row", value=rowData) + writer.newline() + writer.endtag("bitwiseimagedata") + writer.newline() + + +def _readBitwiseImageData(bitmapObject, name, attrs, content, ttFont): + bitDepth = safeEval(attrs["bitDepth"]) + metrics = SmallGlyphMetrics() + metrics.width = safeEval(attrs["width"]) + metrics.height = safeEval(attrs["height"]) + + # A dict for mapping from ASCII to binary. All characters are considered + # a '1' except space, period and '0' which maps to '0'. + binaryConv = {" ": "0", ".": "0", "0": "0"} + + dataRows = [] + for element in content: + if not isinstance(element, tuple): + continue + name, attr, content = element + if name == "row": + mapParams = zip(attr["value"], itertools.repeat("1")) + rowData = strjoin(itertools.starmap(binaryConv.get, mapParams)) + dataRows.append(_binary2data(rowData)) + + bitmapObject.setRows( + dataRows, bitDepth=bitDepth, metrics=metrics, reverseBytes=True + ) + + +def _writeExtFileImageData(strikeIndex, glyphName, bitmapObject, writer, ttFont): + try: + folder = os.path.dirname(writer.file.name) + except AttributeError: + # fall back to current directory if output file's directory isn't found + folder = "." + folder = os.path.join(folder, "bitmaps") + filename = glyphName + bitmapObject.fileExtension + if not os.path.isdir(folder): + os.makedirs(folder) + folder = os.path.join(folder, "strike%d" % strikeIndex) + if not os.path.isdir(folder): + os.makedirs(folder) + + fullPath = os.path.join(folder, filename) + writer.simpletag("extfileimagedata", value=fullPath) + writer.newline() + + with open(fullPath, "wb") as file: + file.write(bitmapObject.imageData) + + +def _readExtFileImageData(bitmapObject, name, attrs, content, ttFont): + fullPath = attrs["value"] + with open(fullPath, "rb") as file: + bitmapObject.imageData = file.read() + + +# End of XML writing code. + +# Important information about the naming scheme. Used for identifying formats +# in XML. +_bitmapGlyphSubclassPrefix = "ebdt_bitmap_format_" + + +class BitmapGlyph(object): + # For the external file format. This can be changed in subclasses. This way + # when the extfile option is turned on files have the form: glyphName.ext + # The default is just a flat binary file with no meaning. + fileExtension = ".bin" + + # Keep track of reading and writing of various forms. + xmlDataFunctions = { + "raw": (_writeRawImageData, _readRawImageData), + "row": (_writeRowImageData, _readRowImageData), + "bitwise": (_writeBitwiseImageData, _readBitwiseImageData), + "extfile": (_writeExtFileImageData, _readExtFileImageData), + } + + def __init__(self, data, ttFont): + self.data = data + self.ttFont = ttFont + # TODO Currently non-lazy decompilation is untested here... + # if not ttFont.lazy: + # self.decompile() + # del self.data + + def __getattr__(self, attr): + # Allow lazy decompile. + if attr[:2] == "__": + raise AttributeError(attr) + if attr == "data": + raise AttributeError(attr) + self.decompile() + del self.data + return getattr(self, attr) + + def ensureDecompiled(self, recurse=False): + if hasattr(self, "data"): + self.decompile() + del self.data + + # Not a fan of this but it is needed for safer safety checking. + def getFormat(self): + return safeEval(self.__class__.__name__[len(_bitmapGlyphSubclassPrefix) :]) + + def toXML(self, strikeIndex, glyphName, writer, ttFont): + writer.begintag(self.__class__.__name__, [("name", glyphName)]) + writer.newline() + + self.writeMetrics(writer, ttFont) + # Use the internal write method to write using the correct output format. + self.writeData(strikeIndex, glyphName, writer, ttFont) + + writer.endtag(self.__class__.__name__) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + self.readMetrics(name, attrs, content, ttFont) + for element in content: + if not isinstance(element, tuple): + continue + name, attr, content = element + if not name.endswith("imagedata"): + continue + # Chop off 'imagedata' from the tag to get just the option. + option = name[: -len("imagedata")] + assert option in self.__class__.xmlDataFunctions + self.readData(name, attr, content, ttFont) + + # Some of the glyphs have the metrics. This allows for metrics to be + # added if the glyph format has them. Default behavior is to do nothing. + def writeMetrics(self, writer, ttFont): + pass + + # The opposite of write metrics. + def readMetrics(self, name, attrs, content, ttFont): + pass + + def writeData(self, strikeIndex, glyphName, writer, ttFont): + try: + writeFunc, readFunc = self.__class__.xmlDataFunctions[ + ttFont.bitmapGlyphDataFormat + ] + except KeyError: + writeFunc = _writeRawImageData + writeFunc(strikeIndex, glyphName, self, writer, ttFont) + + def readData(self, name, attrs, content, ttFont): + # Chop off 'imagedata' from the tag to get just the option. + option = name[: -len("imagedata")] + writeFunc, readFunc = self.__class__.xmlDataFunctions[option] + readFunc(self, name, attrs, content, ttFont) + + +# A closure for creating a mixin for the two types of metrics handling. +# Most of the code is very similar so its easier to deal with here. +# Everything works just by passing the class that the mixin is for. +def _createBitmapPlusMetricsMixin(metricsClass): + # Both metrics names are listed here to make meaningful error messages. + metricStrings = [BigGlyphMetrics.__name__, SmallGlyphMetrics.__name__] + curMetricsName = metricsClass.__name__ + # Find which metrics this is for and determine the opposite name. + metricsId = metricStrings.index(curMetricsName) + oppositeMetricsName = metricStrings[1 - metricsId] + + class BitmapPlusMetricsMixin(object): + def writeMetrics(self, writer, ttFont): + self.metrics.toXML(writer, ttFont) + + def readMetrics(self, name, attrs, content, ttFont): + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name == curMetricsName: + self.metrics = metricsClass() + self.metrics.fromXML(name, attrs, content, ttFont) + elif name == oppositeMetricsName: + log.warning( + "Warning: %s being ignored in format %d.", + oppositeMetricsName, + self.getFormat(), + ) + + return BitmapPlusMetricsMixin + + +# Since there are only two types of mixin's just create them here. +BitmapPlusBigMetricsMixin = _createBitmapPlusMetricsMixin(BigGlyphMetrics) +BitmapPlusSmallMetricsMixin = _createBitmapPlusMetricsMixin(SmallGlyphMetrics) + + +# Data that is bit aligned can be tricky to deal with. These classes implement +# helper functionality for dealing with the data and getting a particular row +# of bitwise data. Also helps implement fancy data export/import in XML. +class BitAlignedBitmapMixin(object): + def _getBitRange(self, row, bitDepth, metrics): + rowBits = bitDepth * metrics.width + bitOffset = row * rowBits + return (bitOffset, bitOffset + rowBits) + + def getRow(self, row, bitDepth=1, metrics=None, reverseBytes=False): + if metrics is None: + metrics = self.metrics + assert 0 <= row and row < metrics.height, "Illegal row access in bitmap" + + # Loop through each byte. This can cover two bytes in the original data or + # a single byte if things happen to be aligned. The very last entry might + # not be aligned so take care to trim the binary data to size and pad with + # zeros in the row data. Bit aligned data is somewhat tricky. + # + # Example of data cut. Data cut represented in x's. + # '|' represents byte boundary. + # data = ...0XX|XXXXXX00|000... => XXXXXXXX + # or + # data = ...0XX|XXXX0000|000... => XXXXXX00 + # or + # data = ...000|XXXXXXXX|000... => XXXXXXXX + # or + # data = ...000|00XXXX00|000... => XXXX0000 + # + dataList = [] + bitRange = self._getBitRange(row, bitDepth, metrics) + stepRange = bitRange + (8,) + for curBit in range(*stepRange): + endBit = min(curBit + 8, bitRange[1]) + numBits = endBit - curBit + cutPoint = curBit % 8 + firstByteLoc = curBit // 8 + secondByteLoc = endBit // 8 + if firstByteLoc < secondByteLoc: + numBitsCut = 8 - cutPoint + else: + numBitsCut = endBit - curBit + curByte = _reverseBytes(self.imageData[firstByteLoc]) + firstHalf = byteord(curByte) >> cutPoint + firstHalf = ((1 << numBitsCut) - 1) & firstHalf + newByte = firstHalf + if firstByteLoc < secondByteLoc and secondByteLoc < len(self.imageData): + curByte = _reverseBytes(self.imageData[secondByteLoc]) + secondHalf = byteord(curByte) << numBitsCut + newByte = (firstHalf | secondHalf) & ((1 << numBits) - 1) + dataList.append(bytechr(newByte)) + + # The way the data is kept is opposite the algorithm used. + data = bytesjoin(dataList) + if not reverseBytes: + data = _reverseBytes(data) + return data + + def setRows(self, dataRows, bitDepth=1, metrics=None, reverseBytes=False): + if metrics is None: + metrics = self.metrics + if not reverseBytes: + dataRows = list(map(_reverseBytes, dataRows)) + + # Keep track of a list of ordinal values as they are easier to modify + # than a list of strings. Map to actual strings later. + numBytes = (self._getBitRange(len(dataRows), bitDepth, metrics)[0] + 7) // 8 + ordDataList = [0] * numBytes + for row, data in enumerate(dataRows): + bitRange = self._getBitRange(row, bitDepth, metrics) + stepRange = bitRange + (8,) + for curBit, curByte in zip(range(*stepRange), data): + endBit = min(curBit + 8, bitRange[1]) + cutPoint = curBit % 8 + firstByteLoc = curBit // 8 + secondByteLoc = endBit // 8 + if firstByteLoc < secondByteLoc: + numBitsCut = 8 - cutPoint + else: + numBitsCut = endBit - curBit + curByte = byteord(curByte) + firstByte = curByte & ((1 << numBitsCut) - 1) + ordDataList[firstByteLoc] |= firstByte << cutPoint + if firstByteLoc < secondByteLoc and secondByteLoc < numBytes: + secondByte = (curByte >> numBitsCut) & ((1 << 8 - numBitsCut) - 1) + ordDataList[secondByteLoc] |= secondByte + + # Save the image data with the bits going the correct way. + self.imageData = _reverseBytes(bytesjoin(map(bytechr, ordDataList))) + + +class ByteAlignedBitmapMixin(object): + def _getByteRange(self, row, bitDepth, metrics): + rowBytes = (bitDepth * metrics.width + 7) // 8 + byteOffset = row * rowBytes + return (byteOffset, byteOffset + rowBytes) + + def getRow(self, row, bitDepth=1, metrics=None, reverseBytes=False): + if metrics is None: + metrics = self.metrics + assert 0 <= row and row < metrics.height, "Illegal row access in bitmap" + byteRange = self._getByteRange(row, bitDepth, metrics) + data = self.imageData[slice(*byteRange)] + if reverseBytes: + data = _reverseBytes(data) + return data + + def setRows(self, dataRows, bitDepth=1, metrics=None, reverseBytes=False): + if metrics is None: + metrics = self.metrics + if reverseBytes: + dataRows = map(_reverseBytes, dataRows) + self.imageData = bytesjoin(dataRows) + + +class ebdt_bitmap_format_1( + ByteAlignedBitmapMixin, BitmapPlusSmallMetricsMixin, BitmapGlyph +): + def decompile(self): + self.metrics = SmallGlyphMetrics() + dummy, data = sstruct.unpack2(smallGlyphMetricsFormat, self.data, self.metrics) + self.imageData = data + + def compile(self, ttFont): + data = sstruct.pack(smallGlyphMetricsFormat, self.metrics) + return data + self.imageData + + +class ebdt_bitmap_format_2( + BitAlignedBitmapMixin, BitmapPlusSmallMetricsMixin, BitmapGlyph +): + def decompile(self): + self.metrics = SmallGlyphMetrics() + dummy, data = sstruct.unpack2(smallGlyphMetricsFormat, self.data, self.metrics) + self.imageData = data + + def compile(self, ttFont): + data = sstruct.pack(smallGlyphMetricsFormat, self.metrics) + return data + self.imageData + + +class ebdt_bitmap_format_5(BitAlignedBitmapMixin, BitmapGlyph): + def decompile(self): + self.imageData = self.data + + def compile(self, ttFont): + return self.imageData + + +class ebdt_bitmap_format_6( + ByteAlignedBitmapMixin, BitmapPlusBigMetricsMixin, BitmapGlyph +): + def decompile(self): + self.metrics = BigGlyphMetrics() + dummy, data = sstruct.unpack2(bigGlyphMetricsFormat, self.data, self.metrics) + self.imageData = data + + def compile(self, ttFont): + data = sstruct.pack(bigGlyphMetricsFormat, self.metrics) + return data + self.imageData + + +class ebdt_bitmap_format_7( + BitAlignedBitmapMixin, BitmapPlusBigMetricsMixin, BitmapGlyph +): + def decompile(self): + self.metrics = BigGlyphMetrics() + dummy, data = sstruct.unpack2(bigGlyphMetricsFormat, self.data, self.metrics) + self.imageData = data + + def compile(self, ttFont): + data = sstruct.pack(bigGlyphMetricsFormat, self.metrics) + return data + self.imageData + + +class ComponentBitmapGlyph(BitmapGlyph): + def toXML(self, strikeIndex, glyphName, writer, ttFont): + writer.begintag(self.__class__.__name__, [("name", glyphName)]) + writer.newline() + + self.writeMetrics(writer, ttFont) + + writer.begintag("components") + writer.newline() + for curComponent in self.componentArray: + curComponent.toXML(writer, ttFont) + writer.endtag("components") + writer.newline() + + writer.endtag(self.__class__.__name__) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + self.readMetrics(name, attrs, content, ttFont) + for element in content: + if not isinstance(element, tuple): + continue + name, attr, content = element + if name == "components": + self.componentArray = [] + for compElement in content: + if not isinstance(compElement, tuple): + continue + name, attrs, content = compElement + if name == "ebdtComponent": + curComponent = EbdtComponent() + curComponent.fromXML(name, attrs, content, ttFont) + self.componentArray.append(curComponent) + else: + log.warning("'%s' being ignored in component array.", name) + + +class ebdt_bitmap_format_8(BitmapPlusSmallMetricsMixin, ComponentBitmapGlyph): + def decompile(self): + self.metrics = SmallGlyphMetrics() + dummy, data = sstruct.unpack2(smallGlyphMetricsFormat, self.data, self.metrics) + data = data[1:] + + (numComponents,) = struct.unpack(">H", data[:2]) + data = data[2:] + self.componentArray = [] + for i in range(numComponents): + curComponent = EbdtComponent() + dummy, data = sstruct.unpack2(ebdtComponentFormat, data, curComponent) + curComponent.name = self.ttFont.getGlyphName(curComponent.glyphCode) + self.componentArray.append(curComponent) + + def compile(self, ttFont): + dataList = [] + dataList.append(sstruct.pack(smallGlyphMetricsFormat, self.metrics)) + dataList.append(b"\0") + dataList.append(struct.pack(">H", len(self.componentArray))) + for curComponent in self.componentArray: + curComponent.glyphCode = ttFont.getGlyphID(curComponent.name) + dataList.append(sstruct.pack(ebdtComponentFormat, curComponent)) + return bytesjoin(dataList) + + +class ebdt_bitmap_format_9(BitmapPlusBigMetricsMixin, ComponentBitmapGlyph): + def decompile(self): + self.metrics = BigGlyphMetrics() + dummy, data = sstruct.unpack2(bigGlyphMetricsFormat, self.data, self.metrics) + (numComponents,) = struct.unpack(">H", data[:2]) + data = data[2:] + self.componentArray = [] + for i in range(numComponents): + curComponent = EbdtComponent() + dummy, data = sstruct.unpack2(ebdtComponentFormat, data, curComponent) + curComponent.name = self.ttFont.getGlyphName(curComponent.glyphCode) + self.componentArray.append(curComponent) + + def compile(self, ttFont): + dataList = [] + dataList.append(sstruct.pack(bigGlyphMetricsFormat, self.metrics)) + dataList.append(struct.pack(">H", len(self.componentArray))) + for curComponent in self.componentArray: + curComponent.glyphCode = ttFont.getGlyphID(curComponent.name) + dataList.append(sstruct.pack(ebdtComponentFormat, curComponent)) + return bytesjoin(dataList) + + +# Dictionary of bitmap formats to the class representing that format +# currently only the ones listed in this map are the ones supported. +ebdt_bitmap_classes = { + 1: ebdt_bitmap_format_1, + 2: ebdt_bitmap_format_2, + 5: ebdt_bitmap_format_5, + 6: ebdt_bitmap_format_6, + 7: ebdt_bitmap_format_7, + 8: ebdt_bitmap_format_8, + 9: ebdt_bitmap_format_9, +} diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/E_B_L_C_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/E_B_L_C_.py new file mode 100644 index 0000000000000000000000000000000000000000..ff93aa8cf67de480419dbe66b7a4702114cddfd9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/E_B_L_C_.py @@ -0,0 +1,718 @@ +from fontTools.misc import sstruct +from . import DefaultTable +from fontTools.misc.textTools import bytesjoin, safeEval +from .BitmapGlyphMetrics import ( + BigGlyphMetrics, + bigGlyphMetricsFormat, + SmallGlyphMetrics, + smallGlyphMetricsFormat, +) +import struct +import itertools +from collections import deque +import logging + + +log = logging.getLogger(__name__) + +eblcHeaderFormat = """ + > # big endian + version: 16.16F + numSizes: I +""" +# The table format string is split to handle sbitLineMetrics simply. +bitmapSizeTableFormatPart1 = """ + > # big endian + indexSubTableArrayOffset: I + indexTablesSize: I + numberOfIndexSubTables: I + colorRef: I +""" +# The compound type for hori and vert. +sbitLineMetricsFormat = """ + > # big endian + ascender: b + descender: b + widthMax: B + caretSlopeNumerator: b + caretSlopeDenominator: b + caretOffset: b + minOriginSB: b + minAdvanceSB: b + maxBeforeBL: b + minAfterBL: b + pad1: b + pad2: b +""" +# hori and vert go between the two parts. +bitmapSizeTableFormatPart2 = """ + > # big endian + startGlyphIndex: H + endGlyphIndex: H + ppemX: B + ppemY: B + bitDepth: B + flags: b +""" + +indexSubTableArrayFormat = ">HHL" +indexSubTableArraySize = struct.calcsize(indexSubTableArrayFormat) + +indexSubHeaderFormat = ">HHL" +indexSubHeaderSize = struct.calcsize(indexSubHeaderFormat) + +codeOffsetPairFormat = ">HH" +codeOffsetPairSize = struct.calcsize(codeOffsetPairFormat) + + +class table_E_B_L_C_(DefaultTable.DefaultTable): + """Embedded Bitmap Location table + + The ``EBLC`` table contains the locations of monochrome or grayscale + bitmaps for glyphs. It must be used in concert with the ``EBDT`` table. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/eblc + """ + + dependencies = ["EBDT"] + + # This method can be overridden in subclasses to support new formats + # without changing the other implementation. Also can be used as a + # convenience method for coverting a font file to an alternative format. + def getIndexFormatClass(self, indexFormat): + return eblc_sub_table_classes[indexFormat] + + def decompile(self, data, ttFont): + # Save the original data because offsets are from the start of the table. + origData = data + i = 0 + + dummy = sstruct.unpack(eblcHeaderFormat, data[:8], self) + i += 8 + + self.strikes = [] + for curStrikeIndex in range(self.numSizes): + curStrike = Strike() + self.strikes.append(curStrike) + curTable = curStrike.bitmapSizeTable + dummy = sstruct.unpack2( + bitmapSizeTableFormatPart1, data[i : i + 16], curTable + ) + i += 16 + for metric in ("hori", "vert"): + metricObj = SbitLineMetrics() + vars(curTable)[metric] = metricObj + dummy = sstruct.unpack2( + sbitLineMetricsFormat, data[i : i + 12], metricObj + ) + i += 12 + dummy = sstruct.unpack( + bitmapSizeTableFormatPart2, data[i : i + 8], curTable + ) + i += 8 + + for curStrike in self.strikes: + curTable = curStrike.bitmapSizeTable + for subtableIndex in range(curTable.numberOfIndexSubTables): + i = ( + curTable.indexSubTableArrayOffset + + subtableIndex * indexSubTableArraySize + ) + + tup = struct.unpack( + indexSubTableArrayFormat, data[i : i + indexSubTableArraySize] + ) + (firstGlyphIndex, lastGlyphIndex, additionalOffsetToIndexSubtable) = tup + i = curTable.indexSubTableArrayOffset + additionalOffsetToIndexSubtable + + tup = struct.unpack( + indexSubHeaderFormat, data[i : i + indexSubHeaderSize] + ) + (indexFormat, imageFormat, imageDataOffset) = tup + + indexFormatClass = self.getIndexFormatClass(indexFormat) + indexSubTable = indexFormatClass(data[i + indexSubHeaderSize :], ttFont) + indexSubTable.firstGlyphIndex = firstGlyphIndex + indexSubTable.lastGlyphIndex = lastGlyphIndex + indexSubTable.additionalOffsetToIndexSubtable = ( + additionalOffsetToIndexSubtable + ) + indexSubTable.indexFormat = indexFormat + indexSubTable.imageFormat = imageFormat + indexSubTable.imageDataOffset = imageDataOffset + indexSubTable.decompile() # https://github.com/fonttools/fonttools/issues/317 + curStrike.indexSubTables.append(indexSubTable) + + def compile(self, ttFont): + dataList = [] + self.numSizes = len(self.strikes) + dataList.append(sstruct.pack(eblcHeaderFormat, self)) + + # Data size of the header + bitmapSizeTable needs to be calculated + # in order to form offsets. This value will hold the size of the data + # in dataList after all the data is consolidated in dataList. + dataSize = len(dataList[0]) + + # The table will be structured in the following order: + # (0) header + # (1) Each bitmapSizeTable [1 ... self.numSizes] + # (2) Alternate between indexSubTableArray and indexSubTable + # for each bitmapSizeTable present. + # + # The issue is maintaining the proper offsets when table information + # gets moved around. All offsets and size information must be recalculated + # when building the table to allow editing within ttLib and also allow easy + # import/export to and from XML. All of this offset information is lost + # when exporting to XML so everything must be calculated fresh so importing + # from XML will work cleanly. Only byte offset and size information is + # calculated fresh. Count information like numberOfIndexSubTables is + # checked through assertions. If the information in this table was not + # touched or was changed properly then these types of values should match. + # + # The table will be rebuilt the following way: + # (0) Precompute the size of all the bitmapSizeTables. This is needed to + # compute the offsets properly. + # (1) For each bitmapSizeTable compute the indexSubTable and + # indexSubTableArray pair. The indexSubTable must be computed first + # so that the offset information in indexSubTableArray can be + # calculated. Update the data size after each pairing. + # (2) Build each bitmapSizeTable. + # (3) Consolidate all the data into the main dataList in the correct order. + + for _ in self.strikes: + dataSize += sstruct.calcsize(bitmapSizeTableFormatPart1) + dataSize += len(("hori", "vert")) * sstruct.calcsize(sbitLineMetricsFormat) + dataSize += sstruct.calcsize(bitmapSizeTableFormatPart2) + + indexSubTablePairDataList = [] + for curStrike in self.strikes: + curTable = curStrike.bitmapSizeTable + curTable.numberOfIndexSubTables = len(curStrike.indexSubTables) + curTable.indexSubTableArrayOffset = dataSize + + # Precompute the size of the indexSubTableArray. This information + # is important for correctly calculating the new value for + # additionalOffsetToIndexSubtable. + sizeOfSubTableArray = ( + curTable.numberOfIndexSubTables * indexSubTableArraySize + ) + lowerBound = dataSize + dataSize += sizeOfSubTableArray + upperBound = dataSize + + indexSubTableDataList = [] + for indexSubTable in curStrike.indexSubTables: + indexSubTable.additionalOffsetToIndexSubtable = ( + dataSize - curTable.indexSubTableArrayOffset + ) + glyphIds = list(map(ttFont.getGlyphID, indexSubTable.names)) + indexSubTable.firstGlyphIndex = min(glyphIds) + indexSubTable.lastGlyphIndex = max(glyphIds) + data = indexSubTable.compile(ttFont) + indexSubTableDataList.append(data) + dataSize += len(data) + curTable.startGlyphIndex = min( + ist.firstGlyphIndex for ist in curStrike.indexSubTables + ) + curTable.endGlyphIndex = max( + ist.lastGlyphIndex for ist in curStrike.indexSubTables + ) + + for i in curStrike.indexSubTables: + data = struct.pack( + indexSubHeaderFormat, + i.firstGlyphIndex, + i.lastGlyphIndex, + i.additionalOffsetToIndexSubtable, + ) + indexSubTablePairDataList.append(data) + indexSubTablePairDataList.extend(indexSubTableDataList) + curTable.indexTablesSize = dataSize - curTable.indexSubTableArrayOffset + + for curStrike in self.strikes: + curTable = curStrike.bitmapSizeTable + data = sstruct.pack(bitmapSizeTableFormatPart1, curTable) + dataList.append(data) + for metric in ("hori", "vert"): + metricObj = vars(curTable)[metric] + data = sstruct.pack(sbitLineMetricsFormat, metricObj) + dataList.append(data) + data = sstruct.pack(bitmapSizeTableFormatPart2, curTable) + dataList.append(data) + dataList.extend(indexSubTablePairDataList) + + return bytesjoin(dataList) + + def toXML(self, writer, ttFont): + writer.simpletag("header", [("version", self.version)]) + writer.newline() + for curIndex, curStrike in enumerate(self.strikes): + curStrike.toXML(curIndex, writer, ttFont) + + def fromXML(self, name, attrs, content, ttFont): + if name == "header": + self.version = safeEval(attrs["version"]) + elif name == "strike": + if not hasattr(self, "strikes"): + self.strikes = [] + strikeIndex = safeEval(attrs["index"]) + curStrike = Strike() + curStrike.fromXML(name, attrs, content, ttFont, self) + + # Grow the strike array to the appropriate size. The XML format + # allows for the strike index value to be out of order. + if strikeIndex >= len(self.strikes): + self.strikes += [None] * (strikeIndex + 1 - len(self.strikes)) + assert self.strikes[strikeIndex] is None, "Duplicate strike EBLC indices." + self.strikes[strikeIndex] = curStrike + + +class Strike(object): + def __init__(self): + self.bitmapSizeTable = BitmapSizeTable() + self.indexSubTables = [] + + def toXML(self, strikeIndex, writer, ttFont): + writer.begintag("strike", [("index", strikeIndex)]) + writer.newline() + self.bitmapSizeTable.toXML(writer, ttFont) + writer.comment( + "GlyphIds are written but not read. The firstGlyphIndex and\nlastGlyphIndex values will be recalculated by the compiler." + ) + writer.newline() + for indexSubTable in self.indexSubTables: + indexSubTable.toXML(writer, ttFont) + writer.endtag("strike") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont, locator): + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name == "bitmapSizeTable": + self.bitmapSizeTable.fromXML(name, attrs, content, ttFont) + elif name.startswith(_indexSubTableSubclassPrefix): + indexFormat = safeEval(name[len(_indexSubTableSubclassPrefix) :]) + indexFormatClass = locator.getIndexFormatClass(indexFormat) + indexSubTable = indexFormatClass(None, None) + indexSubTable.indexFormat = indexFormat + indexSubTable.fromXML(name, attrs, content, ttFont) + self.indexSubTables.append(indexSubTable) + + +class BitmapSizeTable(object): + # Returns all the simple metric names that bitmap size table + # cares about in terms of XML creation. + def _getXMLMetricNames(self): + dataNames = sstruct.getformat(bitmapSizeTableFormatPart1)[1] + dataNames = {**dataNames, **sstruct.getformat(bitmapSizeTableFormatPart2)[1]} + # Skip the first 3 data names because they are byte offsets and counts. + return list(dataNames.keys())[3:] + + def toXML(self, writer, ttFont): + writer.begintag("bitmapSizeTable") + writer.newline() + for metric in ("hori", "vert"): + getattr(self, metric).toXML(metric, writer, ttFont) + for metricName in self._getXMLMetricNames(): + writer.simpletag(metricName, value=getattr(self, metricName)) + writer.newline() + writer.endtag("bitmapSizeTable") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + # Create a lookup for all the simple names that make sense to + # bitmap size table. Only read the information from these names. + dataNames = set(self._getXMLMetricNames()) + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name == "sbitLineMetrics": + direction = attrs["direction"] + assert direction in ( + "hori", + "vert", + ), "SbitLineMetrics direction specified invalid." + metricObj = SbitLineMetrics() + metricObj.fromXML(name, attrs, content, ttFont) + vars(self)[direction] = metricObj + elif name in dataNames: + vars(self)[name] = safeEval(attrs["value"]) + else: + log.warning("unknown name '%s' being ignored in BitmapSizeTable.", name) + + +class SbitLineMetrics(object): + def toXML(self, name, writer, ttFont): + writer.begintag("sbitLineMetrics", [("direction", name)]) + writer.newline() + for metricName in sstruct.getformat(sbitLineMetricsFormat)[1]: + writer.simpletag(metricName, value=getattr(self, metricName)) + writer.newline() + writer.endtag("sbitLineMetrics") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + metricNames = set(sstruct.getformat(sbitLineMetricsFormat)[1]) + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name in metricNames: + vars(self)[name] = safeEval(attrs["value"]) + + +# Important information about the naming scheme. Used for identifying subtables. +_indexSubTableSubclassPrefix = "eblc_index_sub_table_" + + +class EblcIndexSubTable(object): + def __init__(self, data, ttFont): + self.data = data + self.ttFont = ttFont + # TODO Currently non-lazy decompiling doesn't work for this class... + # if not ttFont.lazy: + # self.decompile() + # del self.data, self.ttFont + + def __getattr__(self, attr): + # Allow lazy decompile. + if attr[:2] == "__": + raise AttributeError(attr) + if attr == "data": + raise AttributeError(attr) + self.decompile() + return getattr(self, attr) + + def ensureDecompiled(self, recurse=False): + if hasattr(self, "data"): + self.decompile() + + # This method just takes care of the indexSubHeader. Implementing subclasses + # should call it to compile the indexSubHeader and then continue compiling + # the remainder of their unique format. + def compile(self, ttFont): + return struct.pack( + indexSubHeaderFormat, + self.indexFormat, + self.imageFormat, + self.imageDataOffset, + ) + + # Creates the XML for bitmap glyphs. Each index sub table basically makes + # the same XML except for specific metric information that is written + # out via a method call that a subclass implements optionally. + def toXML(self, writer, ttFont): + writer.begintag( + self.__class__.__name__, + [ + ("imageFormat", self.imageFormat), + ("firstGlyphIndex", self.firstGlyphIndex), + ("lastGlyphIndex", self.lastGlyphIndex), + ], + ) + writer.newline() + self.writeMetrics(writer, ttFont) + # Write out the names as thats all thats needed to rebuild etc. + # For font debugging of consecutive formats the ids are also written. + # The ids are not read when moving from the XML format. + glyphIds = map(ttFont.getGlyphID, self.names) + for glyphName, glyphId in zip(self.names, glyphIds): + writer.simpletag("glyphLoc", name=glyphName, id=glyphId) + writer.newline() + writer.endtag(self.__class__.__name__) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + # Read all the attributes. Even though the glyph indices are + # recalculated, they are still read in case there needs to + # be an immediate export of the data. + self.imageFormat = safeEval(attrs["imageFormat"]) + self.firstGlyphIndex = safeEval(attrs["firstGlyphIndex"]) + self.lastGlyphIndex = safeEval(attrs["lastGlyphIndex"]) + + self.readMetrics(name, attrs, content, ttFont) + + self.names = [] + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name == "glyphLoc": + self.names.append(attrs["name"]) + + # A helper method that writes the metrics for the index sub table. It also + # is responsible for writing the image size for fixed size data since fixed + # size is not recalculated on compile. Default behavior is to do nothing. + def writeMetrics(self, writer, ttFont): + pass + + # A helper method that is the inverse of writeMetrics. + def readMetrics(self, name, attrs, content, ttFont): + pass + + # This method is for fixed glyph data sizes. There are formats where + # the glyph data is fixed but are actually composite glyphs. To handle + # this the font spec in indexSubTable makes the data the size of the + # fixed size by padding the component arrays. This function abstracts + # out this padding process. Input is data unpadded. Output is data + # padded only in fixed formats. Default behavior is to return the data. + def padBitmapData(self, data): + return data + + # Remove any of the glyph locations and names that are flagged as skipped. + # This only occurs in formats {1,3}. + def removeSkipGlyphs(self): + # Determines if a name, location pair is a valid data location. + # Skip glyphs are marked when the size is equal to zero. + def isValidLocation(args): + (name, (startByte, endByte)) = args + return startByte < endByte + + # Remove all skip glyphs. + dataPairs = list(filter(isValidLocation, zip(self.names, self.locations))) + self.names, self.locations = list(map(list, zip(*dataPairs))) + + +# A closure for creating a custom mixin. This is done because formats 1 and 3 +# are very similar. The only difference between them is the size per offset +# value. Code put in here should handle both cases generally. +def _createOffsetArrayIndexSubTableMixin(formatStringForDataType): + # Prep the data size for the offset array data format. + dataFormat = ">" + formatStringForDataType + offsetDataSize = struct.calcsize(dataFormat) + + class OffsetArrayIndexSubTableMixin(object): + def decompile(self): + numGlyphs = self.lastGlyphIndex - self.firstGlyphIndex + 1 + indexingOffsets = [ + glyphIndex * offsetDataSize for glyphIndex in range(numGlyphs + 2) + ] + indexingLocations = zip(indexingOffsets, indexingOffsets[1:]) + offsetArray = [ + struct.unpack(dataFormat, self.data[slice(*loc)])[0] + for loc in indexingLocations + ] + + glyphIds = list(range(self.firstGlyphIndex, self.lastGlyphIndex + 1)) + modifiedOffsets = [offset + self.imageDataOffset for offset in offsetArray] + self.locations = list(zip(modifiedOffsets, modifiedOffsets[1:])) + + self.names = list(map(self.ttFont.getGlyphName, glyphIds)) + self.removeSkipGlyphs() + del self.data, self.ttFont + + def compile(self, ttFont): + # First make sure that all the data lines up properly. Formats 1 and 3 + # must have all its data lined up consecutively. If not this will fail. + for curLoc, nxtLoc in zip(self.locations, self.locations[1:]): + assert ( + curLoc[1] == nxtLoc[0] + ), "Data must be consecutive in indexSubTable offset formats" + + glyphIds = list(map(ttFont.getGlyphID, self.names)) + # Make sure that all ids are sorted strictly increasing. + assert all(glyphIds[i] < glyphIds[i + 1] for i in range(len(glyphIds) - 1)) + + # Run a simple algorithm to add skip glyphs to the data locations at + # the places where an id is not present. + idQueue = deque(glyphIds) + locQueue = deque(self.locations) + allGlyphIds = list(range(self.firstGlyphIndex, self.lastGlyphIndex + 1)) + allLocations = [] + for curId in allGlyphIds: + if curId != idQueue[0]: + allLocations.append((locQueue[0][0], locQueue[0][0])) + else: + idQueue.popleft() + allLocations.append(locQueue.popleft()) + + # Now that all the locations are collected, pack them appropriately into + # offsets. This is the form where offset[i] is the location and + # offset[i+1]-offset[i] is the size of the data location. + offsets = list(allLocations[0]) + [loc[1] for loc in allLocations[1:]] + # Image data offset must be less than or equal to the minimum of locations. + # This offset may change the value for round tripping but is safer and + # allows imageDataOffset to not be required to be in the XML version. + self.imageDataOffset = min(offsets) + offsetArray = [offset - self.imageDataOffset for offset in offsets] + + dataList = [EblcIndexSubTable.compile(self, ttFont)] + dataList += [ + struct.pack(dataFormat, offsetValue) for offsetValue in offsetArray + ] + # Take care of any padding issues. Only occurs in format 3. + if offsetDataSize * len(offsetArray) % 4 != 0: + dataList.append(struct.pack(dataFormat, 0)) + return bytesjoin(dataList) + + return OffsetArrayIndexSubTableMixin + + +# A Mixin for functionality shared between the different kinds +# of fixed sized data handling. Both kinds have big metrics so +# that kind of special processing is also handled in this mixin. +class FixedSizeIndexSubTableMixin(object): + def writeMetrics(self, writer, ttFont): + writer.simpletag("imageSize", value=self.imageSize) + writer.newline() + self.metrics.toXML(writer, ttFont) + + def readMetrics(self, name, attrs, content, ttFont): + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name == "imageSize": + self.imageSize = safeEval(attrs["value"]) + elif name == BigGlyphMetrics.__name__: + self.metrics = BigGlyphMetrics() + self.metrics.fromXML(name, attrs, content, ttFont) + elif name == SmallGlyphMetrics.__name__: + log.warning( + "SmallGlyphMetrics being ignored in format %d.", self.indexFormat + ) + + def padBitmapData(self, data): + # Make sure that the data isn't bigger than the fixed size. + assert len(data) <= self.imageSize, ( + "Data in indexSubTable format %d must be less than the fixed size." + % self.indexFormat + ) + # Pad the data so that it matches the fixed size. + pad = (self.imageSize - len(data)) * b"\0" + return data + pad + + +class eblc_index_sub_table_1( + _createOffsetArrayIndexSubTableMixin("L"), EblcIndexSubTable +): + pass + + +class eblc_index_sub_table_2(FixedSizeIndexSubTableMixin, EblcIndexSubTable): + def decompile(self): + (self.imageSize,) = struct.unpack(">L", self.data[:4]) + self.metrics = BigGlyphMetrics() + sstruct.unpack2(bigGlyphMetricsFormat, self.data[4:], self.metrics) + glyphIds = list(range(self.firstGlyphIndex, self.lastGlyphIndex + 1)) + offsets = [ + self.imageSize * i + self.imageDataOffset for i in range(len(glyphIds) + 1) + ] + self.locations = list(zip(offsets, offsets[1:])) + self.names = list(map(self.ttFont.getGlyphName, glyphIds)) + del self.data, self.ttFont + + def compile(self, ttFont): + glyphIds = list(map(ttFont.getGlyphID, self.names)) + # Make sure all the ids are consecutive. This is required by Format 2. + assert glyphIds == list( + range(self.firstGlyphIndex, self.lastGlyphIndex + 1) + ), "Format 2 ids must be consecutive." + self.imageDataOffset = min(next(iter(zip(*self.locations)))) + + dataList = [EblcIndexSubTable.compile(self, ttFont)] + dataList.append(struct.pack(">L", self.imageSize)) + dataList.append(sstruct.pack(bigGlyphMetricsFormat, self.metrics)) + return bytesjoin(dataList) + + +class eblc_index_sub_table_3( + _createOffsetArrayIndexSubTableMixin("H"), EblcIndexSubTable +): + pass + + +class eblc_index_sub_table_4(EblcIndexSubTable): + def decompile(self): + (numGlyphs,) = struct.unpack(">L", self.data[:4]) + data = self.data[4:] + indexingOffsets = [ + glyphIndex * codeOffsetPairSize for glyphIndex in range(numGlyphs + 2) + ] + indexingLocations = zip(indexingOffsets, indexingOffsets[1:]) + glyphArray = [ + struct.unpack(codeOffsetPairFormat, data[slice(*loc)]) + for loc in indexingLocations + ] + glyphIds, offsets = list(map(list, zip(*glyphArray))) + # There are one too many glyph ids. Get rid of the last one. + glyphIds.pop() + + offsets = [offset + self.imageDataOffset for offset in offsets] + self.locations = list(zip(offsets, offsets[1:])) + self.names = list(map(self.ttFont.getGlyphName, glyphIds)) + del self.data, self.ttFont + + def compile(self, ttFont): + # First make sure that all the data lines up properly. Format 4 + # must have all its data lined up consecutively. If not this will fail. + for curLoc, nxtLoc in zip(self.locations, self.locations[1:]): + assert ( + curLoc[1] == nxtLoc[0] + ), "Data must be consecutive in indexSubTable format 4" + + offsets = list(self.locations[0]) + [loc[1] for loc in self.locations[1:]] + # Image data offset must be less than or equal to the minimum of locations. + # Resetting this offset may change the value for round tripping but is safer + # and allows imageDataOffset to not be required to be in the XML version. + self.imageDataOffset = min(offsets) + offsets = [offset - self.imageDataOffset for offset in offsets] + glyphIds = list(map(ttFont.getGlyphID, self.names)) + # Create an iterator over the ids plus a padding value. + idsPlusPad = list(itertools.chain(glyphIds, [0])) + + dataList = [EblcIndexSubTable.compile(self, ttFont)] + dataList.append(struct.pack(">L", len(glyphIds))) + tmp = [ + struct.pack(codeOffsetPairFormat, *cop) for cop in zip(idsPlusPad, offsets) + ] + dataList += tmp + data = bytesjoin(dataList) + return data + + +class eblc_index_sub_table_5(FixedSizeIndexSubTableMixin, EblcIndexSubTable): + def decompile(self): + self.origDataLen = 0 + (self.imageSize,) = struct.unpack(">L", self.data[:4]) + data = self.data[4:] + self.metrics, data = sstruct.unpack2( + bigGlyphMetricsFormat, data, BigGlyphMetrics() + ) + (numGlyphs,) = struct.unpack(">L", data[:4]) + data = data[4:] + glyphIds = [ + struct.unpack(">H", data[2 * i : 2 * (i + 1)])[0] for i in range(numGlyphs) + ] + + offsets = [ + self.imageSize * i + self.imageDataOffset for i in range(len(glyphIds) + 1) + ] + self.locations = list(zip(offsets, offsets[1:])) + self.names = list(map(self.ttFont.getGlyphName, glyphIds)) + del self.data, self.ttFont + + def compile(self, ttFont): + self.imageDataOffset = min(next(iter(zip(*self.locations)))) + dataList = [EblcIndexSubTable.compile(self, ttFont)] + dataList.append(struct.pack(">L", self.imageSize)) + dataList.append(sstruct.pack(bigGlyphMetricsFormat, self.metrics)) + glyphIds = list(map(ttFont.getGlyphID, self.names)) + dataList.append(struct.pack(">L", len(glyphIds))) + dataList += [struct.pack(">H", curId) for curId in glyphIds] + if len(glyphIds) % 2 == 1: + dataList.append(struct.pack(">H", 0)) + return bytesjoin(dataList) + + +# Dictionary of indexFormat to the class representing that format. +eblc_sub_table_classes = { + 1: eblc_index_sub_table_1, + 2: eblc_index_sub_table_2, + 3: eblc_index_sub_table_3, + 4: eblc_index_sub_table_4, + 5: eblc_index_sub_table_5, +} diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/F_F_T_M_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/F_F_T_M_.py new file mode 100644 index 0000000000000000000000000000000000000000..20b72346611911a1044ae0d52eb2a5c9efdf5540 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/F_F_T_M_.py @@ -0,0 +1,52 @@ +from fontTools.misc import sstruct +from fontTools.misc.textTools import safeEval +from fontTools.misc.timeTools import timestampFromString, timestampToString +from . import DefaultTable + +FFTMFormat = """ + > # big endian + version: I + FFTimeStamp: Q + sourceCreated: Q + sourceModified: Q +""" + + +class table_F_F_T_M_(DefaultTable.DefaultTable): + """FontForge Time Stamp table + + The ``FFTM`` table is used by the free-software font editor + FontForge to record timestamps for the creation and modification + of font source (.sfd) files and a timestamp for FontForge's + own source code. + + See also https://fontforge.org/docs/techref/non-standard.html + """ + + def decompile(self, data, ttFont): + dummy, rest = sstruct.unpack2(FFTMFormat, data, self) + + def compile(self, ttFont): + data = sstruct.pack(FFTMFormat, self) + return data + + def toXML(self, writer, ttFont): + writer.comment( + "FontForge's timestamp, font source creation and modification dates" + ) + writer.newline() + formatstring, names, fixes = sstruct.getformat(FFTMFormat) + for name in names: + value = getattr(self, name) + if name in ("FFTimeStamp", "sourceCreated", "sourceModified"): + value = timestampToString(value) + writer.simpletag(name, value=value) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + value = attrs["value"] + if name in ("FFTimeStamp", "sourceCreated", "sourceModified"): + value = timestampFromString(value) + else: + value = safeEval(value) + setattr(self, name, value) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/F__e_a_t.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/F__e_a_t.py new file mode 100644 index 0000000000000000000000000000000000000000..579eb27bdd7f11dcba75eae68bf900a0e298d0cc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/F__e_a_t.py @@ -0,0 +1,149 @@ +from fontTools.misc import sstruct +from fontTools.misc.fixedTools import floatToFixedToStr +from fontTools.misc.textTools import safeEval +from . import DefaultTable +from . import grUtils +import struct + +Feat_hdr_format = """ + > + version: 16.16F +""" + + +class table_F__e_a_t(DefaultTable.DefaultTable): + """Feature table + + The ``Feat`` table is used exclusively by the Graphite shaping engine + to store features and possible settings specified in GDL. Graphite features + determine what rules are applied to transform a glyph stream. + + Not to be confused with ``feat``, or the OpenType Layout tables + ``GSUB``/``GPOS``. + + See also https://graphite.sil.org/graphite_techAbout#graphite-font-tables + """ + + def __init__(self, tag=None): + DefaultTable.DefaultTable.__init__(self, tag) + self.features = {} + + def decompile(self, data, ttFont): + (_, data) = sstruct.unpack2(Feat_hdr_format, data, self) + self.version = float(floatToFixedToStr(self.version, precisionBits=16)) + (numFeats,) = struct.unpack(">H", data[:2]) + data = data[8:] + allfeats = [] + maxsetting = 0 + for i in range(numFeats): + if self.version >= 2.0: + (fid, nums, _, offset, flags, lid) = struct.unpack( + ">LHHLHH", data[16 * i : 16 * (i + 1)] + ) + offset = int((offset - 12 - 16 * numFeats) / 4) + else: + (fid, nums, offset, flags, lid) = struct.unpack( + ">HHLHH", data[12 * i : 12 * (i + 1)] + ) + offset = int((offset - 12 - 12 * numFeats) / 4) + allfeats.append((fid, nums, offset, flags, lid)) + maxsetting = max(maxsetting, offset + nums) + data = data[16 * numFeats :] + allsettings = [] + for i in range(maxsetting): + if len(data) >= 4 * (i + 1): + (val, lid) = struct.unpack(">HH", data[4 * i : 4 * (i + 1)]) + allsettings.append((val, lid)) + for i, f in enumerate(allfeats): + (fid, nums, offset, flags, lid) = f + fobj = Feature() + fobj.flags = flags + fobj.label = lid + self.features[grUtils.num2tag(fid)] = fobj + fobj.settings = {} + fobj.default = None + fobj.index = i + for i in range(offset, offset + nums): + if i >= len(allsettings): + continue + (vid, vlid) = allsettings[i] + fobj.settings[vid] = vlid + if fobj.default is None: + fobj.default = vid + + def compile(self, ttFont): + fdat = b"" + vdat = b"" + offset = 0 + for f, v in sorted(self.features.items(), key=lambda x: x[1].index): + fnum = grUtils.tag2num(f) + if self.version >= 2.0: + fdat += struct.pack( + ">LHHLHH", + grUtils.tag2num(f), + len(v.settings), + 0, + offset * 4 + 12 + 16 * len(self.features), + v.flags, + v.label, + ) + elif fnum > 65535: # self healing for alphabetic ids + self.version = 2.0 + return self.compile(ttFont) + else: + fdat += struct.pack( + ">HHLHH", + grUtils.tag2num(f), + len(v.settings), + offset * 4 + 12 + 12 * len(self.features), + v.flags, + v.label, + ) + for s, l in sorted( + v.settings.items(), key=lambda x: (-1, x[1]) if x[0] == v.default else x + ): + vdat += struct.pack(">HH", s, l) + offset += len(v.settings) + hdr = sstruct.pack(Feat_hdr_format, self) + return hdr + struct.pack(">HHL", len(self.features), 0, 0) + fdat + vdat + + def toXML(self, writer, ttFont): + writer.simpletag("version", version=self.version) + writer.newline() + for f, v in sorted(self.features.items(), key=lambda x: x[1].index): + writer.begintag( + "feature", + fid=f, + label=v.label, + flags=v.flags, + default=(v.default if v.default else 0), + ) + writer.newline() + for s, l in sorted(v.settings.items()): + writer.simpletag("setting", value=s, label=l) + writer.newline() + writer.endtag("feature") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "version": + self.version = float(safeEval(attrs["version"])) + elif name == "feature": + fid = attrs["fid"] + fobj = Feature() + fobj.flags = int(safeEval(attrs["flags"])) + fobj.label = int(safeEval(attrs["label"])) + fobj.default = int(safeEval(attrs.get("default", "0"))) + fobj.index = len(self.features) + self.features[fid] = fobj + fobj.settings = {} + for element in content: + if not isinstance(element, tuple): + continue + tag, a, c = element + if tag == "setting": + fobj.settings[int(safeEval(a["value"]))] = int(safeEval(a["label"])) + + +class Feature(object): + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_D_E_F_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_D_E_F_.py new file mode 100644 index 0000000000000000000000000000000000000000..922a9cb2063777cae486a3369d3d6380f9f626cf --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_D_E_F_.py @@ -0,0 +1,13 @@ +from .otBase import BaseTTXConverter + + +class table_G_D_E_F_(BaseTTXConverter): + """Glyph Definition table + + The ``GDEF`` table stores various glyph properties that are used + by OpenType Layout. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/gdef + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_M_A_P_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_M_A_P_.py new file mode 100644 index 0000000000000000000000000000000000000000..070c61919e174a52cd0acd23d8f32b38e2ee3ecb --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_M_A_P_.py @@ -0,0 +1,148 @@ +from fontTools.misc import sstruct +from fontTools.misc.textTools import tobytes, tostr, safeEval +from . import DefaultTable + +GMAPFormat = """ + > # big endian + tableVersionMajor: H + tableVersionMinor: H + flags: H + recordsCount: H + recordsOffset: H + fontNameLength: H +""" +# psFontName is a byte string which follows the record above. This is zero padded +# to the beginning of the records array. The recordsOffsst is 32 bit aligned. + +GMAPRecordFormat1 = """ + > # big endian + UV: L + cid: H + gid: H + ggid: H + name: 32s +""" + + +class GMAPRecord(object): + def __init__(self, uv=0, cid=0, gid=0, ggid=0, name=""): + self.UV = uv + self.cid = cid + self.gid = gid + self.ggid = ggid + self.name = name + + def toXML(self, writer, ttFont): + writer.begintag("GMAPRecord") + writer.newline() + writer.simpletag("UV", value=self.UV) + writer.newline() + writer.simpletag("cid", value=self.cid) + writer.newline() + writer.simpletag("gid", value=self.gid) + writer.newline() + writer.simpletag("glyphletGid", value=self.gid) + writer.newline() + writer.simpletag("GlyphletName", value=self.name) + writer.newline() + writer.endtag("GMAPRecord") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + value = attrs["value"] + if name == "GlyphletName": + self.name = value + else: + setattr(self, name, safeEval(value)) + + def compile(self, ttFont): + if self.UV is None: + self.UV = 0 + nameLen = len(self.name) + if nameLen < 32: + self.name = self.name + "\0" * (32 - nameLen) + data = sstruct.pack(GMAPRecordFormat1, self) + return data + + def __repr__(self): + return ( + "GMAPRecord[ UV: " + + str(self.UV) + + ", cid: " + + str(self.cid) + + ", gid: " + + str(self.gid) + + ", ggid: " + + str(self.ggid) + + ", Glyphlet Name: " + + str(self.name) + + " ]" + ) + + +class table_G_M_A_P_(DefaultTable.DefaultTable): + """Glyphlets GMAP table + + The ``GMAP`` table is used by Adobe's SING Glyphlets. + + See also https://web.archive.org/web/20080627183635/http://www.adobe.com/devnet/opentype/gdk/topic.html + """ + + dependencies = [] + + def decompile(self, data, ttFont): + dummy, newData = sstruct.unpack2(GMAPFormat, data, self) + self.psFontName = tostr(newData[: self.fontNameLength]) + assert ( + self.recordsOffset % 4 + ) == 0, "GMAP error: recordsOffset is not 32 bit aligned." + newData = data[self.recordsOffset :] + self.gmapRecords = [] + for i in range(self.recordsCount): + gmapRecord, newData = sstruct.unpack2( + GMAPRecordFormat1, newData, GMAPRecord() + ) + gmapRecord.name = gmapRecord.name.strip("\0") + self.gmapRecords.append(gmapRecord) + + def compile(self, ttFont): + self.recordsCount = len(self.gmapRecords) + self.fontNameLength = len(self.psFontName) + self.recordsOffset = 4 * (((self.fontNameLength + 12) + 3) // 4) + data = sstruct.pack(GMAPFormat, self) + data = data + tobytes(self.psFontName) + data = data + b"\0" * (self.recordsOffset - len(data)) + for record in self.gmapRecords: + data = data + record.compile(ttFont) + return data + + def toXML(self, writer, ttFont): + writer.comment("Most of this table will be recalculated by the compiler") + writer.newline() + formatstring, names, fixes = sstruct.getformat(GMAPFormat) + for name in names: + value = getattr(self, name) + writer.simpletag(name, value=value) + writer.newline() + writer.simpletag("PSFontName", value=self.psFontName) + writer.newline() + for gmapRecord in self.gmapRecords: + gmapRecord.toXML(writer, ttFont) + + def fromXML(self, name, attrs, content, ttFont): + if name == "GMAPRecord": + if not hasattr(self, "gmapRecords"): + self.gmapRecords = [] + gmapRecord = GMAPRecord() + self.gmapRecords.append(gmapRecord) + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + gmapRecord.fromXML(name, attrs, content, ttFont) + else: + value = attrs["value"] + if name == "PSFontName": + self.psFontName = value + else: + setattr(self, name, safeEval(value)) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_P_K_G_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_P_K_G_.py new file mode 100644 index 0000000000000000000000000000000000000000..0da99fcda4017d60788ff3cac336b2c6c877936e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_P_K_G_.py @@ -0,0 +1,133 @@ +from fontTools.misc import sstruct +from fontTools.misc.textTools import bytesjoin, safeEval, readHex +from . import DefaultTable +import sys +import array + +GPKGFormat = """ + > # big endian + version: H + flags: H + numGMAPs: H + numGlyplets: H +""" +# psFontName is a byte string which follows the record above. This is zero padded +# to the beginning of the records array. The recordsOffsst is 32 bit aligned. + + +class table_G_P_K_G_(DefaultTable.DefaultTable): + """Glyphlets GPKG table + + The ``GPKG`` table is used by Adobe's SING Glyphlets. + + See also https://web.archive.org/web/20080627183635/http://www.adobe.com/devnet/opentype/gdk/topic.html + """ + + def decompile(self, data, ttFont): + dummy, newData = sstruct.unpack2(GPKGFormat, data, self) + + GMAPoffsets = array.array("I") + endPos = (self.numGMAPs + 1) * 4 + GMAPoffsets.frombytes(newData[:endPos]) + if sys.byteorder != "big": + GMAPoffsets.byteswap() + self.GMAPs = [] + for i in range(self.numGMAPs): + start = GMAPoffsets[i] + end = GMAPoffsets[i + 1] + self.GMAPs.append(data[start:end]) + pos = endPos + endPos = pos + (self.numGlyplets + 1) * 4 + glyphletOffsets = array.array("I") + glyphletOffsets.frombytes(newData[pos:endPos]) + if sys.byteorder != "big": + glyphletOffsets.byteswap() + self.glyphlets = [] + for i in range(self.numGlyplets): + start = glyphletOffsets[i] + end = glyphletOffsets[i + 1] + self.glyphlets.append(data[start:end]) + + def compile(self, ttFont): + self.numGMAPs = len(self.GMAPs) + self.numGlyplets = len(self.glyphlets) + GMAPoffsets = [0] * (self.numGMAPs + 1) + glyphletOffsets = [0] * (self.numGlyplets + 1) + + dataList = [sstruct.pack(GPKGFormat, self)] + + pos = len(dataList[0]) + (self.numGMAPs + 1) * 4 + (self.numGlyplets + 1) * 4 + GMAPoffsets[0] = pos + for i in range(1, self.numGMAPs + 1): + pos += len(self.GMAPs[i - 1]) + GMAPoffsets[i] = pos + gmapArray = array.array("I", GMAPoffsets) + if sys.byteorder != "big": + gmapArray.byteswap() + dataList.append(gmapArray.tobytes()) + + glyphletOffsets[0] = pos + for i in range(1, self.numGlyplets + 1): + pos += len(self.glyphlets[i - 1]) + glyphletOffsets[i] = pos + glyphletArray = array.array("I", glyphletOffsets) + if sys.byteorder != "big": + glyphletArray.byteswap() + dataList.append(glyphletArray.tobytes()) + dataList += self.GMAPs + dataList += self.glyphlets + data = bytesjoin(dataList) + return data + + def toXML(self, writer, ttFont): + writer.comment("Most of this table will be recalculated by the compiler") + writer.newline() + formatstring, names, fixes = sstruct.getformat(GPKGFormat) + for name in names: + value = getattr(self, name) + writer.simpletag(name, value=value) + writer.newline() + + writer.begintag("GMAPs") + writer.newline() + for gmapData in self.GMAPs: + writer.begintag("hexdata") + writer.newline() + writer.dumphex(gmapData) + writer.endtag("hexdata") + writer.newline() + writer.endtag("GMAPs") + writer.newline() + + writer.begintag("glyphlets") + writer.newline() + for glyphletData in self.glyphlets: + writer.begintag("hexdata") + writer.newline() + writer.dumphex(glyphletData) + writer.endtag("hexdata") + writer.newline() + writer.endtag("glyphlets") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "GMAPs": + if not hasattr(self, "GMAPs"): + self.GMAPs = [] + for element in content: + if isinstance(element, str): + continue + itemName, itemAttrs, itemContent = element + if itemName == "hexdata": + self.GMAPs.append(readHex(itemContent)) + elif name == "glyphlets": + if not hasattr(self, "glyphlets"): + self.glyphlets = [] + for element in content: + if isinstance(element, str): + continue + itemName, itemAttrs, itemContent = element + if itemName == "hexdata": + self.glyphlets.append(readHex(itemContent)) + else: + setattr(self, name, safeEval(attrs["value"])) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_P_O_S_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_P_O_S_.py new file mode 100644 index 0000000000000000000000000000000000000000..03bdc612ead945133c97f4a4d0002e8ca31c60c4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_P_O_S_.py @@ -0,0 +1,14 @@ +from .otBase import BaseTTXConverter + + +class table_G_P_O_S_(BaseTTXConverter): + """Glyph Positioning table + + The ``GPOS`` table stores advanced glyph-positioning data + used in OpenType Layout features, such as mark attachment, + cursive attachment, kerning, and other position adjustments. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/gpos + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_S_U_B_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_S_U_B_.py new file mode 100644 index 0000000000000000000000000000000000000000..ca1aff8b0680bf22550c460819627b4d2b14a463 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_S_U_B_.py @@ -0,0 +1,13 @@ +from .otBase import BaseTTXConverter + + +class table_G_S_U_B_(BaseTTXConverter): + """Glyph Substitution table + + The ``GSUB`` table contains glyph-substitution rules used in + OpenType Layout. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/gsub + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_V_A_R_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_V_A_R_.py new file mode 100644 index 0000000000000000000000000000000000000000..889b1f2a3bd712b68140a6b9102e732ce794587c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G_V_A_R_.py @@ -0,0 +1,5 @@ +from ._g_v_a_r import table__g_v_a_r + + +class table_G_V_A_R_(table__g_v_a_r): + gid_size = 3 diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G__l_a_t.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G__l_a_t.py new file mode 100644 index 0000000000000000000000000000000000000000..fe1e0534fb75e372933add1e71799c272a01c3dd --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G__l_a_t.py @@ -0,0 +1,235 @@ +from fontTools.misc import sstruct +from fontTools.misc.fixedTools import floatToFixedToStr +from fontTools.misc.textTools import safeEval + +# from itertools import * +from functools import partial +from . import DefaultTable +from . import grUtils +import struct + + +Glat_format_0 = """ + > # big endian + version: 16.16F +""" + +Glat_format_3 = """ + > + version: 16.16F + compression:L # compression scheme or reserved +""" + +Glat_format_1_entry = """ + > + attNum: B # Attribute number of first attribute + num: B # Number of attributes in this run +""" +Glat_format_23_entry = """ + > + attNum: H # Attribute number of first attribute + num: H # Number of attributes in this run +""" + +Glat_format_3_octabox_metrics = """ + > + subboxBitmap: H # Which subboxes exist on 4x4 grid + diagNegMin: B # Defines minimum negatively-sloped diagonal (si) + diagNegMax: B # Defines maximum negatively-sloped diagonal (sa) + diagPosMin: B # Defines minimum positively-sloped diagonal (di) + diagPosMax: B # Defines maximum positively-sloped diagonal (da) +""" + +Glat_format_3_subbox_entry = """ + > + left: B # xi + right: B # xa + bottom: B # yi + top: B # ya + diagNegMin: B # Defines minimum negatively-sloped diagonal (si) + diagNegMax: B # Defines maximum negatively-sloped diagonal (sa) + diagPosMin: B # Defines minimum positively-sloped diagonal (di) + diagPosMax: B # Defines maximum positively-sloped diagonal (da) +""" + + +class _Object: + pass + + +class _Dict(dict): + pass + + +class table_G__l_a_t(DefaultTable.DefaultTable): + """Graphite Glyph Attributes table + + See also https://graphite.sil.org/graphite_techAbout#graphite-font-tables + """ + + def __init__(self, tag=None): + DefaultTable.DefaultTable.__init__(self, tag) + self.scheme = 0 + + def decompile(self, data, ttFont): + sstruct.unpack2(Glat_format_0, data, self) + self.version = float(floatToFixedToStr(self.version, precisionBits=16)) + if self.version <= 1.9: + decoder = partial(self.decompileAttributes12, fmt=Glat_format_1_entry) + elif self.version <= 2.9: + decoder = partial(self.decompileAttributes12, fmt=Glat_format_23_entry) + elif self.version >= 3.0: + (data, self.scheme) = grUtils.decompress(data) + sstruct.unpack2(Glat_format_3, data, self) + self.hasOctaboxes = (self.compression & 1) == 1 + decoder = self.decompileAttributes3 + + gloc = ttFont["Gloc"] + self.attributes = {} + count = 0 + for s, e in zip(gloc, gloc[1:]): + self.attributes[ttFont.getGlyphName(count)] = decoder(data[s:e]) + count += 1 + + def decompileAttributes12(self, data, fmt): + attributes = _Dict() + while len(data) > 3: + e, data = sstruct.unpack2(fmt, data, _Object()) + keys = range(e.attNum, e.attNum + e.num) + if len(data) >= 2 * e.num: + vals = struct.unpack_from((">%dh" % e.num), data) + attributes.update(zip(keys, vals)) + data = data[2 * e.num :] + return attributes + + def decompileAttributes3(self, data): + if self.hasOctaboxes: + o, data = sstruct.unpack2(Glat_format_3_octabox_metrics, data, _Object()) + numsub = bin(o.subboxBitmap).count("1") + o.subboxes = [] + for b in range(numsub): + if len(data) >= 8: + subbox, data = sstruct.unpack2( + Glat_format_3_subbox_entry, data, _Object() + ) + o.subboxes.append(subbox) + attrs = self.decompileAttributes12(data, Glat_format_23_entry) + if self.hasOctaboxes: + attrs.octabox = o + return attrs + + def compile(self, ttFont): + data = sstruct.pack(Glat_format_0, self) + if self.version <= 1.9: + encoder = partial(self.compileAttributes12, fmt=Glat_format_1_entry) + elif self.version <= 2.9: + encoder = partial(self.compileAttributes12, fmt=Glat_format_1_entry) + elif self.version >= 3.0: + self.compression = (self.scheme << 27) + (1 if self.hasOctaboxes else 0) + data = sstruct.pack(Glat_format_3, self) + encoder = self.compileAttributes3 + + glocs = [] + for n in range(len(self.attributes)): + glocs.append(len(data)) + data += encoder(self.attributes[ttFont.getGlyphName(n)]) + glocs.append(len(data)) + ttFont["Gloc"].set(glocs) + + if self.version >= 3.0: + data = grUtils.compress(self.scheme, data) + return data + + def compileAttributes12(self, attrs, fmt): + data = b"" + for e in grUtils.entries(attrs): + data += sstruct.pack(fmt, {"attNum": e[0], "num": e[1]}) + struct.pack( + (">%dh" % len(e[2])), *e[2] + ) + return data + + def compileAttributes3(self, attrs): + if self.hasOctaboxes: + o = attrs.octabox + data = sstruct.pack(Glat_format_3_octabox_metrics, o) + numsub = bin(o.subboxBitmap).count("1") + for b in range(numsub): + data += sstruct.pack(Glat_format_3_subbox_entry, o.subboxes[b]) + else: + data = "" + return data + self.compileAttributes12(attrs, Glat_format_23_entry) + + def toXML(self, writer, ttFont): + writer.simpletag("version", version=self.version, compressionScheme=self.scheme) + writer.newline() + for n, a in sorted( + self.attributes.items(), key=lambda x: ttFont.getGlyphID(x[0]) + ): + writer.begintag("glyph", name=n) + writer.newline() + if hasattr(a, "octabox"): + o = a.octabox + formatstring, names, fixes = sstruct.getformat( + Glat_format_3_octabox_metrics + ) + vals = {} + for k in names: + if k == "subboxBitmap": + continue + vals[k] = "{:.3f}%".format(getattr(o, k) * 100.0 / 255) + vals["bitmap"] = "{:0X}".format(o.subboxBitmap) + writer.begintag("octaboxes", **vals) + writer.newline() + formatstring, names, fixes = sstruct.getformat( + Glat_format_3_subbox_entry + ) + for s in o.subboxes: + vals = {} + for k in names: + vals[k] = "{:.3f}%".format(getattr(s, k) * 100.0 / 255) + writer.simpletag("octabox", **vals) + writer.newline() + writer.endtag("octaboxes") + writer.newline() + for k, v in sorted(a.items()): + writer.simpletag("attribute", index=k, value=v) + writer.newline() + writer.endtag("glyph") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "version": + self.version = float(safeEval(attrs["version"])) + self.scheme = int(safeEval(attrs["compressionScheme"])) + if name != "glyph": + return + if not hasattr(self, "attributes"): + self.attributes = {} + gname = attrs["name"] + attributes = _Dict() + for element in content: + if not isinstance(element, tuple): + continue + tag, attrs, subcontent = element + if tag == "attribute": + k = int(safeEval(attrs["index"])) + v = int(safeEval(attrs["value"])) + attributes[k] = v + elif tag == "octaboxes": + self.hasOctaboxes = True + o = _Object() + o.subboxBitmap = int(attrs["bitmap"], 16) + o.subboxes = [] + del attrs["bitmap"] + for k, v in attrs.items(): + setattr(o, k, int(float(v[:-1]) * 255.0 / 100.0 + 0.5)) + for element in subcontent: + if not isinstance(element, tuple): + continue + (tag, attrs, subcontent) = element + so = _Object() + for k, v in attrs.items(): + setattr(so, k, int(float(v[:-1]) * 255.0 / 100.0 + 0.5)) + o.subboxes.append(so) + attributes.octabox = o + self.attributes[gname] = attributes diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G__l_o_c.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G__l_o_c.py new file mode 100644 index 0000000000000000000000000000000000000000..4c3d78ab2e4b993708a83c13efe45c3c4a1eaf92 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/G__l_o_c.py @@ -0,0 +1,85 @@ +from fontTools.misc import sstruct +from fontTools.misc.textTools import safeEval +from . import DefaultTable +import array +import sys + + +Gloc_header = """ + > # big endian + version: 16.16F # Table version + flags: H # bit 0: 1=long format, 0=short format + # bit 1: 1=attribute names, 0=no names + numAttribs: H # NUmber of attributes +""" + + +class table_G__l_o_c(DefaultTable.DefaultTable): + """Graphite Index to Glyph Atttributes table + + See also https://graphite.sil.org/graphite_techAbout#graphite-font-tables + """ + + dependencies = ["Glat"] + + def __init__(self, tag=None): + DefaultTable.DefaultTable.__init__(self, tag) + self.attribIds = None + self.numAttribs = 0 + + def decompile(self, data, ttFont): + _, data = sstruct.unpack2(Gloc_header, data, self) + flags = self.flags + del self.flags + self.locations = array.array("I" if flags & 1 else "H") + self.locations.frombytes(data[: len(data) - self.numAttribs * (flags & 2)]) + if sys.byteorder != "big": + self.locations.byteswap() + self.attribIds = array.array("H") + if flags & 2: + self.attribIds.frombytes(data[-self.numAttribs * 2 :]) + if sys.byteorder != "big": + self.attribIds.byteswap() + + def compile(self, ttFont): + data = sstruct.pack( + Gloc_header, + dict( + version=1.0, + flags=(bool(self.attribIds) << 1) + (self.locations.typecode == "I"), + numAttribs=self.numAttribs, + ), + ) + if sys.byteorder != "big": + self.locations.byteswap() + data += self.locations.tobytes() + if sys.byteorder != "big": + self.locations.byteswap() + if self.attribIds: + if sys.byteorder != "big": + self.attribIds.byteswap() + data += self.attribIds.tobytes() + if sys.byteorder != "big": + self.attribIds.byteswap() + return data + + def set(self, locations): + long_format = max(locations) >= 65536 + self.locations = array.array("I" if long_format else "H", locations) + + def toXML(self, writer, ttFont): + writer.simpletag("attributes", number=self.numAttribs) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "attributes": + self.numAttribs = int(safeEval(attrs["number"])) + + def __getitem__(self, index): + return self.locations[index] + + def __len__(self): + return len(self.locations) + + def __iter__(self): + return iter(self.locations) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/H_V_A_R_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/H_V_A_R_.py new file mode 100644 index 0000000000000000000000000000000000000000..48e7fd67cf0f89e5dc6057e5cbae7f07324a0402 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/H_V_A_R_.py @@ -0,0 +1,13 @@ +from .otBase import BaseTTXConverter + + +class table_H_V_A_R_(BaseTTXConverter): + """Horizontal Metrics Variations table + + The ``HVAR`` table contains variations in horizontal glyph metrics + in variable fonts. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/hvar + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/J_S_T_F_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/J_S_T_F_.py new file mode 100644 index 0000000000000000000000000000000000000000..b185f30f3a9a2978c1d4278b920f69969fe79b97 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/J_S_T_F_.py @@ -0,0 +1,13 @@ +from .otBase import BaseTTXConverter + + +class table_J_S_T_F_(BaseTTXConverter): + """Justification table + + The ``JSTF`` table contains glyph substitution and positioning + data used to perform text justification. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/jstf + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/L_T_S_H_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/L_T_S_H_.py new file mode 100644 index 0000000000000000000000000000000000000000..e691c06e9bfdc270127c2a5be33acf6505177d85 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/L_T_S_H_.py @@ -0,0 +1,58 @@ +from fontTools.misc.textTools import safeEval +from . import DefaultTable +import struct +import array + +# XXX I've lowered the strictness, to make sure Apple's own Chicago +# XXX gets through. They're looking into it, I hope to raise the standards +# XXX back to normal eventually. + + +class table_L_T_S_H_(DefaultTable.DefaultTable): + """Linear Threshold table + + The ``LTSH`` table contains per-glyph settings indicating the ppem sizes + at which the advance width metric should be scaled linearly, despite the + effects of any TrueType instructions that might otherwise alter the + advance width. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/ltsh + """ + + def decompile(self, data, ttFont): + version, numGlyphs = struct.unpack(">HH", data[:4]) + data = data[4:] + assert version == 0, "unknown version: %s" % version + assert (len(data) % numGlyphs) < 4, "numGlyphs doesn't match data length" + # ouch: the assertion is not true in Chicago! + # assert numGlyphs == ttFont['maxp'].numGlyphs + yPels = array.array("B") + yPels.frombytes(data) + self.yPels = {} + for i in range(numGlyphs): + self.yPels[ttFont.getGlyphName(i)] = yPels[i] + + def compile(self, ttFont): + version = 0 + names = list(self.yPels.keys()) + numGlyphs = len(names) + yPels = [0] * numGlyphs + # ouch: the assertion is not true in Chicago! + # assert len(self.yPels) == ttFont['maxp'].numGlyphs == numGlyphs + for name in names: + yPels[ttFont.getGlyphID(name)] = self.yPels[name] + yPels = array.array("B", yPels) + return struct.pack(">HH", version, numGlyphs) + yPels.tobytes() + + def toXML(self, writer, ttFont): + names = sorted(self.yPels.keys()) + for name in names: + writer.simpletag("yPel", name=name, value=self.yPels[name]) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if not hasattr(self, "yPels"): + self.yPels = {} + if name != "yPel": + return # ignore unknown tags + self.yPels[attrs["name"]] = safeEval(attrs["value"]) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/M_A_T_H_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/M_A_T_H_.py new file mode 100644 index 0000000000000000000000000000000000000000..35d29e9b13e9c8aeca0a95a3e965c52e7c96aed1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/M_A_T_H_.py @@ -0,0 +1,13 @@ +from .otBase import BaseTTXConverter + + +class table_M_A_T_H_(BaseTTXConverter): + """Mathematical Typesetting table + + The ``MATH`` table contains a variety of information needed to + typeset glyphs in mathematical formulas and expressions. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/math + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/M_E_T_A_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/M_E_T_A_.py new file mode 100644 index 0000000000000000000000000000000000000000..6a6f8bbf8400a0a39c3a251310c40464b1bbc627 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/M_E_T_A_.py @@ -0,0 +1,352 @@ +from fontTools.misc import sstruct +from fontTools.misc.textTools import byteord, safeEval +from . import DefaultTable +import pdb +import struct + + +METAHeaderFormat = """ + > # big endian + tableVersionMajor: H + tableVersionMinor: H + metaEntriesVersionMajor: H + metaEntriesVersionMinor: H + unicodeVersion: L + metaFlags: H + nMetaRecs: H +""" +# This record is followed by nMetaRecs of METAGlyphRecordFormat. +# This in turn is followd by as many METAStringRecordFormat entries +# as specified by the METAGlyphRecordFormat entries +# this is followed by the strings specifried in the METAStringRecordFormat +METAGlyphRecordFormat = """ + > # big endian + glyphID: H + nMetaEntry: H +""" +# This record is followd by a variable data length field: +# USHORT or ULONG hdrOffset +# Offset from start of META table to the beginning +# of this glyphs array of ns Metadata string entries. +# Size determined by metaFlags field +# METAGlyphRecordFormat entries must be sorted by glyph ID + +METAStringRecordFormat = """ + > # big endian + labelID: H + stringLen: H +""" +# This record is followd by a variable data length field: +# USHORT or ULONG stringOffset +# METAStringRecordFormat entries must be sorted in order of labelID +# There may be more than one entry with the same labelID +# There may be more than one strign with the same content. + +# Strings shall be Unicode UTF-8 encoded, and null-terminated. + +METALabelDict = { + 0: "MojikumiX4051", # An integer in the range 1-20 + 1: "UNIUnifiedBaseChars", + 2: "BaseFontName", + 3: "Language", + 4: "CreationDate", + 5: "FoundryName", + 6: "FoundryCopyright", + 7: "OwnerURI", + 8: "WritingScript", + 10: "StrokeCount", + 11: "IndexingRadical", +} + + +def getLabelString(labelID): + try: + label = METALabelDict[labelID] + except KeyError: + label = "Unknown label" + return str(label) + + +class table_M_E_T_A_(DefaultTable.DefaultTable): + """Glyphlets META table + + The ``META`` table is used by Adobe's SING Glyphlets. + + See also https://web.archive.org/web/20080627183635/http://www.adobe.com/devnet/opentype/gdk/topic.html + """ + + dependencies = [] + + def decompile(self, data, ttFont): + dummy, newData = sstruct.unpack2(METAHeaderFormat, data, self) + self.glyphRecords = [] + for i in range(self.nMetaRecs): + glyphRecord, newData = sstruct.unpack2( + METAGlyphRecordFormat, newData, GlyphRecord() + ) + if self.metaFlags == 0: + [glyphRecord.offset] = struct.unpack(">H", newData[:2]) + newData = newData[2:] + elif self.metaFlags == 1: + [glyphRecord.offset] = struct.unpack(">H", newData[:4]) + newData = newData[4:] + else: + assert 0, ( + "The metaFlags field in the META table header has a value other than 0 or 1 :" + + str(self.metaFlags) + ) + glyphRecord.stringRecs = [] + newData = data[glyphRecord.offset :] + for j in range(glyphRecord.nMetaEntry): + stringRec, newData = sstruct.unpack2( + METAStringRecordFormat, newData, StringRecord() + ) + if self.metaFlags == 0: + [stringRec.offset] = struct.unpack(">H", newData[:2]) + newData = newData[2:] + else: + [stringRec.offset] = struct.unpack(">H", newData[:4]) + newData = newData[4:] + stringRec.string = data[ + stringRec.offset : stringRec.offset + stringRec.stringLen + ] + glyphRecord.stringRecs.append(stringRec) + self.glyphRecords.append(glyphRecord) + + def compile(self, ttFont): + offsetOK = 0 + self.nMetaRecs = len(self.glyphRecords) + count = 0 + while offsetOK != 1: + count = count + 1 + if count > 4: + pdb.set_trace() + metaData = sstruct.pack(METAHeaderFormat, self) + stringRecsOffset = len(metaData) + self.nMetaRecs * ( + 6 + 2 * (self.metaFlags & 1) + ) + stringRecSize = 6 + 2 * (self.metaFlags & 1) + for glyphRec in self.glyphRecords: + glyphRec.offset = stringRecsOffset + if (glyphRec.offset > 65535) and ((self.metaFlags & 1) == 0): + self.metaFlags = self.metaFlags + 1 + offsetOK = -1 + break + metaData = metaData + glyphRec.compile(self) + stringRecsOffset = stringRecsOffset + ( + glyphRec.nMetaEntry * stringRecSize + ) + # this will be the String Record offset for the next GlyphRecord. + if offsetOK == -1: + offsetOK = 0 + continue + + # metaData now contains the header and all of the GlyphRecords. Its length should bw + # the offset to the first StringRecord. + stringOffset = stringRecsOffset + for glyphRec in self.glyphRecords: + assert glyphRec.offset == len( + metaData + ), "Glyph record offset did not compile correctly! for rec:" + str( + glyphRec + ) + for stringRec in glyphRec.stringRecs: + stringRec.offset = stringOffset + if (stringRec.offset > 65535) and ((self.metaFlags & 1) == 0): + self.metaFlags = self.metaFlags + 1 + offsetOK = -1 + break + metaData = metaData + stringRec.compile(self) + stringOffset = stringOffset + stringRec.stringLen + if offsetOK == -1: + offsetOK = 0 + continue + + if ((self.metaFlags & 1) == 1) and (stringOffset < 65536): + self.metaFlags = self.metaFlags - 1 + continue + else: + offsetOK = 1 + + # metaData now contains the header and all of the GlyphRecords and all of the String Records. + # Its length should be the offset to the first string datum. + for glyphRec in self.glyphRecords: + for stringRec in glyphRec.stringRecs: + assert stringRec.offset == len( + metaData + ), "String offset did not compile correctly! for string:" + str( + stringRec.string + ) + metaData = metaData + stringRec.string + + return metaData + + def toXML(self, writer, ttFont): + writer.comment( + "Lengths and number of entries in this table will be recalculated by the compiler" + ) + writer.newline() + formatstring, names, fixes = sstruct.getformat(METAHeaderFormat) + for name in names: + value = getattr(self, name) + writer.simpletag(name, value=value) + writer.newline() + for glyphRec in self.glyphRecords: + glyphRec.toXML(writer, ttFont) + + def fromXML(self, name, attrs, content, ttFont): + if name == "GlyphRecord": + if not hasattr(self, "glyphRecords"): + self.glyphRecords = [] + glyphRec = GlyphRecord() + self.glyphRecords.append(glyphRec) + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + glyphRec.fromXML(name, attrs, content, ttFont) + glyphRec.offset = -1 + glyphRec.nMetaEntry = len(glyphRec.stringRecs) + else: + setattr(self, name, safeEval(attrs["value"])) + + +class GlyphRecord(object): + def __init__(self): + self.glyphID = -1 + self.nMetaEntry = -1 + self.offset = -1 + self.stringRecs = [] + + def toXML(self, writer, ttFont): + writer.begintag("GlyphRecord") + writer.newline() + writer.simpletag("glyphID", value=self.glyphID) + writer.newline() + writer.simpletag("nMetaEntry", value=self.nMetaEntry) + writer.newline() + for stringRec in self.stringRecs: + stringRec.toXML(writer, ttFont) + writer.endtag("GlyphRecord") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "StringRecord": + stringRec = StringRecord() + self.stringRecs.append(stringRec) + for element in content: + if isinstance(element, str): + continue + stringRec.fromXML(name, attrs, content, ttFont) + stringRec.stringLen = len(stringRec.string) + else: + setattr(self, name, safeEval(attrs["value"])) + + def compile(self, parentTable): + data = sstruct.pack(METAGlyphRecordFormat, self) + if parentTable.metaFlags == 0: + datum = struct.pack(">H", self.offset) + elif parentTable.metaFlags == 1: + datum = struct.pack(">L", self.offset) + data = data + datum + return data + + def __repr__(self): + return ( + "GlyphRecord[ glyphID: " + + str(self.glyphID) + + ", nMetaEntry: " + + str(self.nMetaEntry) + + ", offset: " + + str(self.offset) + + " ]" + ) + + +# XXX The following two functions are really broken around UTF-8 vs Unicode + + +def mapXMLToUTF8(string): + uString = str() + strLen = len(string) + i = 0 + while i < strLen: + prefixLen = 0 + if string[i : i + 3] == "&#x": + prefixLen = 3 + elif string[i : i + 7] == "&#x": + prefixLen = 7 + if prefixLen: + i = i + prefixLen + j = i + while string[i] != ";": + i = i + 1 + valStr = string[j:i] + + uString = uString + chr(eval("0x" + valStr)) + else: + uString = uString + chr(byteord(string[i])) + i = i + 1 + + return uString.encode("utf_8") + + +def mapUTF8toXML(string): + uString = string.decode("utf_8") + string = "" + for uChar in uString: + i = ord(uChar) + if (i < 0x80) and (i > 0x1F): + string = string + uChar + else: + string = string + "&#x" + hex(i)[2:] + ";" + return string + + +class StringRecord(object): + def toXML(self, writer, ttFont): + writer.begintag("StringRecord") + writer.newline() + writer.simpletag("labelID", value=self.labelID) + writer.comment(getLabelString(self.labelID)) + writer.newline() + writer.newline() + writer.simpletag("string", value=mapUTF8toXML(self.string)) + writer.newline() + writer.endtag("StringRecord") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + value = attrs["value"] + if name == "string": + self.string = mapXMLToUTF8(value) + else: + setattr(self, name, safeEval(value)) + + def compile(self, parentTable): + data = sstruct.pack(METAStringRecordFormat, self) + if parentTable.metaFlags == 0: + datum = struct.pack(">H", self.offset) + elif parentTable.metaFlags == 1: + datum = struct.pack(">L", self.offset) + data = data + datum + return data + + def __repr__(self): + return ( + "StringRecord [ labelID: " + + str(self.labelID) + + " aka " + + getLabelString(self.labelID) + + ", offset: " + + str(self.offset) + + ", length: " + + str(self.stringLen) + + ", string: " + + self.string + + " ]" + ) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/M_V_A_R_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/M_V_A_R_.py new file mode 100644 index 0000000000000000000000000000000000000000..c7e7e90fb49965b962f502a3ac9135a1c00b0374 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/M_V_A_R_.py @@ -0,0 +1,13 @@ +from .otBase import BaseTTXConverter + + +class table_M_V_A_R_(BaseTTXConverter): + """Metrics Variations table + + The ``MVAR`` table contains variation information for font-wide + metrics in a variable font. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/mvar + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/O_S_2f_2.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/O_S_2f_2.py new file mode 100644 index 0000000000000000000000000000000000000000..9a7e5f70bb99a37ad5f1260d62b7406df9361771 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/O_S_2f_2.py @@ -0,0 +1,752 @@ +from fontTools.misc import sstruct +from fontTools.misc.roundTools import otRound +from fontTools.misc.textTools import safeEval, num2binary, binary2num +from fontTools.ttLib.tables import DefaultTable +import bisect +import logging + + +log = logging.getLogger(__name__) + +# panose classification + +panoseFormat = """ + bFamilyType: B + bSerifStyle: B + bWeight: B + bProportion: B + bContrast: B + bStrokeVariation: B + bArmStyle: B + bLetterForm: B + bMidline: B + bXHeight: B +""" + + +class Panose(object): + def __init__(self, **kwargs): + _, names, _ = sstruct.getformat(panoseFormat) + for name in names: + setattr(self, name, kwargs.pop(name, 0)) + for k in kwargs: + raise TypeError(f"Panose() got an unexpected keyword argument {k!r}") + + def toXML(self, writer, ttFont): + formatstring, names, fixes = sstruct.getformat(panoseFormat) + for name in names: + writer.simpletag(name, value=getattr(self, name)) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + setattr(self, name, safeEval(attrs["value"])) + + +# 'sfnt' OS/2 and Windows Metrics table - 'OS/2' + +OS2_format_0 = """ + > # big endian + version: H # version + xAvgCharWidth: h # average character width + usWeightClass: H # degree of thickness of strokes + usWidthClass: H # aspect ratio + fsType: H # type flags + ySubscriptXSize: h # subscript horizontal font size + ySubscriptYSize: h # subscript vertical font size + ySubscriptXOffset: h # subscript x offset + ySubscriptYOffset: h # subscript y offset + ySuperscriptXSize: h # superscript horizontal font size + ySuperscriptYSize: h # superscript vertical font size + ySuperscriptXOffset: h # superscript x offset + ySuperscriptYOffset: h # superscript y offset + yStrikeoutSize: h # strikeout size + yStrikeoutPosition: h # strikeout position + sFamilyClass: h # font family class and subclass + panose: 10s # panose classification number + ulUnicodeRange1: L # character range + ulUnicodeRange2: L # character range + ulUnicodeRange3: L # character range + ulUnicodeRange4: L # character range + achVendID: 4s # font vendor identification + fsSelection: H # font selection flags + usFirstCharIndex: H # first unicode character index + usLastCharIndex: H # last unicode character index + sTypoAscender: h # typographic ascender + sTypoDescender: h # typographic descender + sTypoLineGap: h # typographic line gap + usWinAscent: H # Windows ascender + usWinDescent: H # Windows descender +""" + +OS2_format_1_addition = """ + ulCodePageRange1: L + ulCodePageRange2: L +""" + +OS2_format_2_addition = ( + OS2_format_1_addition + + """ + sxHeight: h + sCapHeight: h + usDefaultChar: H + usBreakChar: H + usMaxContext: H +""" +) + +OS2_format_5_addition = ( + OS2_format_2_addition + + """ + usLowerOpticalPointSize: H + usUpperOpticalPointSize: H +""" +) + +bigendian = " > # big endian\n" + +OS2_format_1 = OS2_format_0 + OS2_format_1_addition +OS2_format_2 = OS2_format_0 + OS2_format_2_addition +OS2_format_5 = OS2_format_0 + OS2_format_5_addition +OS2_format_1_addition = bigendian + OS2_format_1_addition +OS2_format_2_addition = bigendian + OS2_format_2_addition +OS2_format_5_addition = bigendian + OS2_format_5_addition + + +class table_O_S_2f_2(DefaultTable.DefaultTable): + """OS/2 and Windows Metrics table + + The ``OS/2`` table contains a variety of font-wide metrics and + parameters that may be useful to an operating system or other + software for system-integration purposes. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/os2 + """ + + dependencies = ["head"] + + def decompile(self, data, ttFont): + dummy, data = sstruct.unpack2(OS2_format_0, data, self) + + if self.version == 1: + dummy, data = sstruct.unpack2(OS2_format_1_addition, data, self) + elif self.version in (2, 3, 4): + dummy, data = sstruct.unpack2(OS2_format_2_addition, data, self) + elif self.version == 5: + dummy, data = sstruct.unpack2(OS2_format_5_addition, data, self) + self.usLowerOpticalPointSize /= 20 + self.usUpperOpticalPointSize /= 20 + elif self.version != 0: + from fontTools import ttLib + + raise ttLib.TTLibError( + "unknown format for OS/2 table: version %s" % self.version + ) + if len(data): + log.warning("too much 'OS/2' table data") + + self.panose = sstruct.unpack(panoseFormat, self.panose, Panose()) + + def compile(self, ttFont): + self.updateFirstAndLastCharIndex(ttFont) + panose = self.panose + head = ttFont["head"] + if (self.fsSelection & 1) and not (head.macStyle & 1 << 1): + log.warning( + "fsSelection bit 0 (italic) and " + "head table macStyle bit 1 (italic) should match" + ) + if (self.fsSelection & 1 << 5) and not (head.macStyle & 1): + log.warning( + "fsSelection bit 5 (bold) and " + "head table macStyle bit 0 (bold) should match" + ) + if (self.fsSelection & 1 << 6) and (self.fsSelection & 1 + (1 << 5)): + log.warning( + "fsSelection bit 6 (regular) is set, " + "bits 0 (italic) and 5 (bold) must be clear" + ) + if self.version < 4 and self.fsSelection & 0b1110000000: + log.warning( + "fsSelection bits 7, 8 and 9 are only defined in " + "OS/2 table version 4 and up: version %s", + self.version, + ) + self.panose = sstruct.pack(panoseFormat, self.panose) + if self.version == 0: + data = sstruct.pack(OS2_format_0, self) + elif self.version == 1: + data = sstruct.pack(OS2_format_1, self) + elif self.version in (2, 3, 4): + data = sstruct.pack(OS2_format_2, self) + elif self.version == 5: + d = self.__dict__.copy() + d["usLowerOpticalPointSize"] = round(self.usLowerOpticalPointSize * 20) + d["usUpperOpticalPointSize"] = round(self.usUpperOpticalPointSize * 20) + data = sstruct.pack(OS2_format_5, d) + else: + from fontTools import ttLib + + raise ttLib.TTLibError( + "unknown format for OS/2 table: version %s" % self.version + ) + self.panose = panose + return data + + def toXML(self, writer, ttFont): + writer.comment( + "The fields 'usFirstCharIndex' and 'usLastCharIndex'\n" + "will be recalculated by the compiler" + ) + writer.newline() + if self.version == 1: + format = OS2_format_1 + elif self.version in (2, 3, 4): + format = OS2_format_2 + elif self.version == 5: + format = OS2_format_5 + else: + format = OS2_format_0 + formatstring, names, fixes = sstruct.getformat(format) + for name in names: + value = getattr(self, name) + if name == "panose": + writer.begintag("panose") + writer.newline() + value.toXML(writer, ttFont) + writer.endtag("panose") + elif name in ( + "ulUnicodeRange1", + "ulUnicodeRange2", + "ulUnicodeRange3", + "ulUnicodeRange4", + "ulCodePageRange1", + "ulCodePageRange2", + ): + writer.simpletag(name, value=num2binary(value)) + elif name in ("fsType", "fsSelection"): + writer.simpletag(name, value=num2binary(value, 16)) + elif name == "achVendID": + writer.simpletag(name, value=repr(value)[1:-1]) + else: + writer.simpletag(name, value=value) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "panose": + self.panose = panose = Panose() + for element in content: + if isinstance(element, tuple): + name, attrs, content = element + panose.fromXML(name, attrs, content, ttFont) + elif name in ( + "ulUnicodeRange1", + "ulUnicodeRange2", + "ulUnicodeRange3", + "ulUnicodeRange4", + "ulCodePageRange1", + "ulCodePageRange2", + "fsType", + "fsSelection", + ): + setattr(self, name, binary2num(attrs["value"])) + elif name == "achVendID": + setattr(self, name, safeEval("'''" + attrs["value"] + "'''")) + else: + setattr(self, name, safeEval(attrs["value"])) + + def updateFirstAndLastCharIndex(self, ttFont): + if "cmap" not in ttFont: + return + codes = set() + for table in getattr(ttFont["cmap"], "tables", []): + if table.isUnicode(): + codes.update(table.cmap.keys()) + if codes: + minCode = min(codes) + maxCode = max(codes) + # USHORT cannot hold codepoints greater than 0xFFFF + self.usFirstCharIndex = min(0xFFFF, minCode) + self.usLastCharIndex = min(0xFFFF, maxCode) + + # misspelled attributes kept for legacy reasons + + @property + def usMaxContex(self): + return self.usMaxContext + + @usMaxContex.setter + def usMaxContex(self, value): + self.usMaxContext = value + + @property + def fsFirstCharIndex(self): + return self.usFirstCharIndex + + @fsFirstCharIndex.setter + def fsFirstCharIndex(self, value): + self.usFirstCharIndex = value + + @property + def fsLastCharIndex(self): + return self.usLastCharIndex + + @fsLastCharIndex.setter + def fsLastCharIndex(self, value): + self.usLastCharIndex = value + + def getUnicodeRanges(self): + """Return the set of 'ulUnicodeRange*' bits currently enabled.""" + bits = set() + ul1, ul2 = self.ulUnicodeRange1, self.ulUnicodeRange2 + ul3, ul4 = self.ulUnicodeRange3, self.ulUnicodeRange4 + for i in range(32): + if ul1 & (1 << i): + bits.add(i) + if ul2 & (1 << i): + bits.add(i + 32) + if ul3 & (1 << i): + bits.add(i + 64) + if ul4 & (1 << i): + bits.add(i + 96) + return bits + + def setUnicodeRanges(self, bits): + """Set the 'ulUnicodeRange*' fields to the specified 'bits'.""" + ul1, ul2, ul3, ul4 = 0, 0, 0, 0 + for bit in bits: + if 0 <= bit < 32: + ul1 |= 1 << bit + elif 32 <= bit < 64: + ul2 |= 1 << (bit - 32) + elif 64 <= bit < 96: + ul3 |= 1 << (bit - 64) + elif 96 <= bit < 123: + ul4 |= 1 << (bit - 96) + else: + raise ValueError("expected 0 <= int <= 122, found: %r" % bit) + self.ulUnicodeRange1, self.ulUnicodeRange2 = ul1, ul2 + self.ulUnicodeRange3, self.ulUnicodeRange4 = ul3, ul4 + + def recalcUnicodeRanges(self, ttFont, pruneOnly=False): + """Intersect the codepoints in the font's Unicode cmap subtables with + the Unicode block ranges defined in the OpenType specification (v1.7), + and set the respective 'ulUnicodeRange*' bits if there is at least ONE + intersection. + If 'pruneOnly' is True, only clear unused bits with NO intersection. + """ + unicodes = set() + for table in ttFont["cmap"].tables: + if table.isUnicode(): + unicodes.update(table.cmap.keys()) + if pruneOnly: + empty = intersectUnicodeRanges(unicodes, inverse=True) + bits = self.getUnicodeRanges() - empty + else: + bits = intersectUnicodeRanges(unicodes) + self.setUnicodeRanges(bits) + return bits + + def getCodePageRanges(self): + """Return the set of 'ulCodePageRange*' bits currently enabled.""" + bits = set() + if self.version < 1: + return bits + ul1, ul2 = self.ulCodePageRange1, self.ulCodePageRange2 + for i in range(32): + if ul1 & (1 << i): + bits.add(i) + if ul2 & (1 << i): + bits.add(i + 32) + return bits + + def setCodePageRanges(self, bits): + """Set the 'ulCodePageRange*' fields to the specified 'bits'.""" + ul1, ul2 = 0, 0 + for bit in bits: + if 0 <= bit < 32: + ul1 |= 1 << bit + elif 32 <= bit < 64: + ul2 |= 1 << (bit - 32) + else: + raise ValueError(f"expected 0 <= int <= 63, found: {bit:r}") + if self.version < 1: + self.version = 1 + self.ulCodePageRange1, self.ulCodePageRange2 = ul1, ul2 + + def recalcCodePageRanges(self, ttFont, pruneOnly=False): + unicodes = set() + for table in ttFont["cmap"].tables: + if table.isUnicode(): + unicodes.update(table.cmap.keys()) + bits = calcCodePageRanges(unicodes) + if pruneOnly: + bits &= self.getCodePageRanges() + # when no codepage ranges can be enabled, fall back to enabling bit 0 + # (Latin 1) so that the font works in MS Word: + # https://github.com/googlei18n/fontmake/issues/468 + if not bits: + bits = {0} + self.setCodePageRanges(bits) + return bits + + def recalcAvgCharWidth(self, ttFont): + """Recalculate xAvgCharWidth using metrics from ttFont's 'hmtx' table. + + Set it to 0 if the unlikely event 'hmtx' table is not found. + """ + avg_width = 0 + hmtx = ttFont.get("hmtx") + if hmtx is not None: + widths = [width for width, _ in hmtx.metrics.values() if width > 0] + if widths: + avg_width = otRound(sum(widths) / len(widths)) + self.xAvgCharWidth = avg_width + return avg_width + + +# Unicode ranges data from the OpenType OS/2 table specification v1.7 + +OS2_UNICODE_RANGES = ( + (("Basic Latin", (0x0000, 0x007F)),), + (("Latin-1 Supplement", (0x0080, 0x00FF)),), + (("Latin Extended-A", (0x0100, 0x017F)),), + (("Latin Extended-B", (0x0180, 0x024F)),), + ( + ("IPA Extensions", (0x0250, 0x02AF)), + ("Phonetic Extensions", (0x1D00, 0x1D7F)), + ("Phonetic Extensions Supplement", (0x1D80, 0x1DBF)), + ), + ( + ("Spacing Modifier Letters", (0x02B0, 0x02FF)), + ("Modifier Tone Letters", (0xA700, 0xA71F)), + ), + ( + ("Combining Diacritical Marks", (0x0300, 0x036F)), + ("Combining Diacritical Marks Supplement", (0x1DC0, 0x1DFF)), + ), + (("Greek and Coptic", (0x0370, 0x03FF)),), + (("Coptic", (0x2C80, 0x2CFF)),), + ( + ("Cyrillic", (0x0400, 0x04FF)), + ("Cyrillic Supplement", (0x0500, 0x052F)), + ("Cyrillic Extended-A", (0x2DE0, 0x2DFF)), + ("Cyrillic Extended-B", (0xA640, 0xA69F)), + ), + (("Armenian", (0x0530, 0x058F)),), + (("Hebrew", (0x0590, 0x05FF)),), + (("Vai", (0xA500, 0xA63F)),), + (("Arabic", (0x0600, 0x06FF)), ("Arabic Supplement", (0x0750, 0x077F))), + (("NKo", (0x07C0, 0x07FF)),), + (("Devanagari", (0x0900, 0x097F)),), + (("Bengali", (0x0980, 0x09FF)),), + (("Gurmukhi", (0x0A00, 0x0A7F)),), + (("Gujarati", (0x0A80, 0x0AFF)),), + (("Oriya", (0x0B00, 0x0B7F)),), + (("Tamil", (0x0B80, 0x0BFF)),), + (("Telugu", (0x0C00, 0x0C7F)),), + (("Kannada", (0x0C80, 0x0CFF)),), + (("Malayalam", (0x0D00, 0x0D7F)),), + (("Thai", (0x0E00, 0x0E7F)),), + (("Lao", (0x0E80, 0x0EFF)),), + (("Georgian", (0x10A0, 0x10FF)), ("Georgian Supplement", (0x2D00, 0x2D2F))), + (("Balinese", (0x1B00, 0x1B7F)),), + (("Hangul Jamo", (0x1100, 0x11FF)),), + ( + ("Latin Extended Additional", (0x1E00, 0x1EFF)), + ("Latin Extended-C", (0x2C60, 0x2C7F)), + ("Latin Extended-D", (0xA720, 0xA7FF)), + ), + (("Greek Extended", (0x1F00, 0x1FFF)),), + ( + ("General Punctuation", (0x2000, 0x206F)), + ("Supplemental Punctuation", (0x2E00, 0x2E7F)), + ), + (("Superscripts And Subscripts", (0x2070, 0x209F)),), + (("Currency Symbols", (0x20A0, 0x20CF)),), + (("Combining Diacritical Marks For Symbols", (0x20D0, 0x20FF)),), + (("Letterlike Symbols", (0x2100, 0x214F)),), + (("Number Forms", (0x2150, 0x218F)),), + ( + ("Arrows", (0x2190, 0x21FF)), + ("Supplemental Arrows-A", (0x27F0, 0x27FF)), + ("Supplemental Arrows-B", (0x2900, 0x297F)), + ("Miscellaneous Symbols and Arrows", (0x2B00, 0x2BFF)), + ), + ( + ("Mathematical Operators", (0x2200, 0x22FF)), + ("Supplemental Mathematical Operators", (0x2A00, 0x2AFF)), + ("Miscellaneous Mathematical Symbols-A", (0x27C0, 0x27EF)), + ("Miscellaneous Mathematical Symbols-B", (0x2980, 0x29FF)), + ), + (("Miscellaneous Technical", (0x2300, 0x23FF)),), + (("Control Pictures", (0x2400, 0x243F)),), + (("Optical Character Recognition", (0x2440, 0x245F)),), + (("Enclosed Alphanumerics", (0x2460, 0x24FF)),), + (("Box Drawing", (0x2500, 0x257F)),), + (("Block Elements", (0x2580, 0x259F)),), + (("Geometric Shapes", (0x25A0, 0x25FF)),), + (("Miscellaneous Symbols", (0x2600, 0x26FF)),), + (("Dingbats", (0x2700, 0x27BF)),), + (("CJK Symbols And Punctuation", (0x3000, 0x303F)),), + (("Hiragana", (0x3040, 0x309F)),), + ( + ("Katakana", (0x30A0, 0x30FF)), + ("Katakana Phonetic Extensions", (0x31F0, 0x31FF)), + ), + (("Bopomofo", (0x3100, 0x312F)), ("Bopomofo Extended", (0x31A0, 0x31BF))), + (("Hangul Compatibility Jamo", (0x3130, 0x318F)),), + (("Phags-pa", (0xA840, 0xA87F)),), + (("Enclosed CJK Letters And Months", (0x3200, 0x32FF)),), + (("CJK Compatibility", (0x3300, 0x33FF)),), + (("Hangul Syllables", (0xAC00, 0xD7AF)),), + (("Non-Plane 0 *", (0xD800, 0xDFFF)),), + (("Phoenician", (0x10900, 0x1091F)),), + ( + ("CJK Unified Ideographs", (0x4E00, 0x9FFF)), + ("CJK Radicals Supplement", (0x2E80, 0x2EFF)), + ("Kangxi Radicals", (0x2F00, 0x2FDF)), + ("Ideographic Description Characters", (0x2FF0, 0x2FFF)), + ("CJK Unified Ideographs Extension A", (0x3400, 0x4DBF)), + ("CJK Unified Ideographs Extension B", (0x20000, 0x2A6DF)), + ("Kanbun", (0x3190, 0x319F)), + ), + (("Private Use Area (plane 0)", (0xE000, 0xF8FF)),), + ( + ("CJK Strokes", (0x31C0, 0x31EF)), + ("CJK Compatibility Ideographs", (0xF900, 0xFAFF)), + ("CJK Compatibility Ideographs Supplement", (0x2F800, 0x2FA1F)), + ), + (("Alphabetic Presentation Forms", (0xFB00, 0xFB4F)),), + (("Arabic Presentation Forms-A", (0xFB50, 0xFDFF)),), + (("Combining Half Marks", (0xFE20, 0xFE2F)),), + ( + ("Vertical Forms", (0xFE10, 0xFE1F)), + ("CJK Compatibility Forms", (0xFE30, 0xFE4F)), + ), + (("Small Form Variants", (0xFE50, 0xFE6F)),), + (("Arabic Presentation Forms-B", (0xFE70, 0xFEFF)),), + (("Halfwidth And Fullwidth Forms", (0xFF00, 0xFFEF)),), + (("Specials", (0xFFF0, 0xFFFF)),), + (("Tibetan", (0x0F00, 0x0FFF)),), + (("Syriac", (0x0700, 0x074F)),), + (("Thaana", (0x0780, 0x07BF)),), + (("Sinhala", (0x0D80, 0x0DFF)),), + (("Myanmar", (0x1000, 0x109F)),), + ( + ("Ethiopic", (0x1200, 0x137F)), + ("Ethiopic Supplement", (0x1380, 0x139F)), + ("Ethiopic Extended", (0x2D80, 0x2DDF)), + ), + (("Cherokee", (0x13A0, 0x13FF)),), + (("Unified Canadian Aboriginal Syllabics", (0x1400, 0x167F)),), + (("Ogham", (0x1680, 0x169F)),), + (("Runic", (0x16A0, 0x16FF)),), + (("Khmer", (0x1780, 0x17FF)), ("Khmer Symbols", (0x19E0, 0x19FF))), + (("Mongolian", (0x1800, 0x18AF)),), + (("Braille Patterns", (0x2800, 0x28FF)),), + (("Yi Syllables", (0xA000, 0xA48F)), ("Yi Radicals", (0xA490, 0xA4CF))), + ( + ("Tagalog", (0x1700, 0x171F)), + ("Hanunoo", (0x1720, 0x173F)), + ("Buhid", (0x1740, 0x175F)), + ("Tagbanwa", (0x1760, 0x177F)), + ), + (("Old Italic", (0x10300, 0x1032F)),), + (("Gothic", (0x10330, 0x1034F)),), + (("Deseret", (0x10400, 0x1044F)),), + ( + ("Byzantine Musical Symbols", (0x1D000, 0x1D0FF)), + ("Musical Symbols", (0x1D100, 0x1D1FF)), + ("Ancient Greek Musical Notation", (0x1D200, 0x1D24F)), + ), + (("Mathematical Alphanumeric Symbols", (0x1D400, 0x1D7FF)),), + ( + ("Private Use (plane 15)", (0xF0000, 0xFFFFD)), + ("Private Use (plane 16)", (0x100000, 0x10FFFD)), + ), + ( + ("Variation Selectors", (0xFE00, 0xFE0F)), + ("Variation Selectors Supplement", (0xE0100, 0xE01EF)), + ), + (("Tags", (0xE0000, 0xE007F)),), + (("Limbu", (0x1900, 0x194F)),), + (("Tai Le", (0x1950, 0x197F)),), + (("New Tai Lue", (0x1980, 0x19DF)),), + (("Buginese", (0x1A00, 0x1A1F)),), + (("Glagolitic", (0x2C00, 0x2C5F)),), + (("Tifinagh", (0x2D30, 0x2D7F)),), + (("Yijing Hexagram Symbols", (0x4DC0, 0x4DFF)),), + (("Syloti Nagri", (0xA800, 0xA82F)),), + ( + ("Linear B Syllabary", (0x10000, 0x1007F)), + ("Linear B Ideograms", (0x10080, 0x100FF)), + ("Aegean Numbers", (0x10100, 0x1013F)), + ), + (("Ancient Greek Numbers", (0x10140, 0x1018F)),), + (("Ugaritic", (0x10380, 0x1039F)),), + (("Old Persian", (0x103A0, 0x103DF)),), + (("Shavian", (0x10450, 0x1047F)),), + (("Osmanya", (0x10480, 0x104AF)),), + (("Cypriot Syllabary", (0x10800, 0x1083F)),), + (("Kharoshthi", (0x10A00, 0x10A5F)),), + (("Tai Xuan Jing Symbols", (0x1D300, 0x1D35F)),), + ( + ("Cuneiform", (0x12000, 0x123FF)), + ("Cuneiform Numbers and Punctuation", (0x12400, 0x1247F)), + ), + (("Counting Rod Numerals", (0x1D360, 0x1D37F)),), + (("Sundanese", (0x1B80, 0x1BBF)),), + (("Lepcha", (0x1C00, 0x1C4F)),), + (("Ol Chiki", (0x1C50, 0x1C7F)),), + (("Saurashtra", (0xA880, 0xA8DF)),), + (("Kayah Li", (0xA900, 0xA92F)),), + (("Rejang", (0xA930, 0xA95F)),), + (("Cham", (0xAA00, 0xAA5F)),), + (("Ancient Symbols", (0x10190, 0x101CF)),), + (("Phaistos Disc", (0x101D0, 0x101FF)),), + ( + ("Carian", (0x102A0, 0x102DF)), + ("Lycian", (0x10280, 0x1029F)), + ("Lydian", (0x10920, 0x1093F)), + ), + (("Domino Tiles", (0x1F030, 0x1F09F)), ("Mahjong Tiles", (0x1F000, 0x1F02F))), +) + + +_unicodeStarts = [] +_unicodeValues = [None] + + +def _getUnicodeRanges(): + # build the ranges of codepoints for each unicode range bit, and cache result + if not _unicodeStarts: + unicodeRanges = [ + (start, (stop, bit)) + for bit, blocks in enumerate(OS2_UNICODE_RANGES) + for _, (start, stop) in blocks + ] + for start, (stop, bit) in sorted(unicodeRanges): + _unicodeStarts.append(start) + _unicodeValues.append((stop, bit)) + return _unicodeStarts, _unicodeValues + + +def intersectUnicodeRanges(unicodes, inverse=False): + """Intersect a sequence of (int) Unicode codepoints with the Unicode block + ranges defined in the OpenType specification v1.7, and return the set of + 'ulUnicodeRanges' bits for which there is at least ONE intersection. + If 'inverse' is True, return the the bits for which there is NO intersection. + + >>> intersectUnicodeRanges([0x0410]) == {9} + True + >>> intersectUnicodeRanges([0x0410, 0x1F000]) == {9, 57, 122} + True + >>> intersectUnicodeRanges([0x0410, 0x1F000], inverse=True) == ( + ... set(range(len(OS2_UNICODE_RANGES))) - {9, 57, 122}) + True + """ + unicodes = set(unicodes) + unicodestarts, unicodevalues = _getUnicodeRanges() + bits = set() + for code in unicodes: + stop, bit = unicodevalues[bisect.bisect(unicodestarts, code)] + if code <= stop: + bits.add(bit) + # The spec says that bit 57 ("Non Plane 0") implies that there's + # at least one codepoint beyond the BMP; so I also include all + # the non-BMP codepoints here + if any(0x10000 <= code < 0x110000 for code in unicodes): + bits.add(57) + return set(range(len(OS2_UNICODE_RANGES))) - bits if inverse else bits + + +def calcCodePageRanges(unicodes): + """Given a set of Unicode codepoints (integers), calculate the + corresponding OS/2 CodePage range bits. + This is a direct translation of FontForge implementation: + https://github.com/fontforge/fontforge/blob/7b2c074/fontforge/tottf.c#L3158 + """ + bits = set() + hasAscii = set(range(0x20, 0x7E)).issubset(unicodes) + hasLineart = ord("┤") in unicodes + + for uni in unicodes: + if uni == ord("Þ") and hasAscii: + bits.add(0) # Latin 1 + elif uni == ord("Ľ") and hasAscii: + bits.add(1) # Latin 2: Eastern Europe + if hasLineart: + bits.add(58) # Latin 2 + elif uni == ord("Б"): + bits.add(2) # Cyrillic + if ord("Ѕ") in unicodes and hasLineart: + bits.add(57) # IBM Cyrillic + if ord("╜") in unicodes and hasLineart: + bits.add(49) # MS-DOS Russian + elif uni == ord("Ά"): + bits.add(3) # Greek + if hasLineart and ord("½") in unicodes: + bits.add(48) # IBM Greek + if hasLineart and ord("√") in unicodes: + bits.add(60) # Greek, former 437 G + elif uni == ord("İ") and hasAscii: + bits.add(4) # Turkish + if hasLineart: + bits.add(56) # IBM turkish + elif uni == ord("א"): + bits.add(5) # Hebrew + if hasLineart and ord("√") in unicodes: + bits.add(53) # Hebrew + elif uni == ord("ر"): + bits.add(6) # Arabic + if ord("√") in unicodes: + bits.add(51) # Arabic + if hasLineart: + bits.add(61) # Arabic; ASMO 708 + elif uni == ord("ŗ") and hasAscii: + bits.add(7) # Windows Baltic + if hasLineart: + bits.add(59) # MS-DOS Baltic + elif uni == ord("₫") and hasAscii: + bits.add(8) # Vietnamese + elif uni == ord("ๅ"): + bits.add(16) # Thai + elif uni == ord("エ"): + bits.add(17) # JIS/Japan + elif uni == ord("ㄅ"): + bits.add(18) # Chinese: Simplified + elif uni == ord("ㄱ"): + bits.add(19) # Korean wansung + elif uni == ord("央"): + bits.add(20) # Chinese: Traditional + elif uni == ord("곴"): + bits.add(21) # Korean Johab + elif uni == ord("♥") and hasAscii: + bits.add(30) # OEM Character Set + # TODO: Symbol bit has a special meaning (check the spec), we need + # to confirm if this is wanted by default. + # elif chr(0xF000) <= char <= chr(0xF0FF): + # codepageRanges.add(31) # Symbol Character Set + elif uni == ord("þ") and hasAscii and hasLineart: + bits.add(54) # MS-DOS Icelandic + elif uni == ord("╚") and hasAscii: + bits.add(62) # WE/Latin 1 + bits.add(63) # US + elif hasAscii and hasLineart and ord("√") in unicodes: + if uni == ord("Å"): + bits.add(50) # MS-DOS Nordic + elif uni == ord("é"): + bits.add(52) # MS-DOS Canadian French + elif uni == ord("õ"): + bits.add(55) # MS-DOS Portuguese + + if hasAscii and ord("‰") in unicodes and ord("∑") in unicodes: + bits.add(29) # Macintosh Character Set (US Roman) + + return bits + + +if __name__ == "__main__": + import doctest, sys + + sys.exit(doctest.testmod().failed) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/S_I_N_G_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/S_I_N_G_.py new file mode 100644 index 0000000000000000000000000000000000000000..1a367a92f2f4b91fb1a29dd257e08d982193deac --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/S_I_N_G_.py @@ -0,0 +1,99 @@ +from fontTools.misc import sstruct +from fontTools.misc.textTools import bytechr, byteord, tobytes, tostr, safeEval +from . import DefaultTable + +SINGFormat = """ + > # big endian + tableVersionMajor: H + tableVersionMinor: H + glyphletVersion: H + permissions: h + mainGID: H + unitsPerEm: H + vertAdvance: h + vertOrigin: h + uniqueName: 28s + METAMD5: 16s + nameLength: 1s +""" +# baseGlyphName is a byte string which follows the record above. + + +class table_S_I_N_G_(DefaultTable.DefaultTable): + """Glyphlets SING table + + The ``SING`` table is used by Adobe's SING Glyphlets. + + See also https://web.archive.org/web/20080627183635/http://www.adobe.com/devnet/opentype/gdk/topic.html + """ + + dependencies = [] + + def decompile(self, data, ttFont): + dummy, rest = sstruct.unpack2(SINGFormat, data, self) + self.uniqueName = self.decompileUniqueName(self.uniqueName) + self.nameLength = byteord(self.nameLength) + assert len(rest) == self.nameLength + self.baseGlyphName = tostr(rest) + + rawMETAMD5 = self.METAMD5 + self.METAMD5 = "[" + hex(byteord(self.METAMD5[0])) + for char in rawMETAMD5[1:]: + self.METAMD5 = self.METAMD5 + ", " + hex(byteord(char)) + self.METAMD5 = self.METAMD5 + "]" + + def decompileUniqueName(self, data): + name = "" + for char in data: + val = byteord(char) + if val == 0: + break + if (val > 31) or (val < 128): + name += chr(val) + else: + octString = oct(val) + if len(octString) > 3: + octString = octString[1:] # chop off that leading zero. + elif len(octString) < 3: + octString.zfill(3) + name += "\\" + octString + return name + + def compile(self, ttFont): + d = self.__dict__.copy() + d["nameLength"] = bytechr(len(self.baseGlyphName)) + d["uniqueName"] = self.compilecompileUniqueName(self.uniqueName, 28) + METAMD5List = eval(self.METAMD5) + d["METAMD5"] = b"" + for val in METAMD5List: + d["METAMD5"] += bytechr(val) + assert len(d["METAMD5"]) == 16, "Failed to pack 16 byte MD5 hash in SING table" + data = sstruct.pack(SINGFormat, d) + data = data + tobytes(self.baseGlyphName) + return data + + def compilecompileUniqueName(self, name, length): + nameLen = len(name) + if length <= nameLen: + name = name[: length - 1] + "\000" + else: + name += (nameLen - length) * "\000" + return name + + def toXML(self, writer, ttFont): + writer.comment("Most of this table will be recalculated by the compiler") + writer.newline() + formatstring, names, fixes = sstruct.getformat(SINGFormat) + for name in names: + value = getattr(self, name) + writer.simpletag(name, value=value) + writer.newline() + writer.simpletag("baseGlyphName", value=self.baseGlyphName) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + value = attrs["value"] + if name in ["uniqueName", "METAMD5", "baseGlyphName"]: + setattr(self, name, value) + else: + setattr(self, name, safeEval(value)) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/S_T_A_T_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/S_T_A_T_.py new file mode 100644 index 0000000000000000000000000000000000000000..86e1271a9817ecb71b663e60ffa685cbf9205bd5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/S_T_A_T_.py @@ -0,0 +1,15 @@ +from .otBase import BaseTTXConverter + + +class table_S_T_A_T_(BaseTTXConverter): + """Style Attributes table + + The ``STAT`` table records stylistic or typeface-design attributes that + differentiate the individual fonts within a font family from one another. + Those attributes can be used to assist users when navigating the style + variations of a variable font or a family of static fonts. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/stat + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/S_V_G_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/S_V_G_.py new file mode 100644 index 0000000000000000000000000000000000000000..76e860c5f627d7b6ed0a3d8fef29efde7b647a70 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/S_V_G_.py @@ -0,0 +1,223 @@ +"""Compiles/decompiles SVG table. + +https://docs.microsoft.com/en-us/typography/opentype/spec/svg + +The XML format is: + +.. code-block:: xml + + + + <complete SVG doc> ]] + </svgDoc> + ... + <svgDoc endGlyphID="n" startGlyphID="m"> + <![CDATA[ <complete SVG doc> ]] + </svgDoc> + </SVG> +""" + +from fontTools.misc.textTools import bytesjoin, safeEval, strjoin, tobytes, tostr +from fontTools.misc import sstruct +from . import DefaultTable +from collections.abc import Sequence +from dataclasses import dataclass, astuple +from io import BytesIO +import struct +import logging + + +log = logging.getLogger(__name__) + + +SVG_format_0 = """ + > # big endian + version: H + offsetToSVGDocIndex: L + reserved: L +""" + +SVG_format_0Size = sstruct.calcsize(SVG_format_0) + +doc_index_entry_format_0 = """ + > # big endian + startGlyphID: H + endGlyphID: H + svgDocOffset: L + svgDocLength: L +""" + +doc_index_entry_format_0Size = sstruct.calcsize(doc_index_entry_format_0) + + +class table_S_V_G_(DefaultTable.DefaultTable): + """Scalable Vector Graphics table + + The ``SVG`` table contains representations for glyphs in the SVG + image format. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/stat + """ + + def decompile(self, data, ttFont): + self.docList = [] + # Version 0 is the standardized version of the table; and current. + # https://www.microsoft.com/typography/otspec/svg.htm + sstruct.unpack(SVG_format_0, data[:SVG_format_0Size], self) + if self.version != 0: + log.warning( + "Unknown SVG table version '%s'. Decompiling as version 0.", + self.version, + ) + # read in SVG Documents Index + # data starts with the first entry of the entry list. + pos = subTableStart = self.offsetToSVGDocIndex + self.numEntries = struct.unpack(">H", data[pos : pos + 2])[0] + pos += 2 + if self.numEntries > 0: + data2 = data[pos:] + entries = [] + for i in range(self.numEntries): + record_data = data2[ + i + * doc_index_entry_format_0Size : (i + 1) + * doc_index_entry_format_0Size + ] + docIndexEntry = sstruct.unpack( + doc_index_entry_format_0, record_data, DocumentIndexEntry() + ) + entries.append(docIndexEntry) + + for entry in entries: + start = entry.svgDocOffset + subTableStart + end = start + entry.svgDocLength + doc = data[start:end] + compressed = False + if doc.startswith(b"\x1f\x8b"): + import gzip + + bytesIO = BytesIO(doc) + with gzip.GzipFile(None, "r", fileobj=bytesIO) as gunzipper: + doc = gunzipper.read() + del bytesIO + compressed = True + doc = tostr(doc, "utf_8") + self.docList.append( + SVGDocument(doc, entry.startGlyphID, entry.endGlyphID, compressed) + ) + + def compile(self, ttFont): + version = 0 + offsetToSVGDocIndex = ( + SVG_format_0Size # I start the SVGDocIndex right after the header. + ) + # get SGVDoc info. + docList = [] + entryList = [] + numEntries = len(self.docList) + datum = struct.pack(">H", numEntries) + entryList.append(datum) + curOffset = len(datum) + doc_index_entry_format_0Size * numEntries + seenDocs = {} + allCompressed = getattr(self, "compressed", False) + for i, doc in enumerate(self.docList): + if isinstance(doc, (list, tuple)): + doc = SVGDocument(*doc) + self.docList[i] = doc + docBytes = tobytes(doc.data, encoding="utf_8") + if (allCompressed or doc.compressed) and not docBytes.startswith( + b"\x1f\x8b" + ): + import gzip + + bytesIO = BytesIO() + # mtime=0 strips the useless timestamp and makes gzip output reproducible; + # equivalent to `gzip -n` + with gzip.GzipFile(None, "w", fileobj=bytesIO, mtime=0) as gzipper: + gzipper.write(docBytes) + gzipped = bytesIO.getvalue() + if len(gzipped) < len(docBytes): + docBytes = gzipped + del gzipped, bytesIO + docLength = len(docBytes) + if docBytes in seenDocs: + docOffset = seenDocs[docBytes] + else: + docOffset = curOffset + curOffset += docLength + seenDocs[docBytes] = docOffset + docList.append(docBytes) + entry = struct.pack( + ">HHLL", doc.startGlyphID, doc.endGlyphID, docOffset, docLength + ) + entryList.append(entry) + entryList.extend(docList) + svgDocData = bytesjoin(entryList) + + reserved = 0 + header = struct.pack(">HLL", version, offsetToSVGDocIndex, reserved) + data = [header, svgDocData] + data = bytesjoin(data) + return data + + def toXML(self, writer, ttFont): + for i, doc in enumerate(self.docList): + if isinstance(doc, (list, tuple)): + doc = SVGDocument(*doc) + self.docList[i] = doc + attrs = {"startGlyphID": doc.startGlyphID, "endGlyphID": doc.endGlyphID} + if doc.compressed: + attrs["compressed"] = 1 + writer.begintag("svgDoc", **attrs) + writer.newline() + writer.writecdata(doc.data) + writer.newline() + writer.endtag("svgDoc") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "svgDoc": + if not hasattr(self, "docList"): + self.docList = [] + doc = strjoin(content) + doc = doc.strip() + startGID = int(attrs["startGlyphID"]) + endGID = int(attrs["endGlyphID"]) + compressed = bool(safeEval(attrs.get("compressed", "0"))) + self.docList.append(SVGDocument(doc, startGID, endGID, compressed)) + else: + log.warning("Unknown %s %s", name, content) + + +class DocumentIndexEntry(object): + def __init__(self): + self.startGlyphID = None # USHORT + self.endGlyphID = None # USHORT + self.svgDocOffset = None # ULONG + self.svgDocLength = None # ULONG + + def __repr__(self): + return ( + "startGlyphID: %s, endGlyphID: %s, svgDocOffset: %s, svgDocLength: %s" + % (self.startGlyphID, self.endGlyphID, self.svgDocOffset, self.svgDocLength) + ) + + +@dataclass +class SVGDocument(Sequence): + data: str + startGlyphID: int + endGlyphID: int + compressed: bool = False + + # Previously, the SVG table's docList attribute contained a lists of 3 items: + # [doc, startGlyphID, endGlyphID]; later, we added a `compressed` attribute. + # For backward compatibility with code that depends of them being sequences of + # fixed length=3, we subclass the Sequence abstract base class and pretend only + # the first three items are present. 'compressed' is only accessible via named + # attribute lookup like regular dataclasses: i.e. `doc.compressed`, not `doc[3]` + def __getitem__(self, index): + return astuple(self)[:3][index] + + def __len__(self): + return 3 diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/S__i_l_f.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/S__i_l_f.py new file mode 100644 index 0000000000000000000000000000000000000000..e8090af1e520737919e6041c259c112a15695035 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/S__i_l_f.py @@ -0,0 +1,1040 @@ +from fontTools.misc import sstruct +from fontTools.misc.fixedTools import floatToFixedToStr +from fontTools.misc.textTools import byteord, safeEval + +# from itertools import * +from . import DefaultTable +from . import grUtils +from array import array +from functools import reduce +import struct, re, sys + +Silf_hdr_format = """ + > + version: 16.16F +""" + +Silf_hdr_format_3 = """ + > + version: 16.16F + compilerVersion: L + numSilf: H + x + x +""" + +Silf_part1_format_v3 = """ + > + ruleVersion: 16.16F + passOffset: H + pseudosOffset: H +""" + +Silf_part1_format = """ + > + maxGlyphID: H + extraAscent: h + extraDescent: h + numPasses: B + iSubst: B + iPos: B + iJust: B + iBidi: B + flags: B + maxPreContext: B + maxPostContext: B + attrPseudo: B + attrBreakWeight: B + attrDirectionality: B + attrMirroring: B + attrSkipPasses: B + numJLevels: B +""" + +Silf_justify_format = """ + > + attrStretch: B + attrShrink: B + attrStep: B + attrWeight: B + runto: B + x + x + x +""" + +Silf_part2_format = """ + > + numLigComp: H + numUserDefn: B + maxCompPerLig: B + direction: B + attCollisions: B + x + x + x + numCritFeatures: B +""" + +Silf_pseudomap_format = """ + > + unicode: L + nPseudo: H +""" + +Silf_pseudomap_format_h = """ + > + unicode: H + nPseudo: H +""" + +Silf_classmap_format = """ + > + numClass: H + numLinear: H +""" + +Silf_lookupclass_format = """ + > + numIDs: H + searchRange: H + entrySelector: H + rangeShift: H +""" + +Silf_lookuppair_format = """ + > + glyphId: H + index: H +""" + +Silf_pass_format = """ + > + flags: B + maxRuleLoop: B + maxRuleContext: B + maxBackup: B + numRules: H + fsmOffset: H + pcCode: L + rcCode: L + aCode: L + oDebug: L + numRows: H + numTransitional: H + numSuccess: H + numColumns: H +""" + +aCode_info = ( + ("NOP", 0), + ("PUSH_BYTE", "b"), + ("PUSH_BYTE_U", "B"), + ("PUSH_SHORT", ">h"), + ("PUSH_SHORT_U", ">H"), + ("PUSH_LONG", ">L"), + ("ADD", 0), + ("SUB", 0), + ("MUL", 0), + ("DIV", 0), + ("MIN", 0), + ("MAX", 0), + ("NEG", 0), + ("TRUNC8", 0), + ("TRUNC16", 0), + ("COND", 0), + ("AND", 0), # x10 + ("OR", 0), + ("NOT", 0), + ("EQUAL", 0), + ("NOT_EQ", 0), + ("LESS", 0), + ("GTR", 0), + ("LESS_EQ", 0), + ("GTR_EQ", 0), + ("NEXT", 0), + ("NEXT_N", "b"), + ("COPY_NEXT", 0), + ("PUT_GLYPH_8BIT_OBS", "B"), + ("PUT_SUBS_8BIT_OBS", "bBB"), + ("PUT_COPY", "b"), + ("INSERT", 0), + ("DELETE", 0), # x20 + ("ASSOC", -1), + ("CNTXT_ITEM", "bB"), + ("ATTR_SET", "B"), + ("ATTR_ADD", "B"), + ("ATTR_SUB", "B"), + ("ATTR_SET_SLOT", "B"), + ("IATTR_SET_SLOT", "BB"), + ("PUSH_SLOT_ATTR", "Bb"), + ("PUSH_GLYPH_ATTR_OBS", "Bb"), + ("PUSH_GLYPH_METRIC", "Bbb"), + ("PUSH_FEAT", "Bb"), + ("PUSH_ATT_TO_GATTR_OBS", "Bb"), + ("PUSH_ATT_TO_GLYPH_METRIC", "Bbb"), + ("PUSH_ISLOT_ATTR", "Bbb"), + ("PUSH_IGLYPH_ATTR", "Bbb"), + ("POP_RET", 0), # x30 + ("RET_ZERO", 0), + ("RET_TRUE", 0), + ("IATTR_SET", "BB"), + ("IATTR_ADD", "BB"), + ("IATTR_SUB", "BB"), + ("PUSH_PROC_STATE", "B"), + ("PUSH_VERSION", 0), + ("PUT_SUBS", ">bHH"), + ("PUT_SUBS2", 0), + ("PUT_SUBS3", 0), + ("PUT_GLYPH", ">H"), + ("PUSH_GLYPH_ATTR", ">Hb"), + ("PUSH_ATT_TO_GLYPH_ATTR", ">Hb"), + ("BITOR", 0), + ("BITAND", 0), + ("BITNOT", 0), # x40 + ("BITSET", ">HH"), + ("SET_FEAT", "Bb"), +) +aCode_map = dict([(x[0], (i, x[1])) for i, x in enumerate(aCode_info)]) + + +def disassemble(aCode): + codelen = len(aCode) + pc = 0 + res = [] + while pc < codelen: + opcode = byteord(aCode[pc : pc + 1]) + if opcode > len(aCode_info): + instr = aCode_info[0] + else: + instr = aCode_info[opcode] + pc += 1 + if instr[1] != 0 and pc >= codelen: + return res + if instr[1] == -1: + count = byteord(aCode[pc]) + fmt = "%dB" % count + pc += 1 + elif instr[1] == 0: + fmt = "" + else: + fmt = instr[1] + if fmt == "": + res.append(instr[0]) + continue + parms = struct.unpack_from(fmt, aCode[pc:]) + res.append(instr[0] + "(" + ", ".join(map(str, parms)) + ")") + pc += struct.calcsize(fmt) + return res + + +instre = re.compile(r"^\s*([^(]+)\s*(?:\(([^)]+)\))?") + + +def assemble(instrs): + res = b"" + for inst in instrs: + m = instre.match(inst) + if not m or not m.group(1) in aCode_map: + continue + opcode, parmfmt = aCode_map[m.group(1)] + res += struct.pack("B", opcode) + if m.group(2): + if parmfmt == 0: + continue + parms = [int(x) for x in re.split(r",\s*", m.group(2))] + if parmfmt == -1: + l = len(parms) + res += struct.pack(("%dB" % (l + 1)), l, *parms) + else: + res += struct.pack(parmfmt, *parms) + return res + + +def writecode(tag, writer, instrs): + writer.begintag(tag) + writer.newline() + for l in disassemble(instrs): + writer.write(l) + writer.newline() + writer.endtag(tag) + writer.newline() + + +def readcode(content): + res = [] + for e in content_string(content).split("\n"): + e = e.strip() + if not len(e): + continue + res.append(e) + return assemble(res) + + +attrs_info = ( + "flags", + "extraAscent", + "extraDescent", + "maxGlyphID", + "numLigComp", + "numUserDefn", + "maxCompPerLig", + "direction", + "lbGID", +) +attrs_passindexes = ("iSubst", "iPos", "iJust", "iBidi") +attrs_contexts = ("maxPreContext", "maxPostContext") +attrs_attributes = ( + "attrPseudo", + "attrBreakWeight", + "attrDirectionality", + "attrMirroring", + "attrSkipPasses", + "attCollisions", +) +pass_attrs_info = ( + "flags", + "maxRuleLoop", + "maxRuleContext", + "maxBackup", + "minRulePreContext", + "maxRulePreContext", + "collisionThreshold", +) +pass_attrs_fsm = ("numRows", "numTransitional", "numSuccess", "numColumns") + + +def writesimple(tag, self, writer, *attrkeys): + attrs = dict([(k, getattr(self, k)) for k in attrkeys]) + writer.simpletag(tag, **attrs) + writer.newline() + + +def getSimple(self, attrs, *attr_list): + for k in attr_list: + if k in attrs: + setattr(self, k, int(safeEval(attrs[k]))) + + +def content_string(contents): + res = "" + for element in contents: + if isinstance(element, tuple): + continue + res += element + return res.strip() + + +def wrapline(writer, dat, length=80): + currline = "" + for d in dat: + if len(currline) > length: + writer.write(currline[:-1]) + writer.newline() + currline = "" + currline += d + " " + if len(currline): + writer.write(currline[:-1]) + writer.newline() + + +class _Object: + pass + + +class table_S__i_l_f(DefaultTable.DefaultTable): + """Graphite Rules table + + See also https://graphite.sil.org/graphite_techAbout#graphite-font-tables + """ + + def __init__(self, tag=None): + DefaultTable.DefaultTable.__init__(self, tag) + self.silfs = [] + + def decompile(self, data, ttFont): + sstruct.unpack2(Silf_hdr_format, data, self) + self.version = float(floatToFixedToStr(self.version, precisionBits=16)) + if self.version >= 5.0: + (data, self.scheme) = grUtils.decompress(data) + sstruct.unpack2(Silf_hdr_format_3, data, self) + base = sstruct.calcsize(Silf_hdr_format_3) + elif self.version < 3.0: + self.numSilf = struct.unpack(">H", data[4:6]) + self.scheme = 0 + self.compilerVersion = 0 + base = 8 + else: + self.scheme = 0 + sstruct.unpack2(Silf_hdr_format_3, data, self) + base = sstruct.calcsize(Silf_hdr_format_3) + + silfoffsets = struct.unpack_from((">%dL" % self.numSilf), data[base:]) + for offset in silfoffsets: + s = Silf() + self.silfs.append(s) + s.decompile(data[offset:], ttFont, self.version) + + def compile(self, ttFont): + self.numSilf = len(self.silfs) + if self.version < 3.0: + hdr = sstruct.pack(Silf_hdr_format, self) + hdr += struct.pack(">HH", self.numSilf, 0) + else: + hdr = sstruct.pack(Silf_hdr_format_3, self) + offset = len(hdr) + 4 * self.numSilf + data = b"" + for s in self.silfs: + hdr += struct.pack(">L", offset) + subdata = s.compile(ttFont, self.version) + offset += len(subdata) + data += subdata + if self.version >= 5.0: + return grUtils.compress(self.scheme, hdr + data) + return hdr + data + + def toXML(self, writer, ttFont): + writer.comment("Attributes starting with _ are informative only") + writer.newline() + writer.simpletag( + "version", + version=self.version, + compilerVersion=self.compilerVersion, + compressionScheme=self.scheme, + ) + writer.newline() + for s in self.silfs: + writer.begintag("silf") + writer.newline() + s.toXML(writer, ttFont, self.version) + writer.endtag("silf") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "version": + self.scheme = int(safeEval(attrs["compressionScheme"])) + self.version = float(safeEval(attrs["version"])) + self.compilerVersion = int(safeEval(attrs["compilerVersion"])) + return + if name == "silf": + s = Silf() + self.silfs.append(s) + for element in content: + if not isinstance(element, tuple): + continue + tag, attrs, subcontent = element + s.fromXML(tag, attrs, subcontent, ttFont, self.version) + + +class Silf(object): + """A particular Silf subtable""" + + def __init__(self): + self.passes = [] + self.scriptTags = [] + self.critFeatures = [] + self.jLevels = [] + self.pMap = {} + + def decompile(self, data, ttFont, version=2.0): + if version >= 3.0: + _, data = sstruct.unpack2(Silf_part1_format_v3, data, self) + self.ruleVersion = float( + floatToFixedToStr(self.ruleVersion, precisionBits=16) + ) + _, data = sstruct.unpack2(Silf_part1_format, data, self) + for jlevel in range(self.numJLevels): + j, data = sstruct.unpack2(Silf_justify_format, data, _Object()) + self.jLevels.append(j) + _, data = sstruct.unpack2(Silf_part2_format, data, self) + if self.numCritFeatures: + self.critFeatures = struct.unpack_from( + (">%dH" % self.numCritFeatures), data + ) + data = data[self.numCritFeatures * 2 + 1 :] + (numScriptTag,) = struct.unpack_from("B", data) + if numScriptTag: + self.scriptTags = [ + struct.unpack("4s", data[x : x + 4])[0].decode("ascii") + for x in range(1, 1 + 4 * numScriptTag, 4) + ] + data = data[1 + 4 * numScriptTag :] + (self.lbGID,) = struct.unpack(">H", data[:2]) + if self.numPasses: + self.oPasses = struct.unpack( + (">%dL" % (self.numPasses + 1)), data[2 : 6 + 4 * self.numPasses] + ) + data = data[6 + 4 * self.numPasses :] + (numPseudo,) = struct.unpack(">H", data[:2]) + for i in range(numPseudo): + if version >= 3.0: + pseudo = sstruct.unpack( + Silf_pseudomap_format, data[8 + 6 * i : 14 + 6 * i], _Object() + ) + else: + pseudo = sstruct.unpack( + Silf_pseudomap_format_h, data[8 + 4 * i : 12 + 4 * i], _Object() + ) + self.pMap[pseudo.unicode] = ttFont.getGlyphName(pseudo.nPseudo) + data = data[8 + 6 * numPseudo :] + currpos = ( + sstruct.calcsize(Silf_part1_format) + + sstruct.calcsize(Silf_justify_format) * self.numJLevels + + sstruct.calcsize(Silf_part2_format) + + 2 * self.numCritFeatures + + 1 + + 1 + + 4 * numScriptTag + + 6 + + 4 * self.numPasses + + 8 + + 6 * numPseudo + ) + if version >= 3.0: + currpos += sstruct.calcsize(Silf_part1_format_v3) + self.classes = Classes() + self.classes.decompile(data, ttFont, version) + for i in range(self.numPasses): + p = Pass() + self.passes.append(p) + p.decompile( + data[self.oPasses[i] - currpos : self.oPasses[i + 1] - currpos], + ttFont, + version, + ) + + def compile(self, ttFont, version=2.0): + self.numPasses = len(self.passes) + self.numJLevels = len(self.jLevels) + self.numCritFeatures = len(self.critFeatures) + numPseudo = len(self.pMap) + data = b"" + if version >= 3.0: + hdroffset = sstruct.calcsize(Silf_part1_format_v3) + else: + hdroffset = 0 + data += sstruct.pack(Silf_part1_format, self) + for j in self.jLevels: + data += sstruct.pack(Silf_justify_format, j) + data += sstruct.pack(Silf_part2_format, self) + if self.numCritFeatures: + data += struct.pack((">%dH" % self.numCritFeaturs), *self.critFeatures) + data += struct.pack("BB", 0, len(self.scriptTags)) + if len(self.scriptTags): + tdata = [struct.pack("4s", x.encode("ascii")) for x in self.scriptTags] + data += b"".join(tdata) + data += struct.pack(">H", self.lbGID) + self.passOffset = len(data) + + data1 = grUtils.bininfo(numPseudo, 6) + currpos = hdroffset + len(data) + 4 * (self.numPasses + 1) + self.pseudosOffset = currpos + len(data1) + for u, p in sorted(self.pMap.items()): + data1 += struct.pack( + (">LH" if version >= 3.0 else ">HH"), u, ttFont.getGlyphID(p) + ) + data1 += self.classes.compile(ttFont, version) + currpos += len(data1) + data2 = b"" + datao = b"" + for i, p in enumerate(self.passes): + base = currpos + len(data2) + datao += struct.pack(">L", base) + data2 += p.compile(ttFont, base, version) + datao += struct.pack(">L", currpos + len(data2)) + + if version >= 3.0: + data3 = sstruct.pack(Silf_part1_format_v3, self) + else: + data3 = b"" + return data3 + data + datao + data1 + data2 + + def toXML(self, writer, ttFont, version=2.0): + if version >= 3.0: + writer.simpletag("version", ruleVersion=self.ruleVersion) + writer.newline() + writesimple("info", self, writer, *attrs_info) + writesimple("passindexes", self, writer, *attrs_passindexes) + writesimple("contexts", self, writer, *attrs_contexts) + writesimple("attributes", self, writer, *attrs_attributes) + if len(self.jLevels): + writer.begintag("justifications") + writer.newline() + jformat, jnames, jfixes = sstruct.getformat(Silf_justify_format) + for i, j in enumerate(self.jLevels): + attrs = dict([(k, getattr(j, k)) for k in jnames]) + writer.simpletag("justify", **attrs) + writer.newline() + writer.endtag("justifications") + writer.newline() + if len(self.critFeatures): + writer.begintag("critFeatures") + writer.newline() + writer.write(" ".join(map(str, self.critFeatures))) + writer.newline() + writer.endtag("critFeatures") + writer.newline() + if len(self.scriptTags): + writer.begintag("scriptTags") + writer.newline() + writer.write(" ".join(self.scriptTags)) + writer.newline() + writer.endtag("scriptTags") + writer.newline() + if self.pMap: + writer.begintag("pseudoMap") + writer.newline() + for k, v in sorted(self.pMap.items()): + writer.simpletag("pseudo", unicode=hex(k), pseudo=v) + writer.newline() + writer.endtag("pseudoMap") + writer.newline() + self.classes.toXML(writer, ttFont, version) + if len(self.passes): + writer.begintag("passes") + writer.newline() + for i, p in enumerate(self.passes): + writer.begintag("pass", _index=i) + writer.newline() + p.toXML(writer, ttFont, version) + writer.endtag("pass") + writer.newline() + writer.endtag("passes") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont, version=2.0): + if name == "version": + self.ruleVersion = float(safeEval(attrs.get("ruleVersion", "0"))) + if name == "info": + getSimple(self, attrs, *attrs_info) + elif name == "passindexes": + getSimple(self, attrs, *attrs_passindexes) + elif name == "contexts": + getSimple(self, attrs, *attrs_contexts) + elif name == "attributes": + getSimple(self, attrs, *attrs_attributes) + elif name == "justifications": + for element in content: + if not isinstance(element, tuple): + continue + (tag, attrs, subcontent) = element + if tag == "justify": + j = _Object() + for k, v in attrs.items(): + setattr(j, k, int(v)) + self.jLevels.append(j) + elif name == "critFeatures": + self.critFeatures = [] + element = content_string(content) + self.critFeatures.extend(map(int, element.split())) + elif name == "scriptTags": + self.scriptTags = [] + element = content_string(content) + for n in element.split(): + self.scriptTags.append(n) + elif name == "pseudoMap": + self.pMap = {} + for element in content: + if not isinstance(element, tuple): + continue + (tag, attrs, subcontent) = element + if tag == "pseudo": + k = int(attrs["unicode"], 16) + v = attrs["pseudo"] + self.pMap[k] = v + elif name == "classes": + self.classes = Classes() + for element in content: + if not isinstance(element, tuple): + continue + tag, attrs, subcontent = element + self.classes.fromXML(tag, attrs, subcontent, ttFont, version) + elif name == "passes": + for element in content: + if not isinstance(element, tuple): + continue + tag, attrs, subcontent = element + if tag == "pass": + p = Pass() + for e in subcontent: + if not isinstance(e, tuple): + continue + p.fromXML(e[0], e[1], e[2], ttFont, version) + self.passes.append(p) + + +class Classes(object): + def __init__(self): + self.linear = [] + self.nonLinear = [] + + def decompile(self, data, ttFont, version=2.0): + sstruct.unpack2(Silf_classmap_format, data, self) + if version >= 4.0: + oClasses = struct.unpack( + (">%dL" % (self.numClass + 1)), data[4 : 8 + 4 * self.numClass] + ) + else: + oClasses = struct.unpack( + (">%dH" % (self.numClass + 1)), data[4 : 6 + 2 * self.numClass] + ) + for s, e in zip(oClasses[: self.numLinear], oClasses[1 : self.numLinear + 1]): + self.linear.append( + ttFont.getGlyphName(x) + for x in struct.unpack((">%dH" % ((e - s) / 2)), data[s:e]) + ) + for s, e in zip( + oClasses[self.numLinear : self.numClass], + oClasses[self.numLinear + 1 : self.numClass + 1], + ): + nonLinids = [ + struct.unpack(">HH", data[x : x + 4]) for x in range(s + 8, e, 4) + ] + nonLin = dict([(ttFont.getGlyphName(x[0]), x[1]) for x in nonLinids]) + self.nonLinear.append(nonLin) + + def compile(self, ttFont, version=2.0): + data = b"" + oClasses = [] + if version >= 4.0: + offset = 8 + 4 * (len(self.linear) + len(self.nonLinear)) + else: + offset = 6 + 2 * (len(self.linear) + len(self.nonLinear)) + for l in self.linear: + oClasses.append(len(data) + offset) + gs = [ttFont.getGlyphID(x) for x in l] + data += struct.pack((">%dH" % len(l)), *gs) + for l in self.nonLinear: + oClasses.append(len(data) + offset) + gs = [(ttFont.getGlyphID(x[0]), x[1]) for x in l.items()] + data += grUtils.bininfo(len(gs)) + data += b"".join([struct.pack(">HH", *x) for x in sorted(gs)]) + oClasses.append(len(data) + offset) + self.numClass = len(oClasses) - 1 + self.numLinear = len(self.linear) + return ( + sstruct.pack(Silf_classmap_format, self) + + struct.pack( + ((">%dL" if version >= 4.0 else ">%dH") % len(oClasses)), *oClasses + ) + + data + ) + + def toXML(self, writer, ttFont, version=2.0): + writer.begintag("classes") + writer.newline() + writer.begintag("linearClasses") + writer.newline() + for i, l in enumerate(self.linear): + writer.begintag("linear", _index=i) + writer.newline() + wrapline(writer, l) + writer.endtag("linear") + writer.newline() + writer.endtag("linearClasses") + writer.newline() + writer.begintag("nonLinearClasses") + writer.newline() + for i, l in enumerate(self.nonLinear): + writer.begintag("nonLinear", _index=i + self.numLinear) + writer.newline() + for inp, ind in l.items(): + writer.simpletag("map", glyph=inp, index=ind) + writer.newline() + writer.endtag("nonLinear") + writer.newline() + writer.endtag("nonLinearClasses") + writer.newline() + writer.endtag("classes") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont, version=2.0): + if name == "linearClasses": + for element in content: + if not isinstance(element, tuple): + continue + tag, attrs, subcontent = element + if tag == "linear": + l = content_string(subcontent).split() + self.linear.append(l) + elif name == "nonLinearClasses": + for element in content: + if not isinstance(element, tuple): + continue + tag, attrs, subcontent = element + if tag == "nonLinear": + l = {} + for e in subcontent: + if not isinstance(e, tuple): + continue + tag, attrs, subsubcontent = e + if tag == "map": + l[attrs["glyph"]] = int(safeEval(attrs["index"])) + self.nonLinear.append(l) + + +class Pass(object): + def __init__(self): + self.colMap = {} + self.rules = [] + self.rulePreContexts = [] + self.ruleSortKeys = [] + self.ruleConstraints = [] + self.passConstraints = b"" + self.actions = [] + self.stateTrans = [] + self.startStates = [] + + def decompile(self, data, ttFont, version=2.0): + _, data = sstruct.unpack2(Silf_pass_format, data, self) + (numRange, _, _, _) = struct.unpack(">4H", data[:8]) + data = data[8:] + for i in range(numRange): + (first, last, col) = struct.unpack(">3H", data[6 * i : 6 * i + 6]) + for g in range(first, last + 1): + self.colMap[ttFont.getGlyphName(g)] = col + data = data[6 * numRange :] + oRuleMap = struct.unpack_from((">%dH" % (self.numSuccess + 1)), data) + data = data[2 + 2 * self.numSuccess :] + rules = struct.unpack_from((">%dH" % oRuleMap[-1]), data) + self.rules = [rules[s:e] for (s, e) in zip(oRuleMap, oRuleMap[1:])] + data = data[2 * oRuleMap[-1] :] + (self.minRulePreContext, self.maxRulePreContext) = struct.unpack("BB", data[:2]) + numStartStates = self.maxRulePreContext - self.minRulePreContext + 1 + self.startStates = struct.unpack( + (">%dH" % numStartStates), data[2 : 2 + numStartStates * 2] + ) + data = data[2 + numStartStates * 2 :] + self.ruleSortKeys = struct.unpack( + (">%dH" % self.numRules), data[: 2 * self.numRules] + ) + data = data[2 * self.numRules :] + self.rulePreContexts = struct.unpack( + ("%dB" % self.numRules), data[: self.numRules] + ) + data = data[self.numRules :] + (self.collisionThreshold, pConstraint) = struct.unpack(">BH", data[:3]) + oConstraints = list( + struct.unpack( + (">%dH" % (self.numRules + 1)), data[3 : 5 + self.numRules * 2] + ) + ) + data = data[5 + self.numRules * 2 :] + oActions = list( + struct.unpack((">%dH" % (self.numRules + 1)), data[: 2 + self.numRules * 2]) + ) + data = data[2 * self.numRules + 2 :] + for i in range(self.numTransitional): + a = array( + "H", data[i * self.numColumns * 2 : (i + 1) * self.numColumns * 2] + ) + if sys.byteorder != "big": + a.byteswap() + self.stateTrans.append(a) + data = data[self.numTransitional * self.numColumns * 2 + 1 :] + self.passConstraints = data[:pConstraint] + data = data[pConstraint:] + for i in range(len(oConstraints) - 2, -1, -1): + if oConstraints[i] == 0: + oConstraints[i] = oConstraints[i + 1] + self.ruleConstraints = [ + (data[s:e] if (e - s > 1) else b"") + for (s, e) in zip(oConstraints, oConstraints[1:]) + ] + data = data[oConstraints[-1] :] + self.actions = [ + (data[s:e] if (e - s > 1) else "") for (s, e) in zip(oActions, oActions[1:]) + ] + data = data[oActions[-1] :] + # not using debug + + def compile(self, ttFont, base, version=2.0): + # build it all up backwards + oActions = reduce( + lambda a, x: (a[0] + len(x), a[1] + [a[0]]), self.actions + [b""], (0, []) + )[1] + oConstraints = reduce( + lambda a, x: (a[0] + len(x), a[1] + [a[0]]), + self.ruleConstraints + [b""], + (1, []), + )[1] + constraintCode = b"\000" + b"".join(self.ruleConstraints) + transes = [] + for t in self.stateTrans: + if sys.byteorder != "big": + t.byteswap() + transes.append(t.tobytes()) + if sys.byteorder != "big": + t.byteswap() + if not len(transes): + self.startStates = [0] + oRuleMap = reduce( + lambda a, x: (a[0] + len(x), a[1] + [a[0]]), self.rules + [[]], (0, []) + )[1] + passRanges = [] + gidcolmap = dict([(ttFont.getGlyphID(x[0]), x[1]) for x in self.colMap.items()]) + for e in grUtils.entries(gidcolmap, sameval=True): + if e[1]: + passRanges.append((e[0], e[0] + e[1] - 1, e[2][0])) + self.numRules = len(self.actions) + self.fsmOffset = ( + sstruct.calcsize(Silf_pass_format) + + 8 + + len(passRanges) * 6 + + len(oRuleMap) * 2 + + 2 * oRuleMap[-1] + + 2 + + 2 * len(self.startStates) + + 3 * self.numRules + + 3 + + 4 * self.numRules + + 4 + ) + self.pcCode = ( + self.fsmOffset + 2 * self.numTransitional * self.numColumns + 1 + base + ) + self.rcCode = self.pcCode + len(self.passConstraints) + self.aCode = self.rcCode + len(constraintCode) + self.oDebug = 0 + # now generate output + data = sstruct.pack(Silf_pass_format, self) + data += grUtils.bininfo(len(passRanges), 6) + data += b"".join(struct.pack(">3H", *p) for p in passRanges) + data += struct.pack((">%dH" % len(oRuleMap)), *oRuleMap) + flatrules = reduce(lambda a, x: a + x, self.rules, []) + data += struct.pack((">%dH" % oRuleMap[-1]), *flatrules) + data += struct.pack("BB", self.minRulePreContext, self.maxRulePreContext) + data += struct.pack((">%dH" % len(self.startStates)), *self.startStates) + data += struct.pack((">%dH" % self.numRules), *self.ruleSortKeys) + data += struct.pack(("%dB" % self.numRules), *self.rulePreContexts) + data += struct.pack(">BH", self.collisionThreshold, len(self.passConstraints)) + data += struct.pack((">%dH" % (self.numRules + 1)), *oConstraints) + data += struct.pack((">%dH" % (self.numRules + 1)), *oActions) + return ( + data + + b"".join(transes) + + struct.pack("B", 0) + + self.passConstraints + + constraintCode + + b"".join(self.actions) + ) + + def toXML(self, writer, ttFont, version=2.0): + writesimple("info", self, writer, *pass_attrs_info) + writesimple("fsminfo", self, writer, *pass_attrs_fsm) + writer.begintag("colmap") + writer.newline() + wrapline( + writer, + [ + "{}={}".format(*x) + for x in sorted( + self.colMap.items(), key=lambda x: ttFont.getGlyphID(x[0]) + ) + ], + ) + writer.endtag("colmap") + writer.newline() + writer.begintag("staterulemap") + writer.newline() + for i, r in enumerate(self.rules): + writer.simpletag( + "state", + number=self.numRows - self.numSuccess + i, + rules=" ".join(map(str, r)), + ) + writer.newline() + writer.endtag("staterulemap") + writer.newline() + writer.begintag("rules") + writer.newline() + for i, action in enumerate(self.actions): + writer.begintag( + "rule", + index=i, + precontext=self.rulePreContexts[i], + sortkey=self.ruleSortKeys[i], + ) + writer.newline() + if len(self.ruleConstraints[i]): + writecode("constraint", writer, self.ruleConstraints[i]) + writecode("action", writer, action) + writer.endtag("rule") + writer.newline() + writer.endtag("rules") + writer.newline() + if len(self.passConstraints): + writecode("passConstraint", writer, self.passConstraints) + if len(self.stateTrans): + writer.begintag("fsm") + writer.newline() + writer.begintag("starts") + writer.write(" ".join(map(str, self.startStates))) + writer.endtag("starts") + writer.newline() + for i, s in enumerate(self.stateTrans): + writer.begintag("row", _i=i) + # no newlines here + writer.write(" ".join(map(str, s))) + writer.endtag("row") + writer.newline() + writer.endtag("fsm") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont, version=2.0): + if name == "info": + getSimple(self, attrs, *pass_attrs_info) + elif name == "fsminfo": + getSimple(self, attrs, *pass_attrs_fsm) + elif name == "colmap": + e = content_string(content) + for w in e.split(): + x = w.split("=") + if len(x) != 2 or x[0] == "" or x[1] == "": + continue + self.colMap[x[0]] = int(x[1]) + elif name == "staterulemap": + for e in content: + if not isinstance(e, tuple): + continue + tag, a, c = e + if tag == "state": + self.rules.append([int(x) for x in a["rules"].split(" ")]) + elif name == "rules": + for element in content: + if not isinstance(element, tuple): + continue + tag, a, c = element + if tag != "rule": + continue + self.rulePreContexts.append(int(a["precontext"])) + self.ruleSortKeys.append(int(a["sortkey"])) + con = b"" + act = b"" + for e in c: + if not isinstance(e, tuple): + continue + tag, a, subc = e + if tag == "constraint": + con = readcode(subc) + elif tag == "action": + act = readcode(subc) + self.actions.append(act) + self.ruleConstraints.append(con) + elif name == "passConstraint": + self.passConstraints = readcode(content) + elif name == "fsm": + for element in content: + if not isinstance(element, tuple): + continue + tag, a, c = element + if tag == "row": + s = array("H") + e = content_string(c) + s.extend(map(int, e.split())) + self.stateTrans.append(s) + elif tag == "starts": + s = [] + e = content_string(c) + s.extend(map(int, e.split())) + self.startStates = s diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/S__i_l_l.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/S__i_l_l.py new file mode 100644 index 0000000000000000000000000000000000000000..61106ea5284ac67219590d87544d44e2e1f970c2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/S__i_l_l.py @@ -0,0 +1,92 @@ +from fontTools.misc import sstruct +from fontTools.misc.fixedTools import floatToFixedToStr +from fontTools.misc.textTools import safeEval +from . import DefaultTable +from . import grUtils +import struct + +Sill_hdr = """ + > + version: 16.16F +""" + + +class table_S__i_l_l(DefaultTable.DefaultTable): + """Graphite Languages table + + See also https://graphite.sil.org/graphite_techAbout#graphite-font-tables + """ + + def __init__(self, tag=None): + DefaultTable.DefaultTable.__init__(self, tag) + self.langs = {} + + def decompile(self, data, ttFont): + (_, data) = sstruct.unpack2(Sill_hdr, data, self) + self.version = float(floatToFixedToStr(self.version, precisionBits=16)) + (numLangs,) = struct.unpack(">H", data[:2]) + data = data[8:] + maxsetting = 0 + langinfo = [] + for i in range(numLangs): + (langcode, numsettings, offset) = struct.unpack( + ">4sHH", data[i * 8 : (i + 1) * 8] + ) + offset = int(offset / 8) - (numLangs + 1) + langcode = langcode.replace(b"\000", b"") + langinfo.append((langcode.decode("utf-8"), numsettings, offset)) + maxsetting = max(maxsetting, offset + numsettings) + data = data[numLangs * 8 :] + finfo = [] + for i in range(maxsetting): + (fid, val, _) = struct.unpack(">LHH", data[i * 8 : (i + 1) * 8]) + finfo.append((fid, val)) + self.langs = {} + for c, n, o in langinfo: + self.langs[c] = [] + for i in range(o, o + n): + self.langs[c].append(finfo[i]) + + def compile(self, ttFont): + ldat = b"" + fdat = b"" + offset = len(self.langs) + for c, inf in sorted(self.langs.items()): + ldat += struct.pack(">4sHH", c.encode("utf8"), len(inf), 8 * offset + 20) + for fid, val in inf: + fdat += struct.pack(">LHH", fid, val, 0) + offset += len(inf) + ldat += struct.pack(">LHH", 0x80808080, 0, 8 * offset + 20) + return ( + sstruct.pack(Sill_hdr, self) + + grUtils.bininfo(len(self.langs)) + + ldat + + fdat + ) + + def toXML(self, writer, ttFont): + writer.simpletag("version", version=self.version) + writer.newline() + for c, inf in sorted(self.langs.items()): + writer.begintag("lang", name=c) + writer.newline() + for fid, val in inf: + writer.simpletag("feature", fid=grUtils.num2tag(fid), val=val) + writer.newline() + writer.endtag("lang") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "version": + self.version = float(safeEval(attrs["version"])) + elif name == "lang": + c = attrs["name"] + self.langs[c] = [] + for element in content: + if not isinstance(element, tuple): + continue + tag, a, subcontent = element + if tag == "feature": + self.langs[c].append( + (grUtils.tag2num(a["fid"]), int(safeEval(a["val"]))) + ) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_B_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_B_.py new file mode 100644 index 0000000000000000000000000000000000000000..ea19fcee856e75fc8aa494e083b4beed303f831c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_B_.py @@ -0,0 +1,13 @@ +""" TSI{B,C,D,J,P,S,V} are private tables used by Microsoft Visual TrueType (VTT) +tool to store its table source data. + +TSIB contains the source text for the ``BASE`` table. + +See also https://learn.microsoft.com/en-us/typography/tools/vtt/tsi-tables +""" + +from .T_S_I_V_ import table_T_S_I_V_ + + +class table_T_S_I_B_(table_T_S_I_V_): + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_C_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_C_.py new file mode 100644 index 0000000000000000000000000000000000000000..14e353cde58b739660b10fe666e26492f5a0069f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_C_.py @@ -0,0 +1,14 @@ +""" TSI{B,C,D,J,P,S,V} are private tables used by Microsoft Visual TrueType (VTT) +tool to store its table source data. + +TSIC contains the source text for the Variation CVT window and data for +the ``cvar`` table. + +See also https://learn.microsoft.com/en-us/typography/tools/vtt/tsi-tables +""" + +from .otBase import BaseTTXConverter + + +class table_T_S_I_C_(BaseTTXConverter): + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_D_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_D_.py new file mode 100644 index 0000000000000000000000000000000000000000..2bb9455efaeda5baac2c1f425c35019723b592bd --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_D_.py @@ -0,0 +1,13 @@ +""" TSI{B,C,D,J,P,S,V} are private tables used by Microsoft Visual TrueType (VTT) +tool to store its table source data. + +TSID contains the source text for the ``GDEF`` table. + +See also https://learn.microsoft.com/en-us/typography/tools/vtt/tsi-tables +""" + +from .T_S_I_V_ import table_T_S_I_V_ + + +class table_T_S_I_D_(table_T_S_I_V_): + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_J_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_J_.py new file mode 100644 index 0000000000000000000000000000000000000000..379b949c6cd380268b139f6c3cfd61fffc43e223 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_J_.py @@ -0,0 +1,13 @@ +""" TSI{B,C,D,J,P,S,V} are private tables used by Microsoft Visual TrueType (VTT) +tool to store its table source data. + +TSIJ contains the source text for the ``JSTF`` table. + +See also https://learn.microsoft.com/en-us/typography/tools/vtt/tsi-tables +""" + +from .T_S_I_V_ import table_T_S_I_V_ + + +class table_T_S_I_J_(table_T_S_I_V_): + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_P_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_P_.py new file mode 100644 index 0000000000000000000000000000000000000000..8b1786970489f4511dcd156e5562eb2156f927a3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_P_.py @@ -0,0 +1,13 @@ +""" TSI{B,C,D,J,P,S,V} are private tables used by Microsoft Visual TrueType (VTT) +tool to store its table source data. + +TSIP contains the source text for the ``GPOS`` table. + +See also https://learn.microsoft.com/en-us/typography/tools/vtt/tsi-tables +""" + +from .T_S_I_V_ import table_T_S_I_V_ + + +class table_T_S_I_P_(table_T_S_I_V_): + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_S_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_S_.py new file mode 100644 index 0000000000000000000000000000000000000000..91f36e7c019087f954a7fa779df045a9097fa289 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_S_.py @@ -0,0 +1,13 @@ +""" TSI{B,C,D,J,P,S,V} are private tables used by Microsoft Visual TrueType (VTT) +tool to store its table source data. + +TSIS contains the source text for the ``GSUB`` table. + +See also https://learn.microsoft.com/en-us/typography/tools/vtt/tsi-tables +""" + +from .T_S_I_V_ import table_T_S_I_V_ + + +class table_T_S_I_S_(table_T_S_I_V_): + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_V_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_V_.py new file mode 100644 index 0000000000000000000000000000000000000000..32af783f26b0f9224e39d3e243f72bfcd1da150b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I_V_.py @@ -0,0 +1,26 @@ +""" TSI{B,C,D,J,P,S,V} are private tables used by Microsoft Visual TrueType (VTT) +tool to store its table source data. + +See also https://learn.microsoft.com/en-us/typography/tools/vtt/tsi-tables +""" + +from fontTools.misc.textTools import strjoin, tobytes, tostr +from . import asciiTable + + +class table_T_S_I_V_(asciiTable.asciiTable): + def toXML(self, writer, ttFont): + data = tostr(self.data) + # removing null bytes. XXX needed?? + data = data.split("\0") + data = strjoin(data) + writer.begintag("source") + writer.newline() + writer.write_noindent(data.replace("\r", "\n")) + writer.newline() + writer.endtag("source") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + lines = strjoin(content).split("\n") + self.data = tobytes("\r".join(lines[1:-1])) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I__0.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I__0.py new file mode 100644 index 0000000000000000000000000000000000000000..d60e783c60873c85487463f151dc25f061cde97f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I__0.py @@ -0,0 +1,70 @@ +"""TSI{0,1,2,3,5} are private tables used by Microsoft Visual TrueType (VTT) +tool to store its hinting source data. + +TSI0 is the index table containing the lengths and offsets for the glyph +programs and 'extra' programs ('fpgm', 'prep', and 'cvt') that are contained +in the TSI1 table. + +See also https://learn.microsoft.com/en-us/typography/tools/vtt/tsi-tables +""" + +import logging +import struct + +from . import DefaultTable + +log = logging.getLogger(__name__) + +tsi0Format = ">HHL" + + +def fixlongs(glyphID, textLength, textOffset): + return int(glyphID), int(textLength), textOffset + + +class table_T_S_I__0(DefaultTable.DefaultTable): + dependencies = ["TSI1"] + + def decompile(self, data, ttFont): + numGlyphs = ttFont["maxp"].numGlyphs + indices = [] + size = struct.calcsize(tsi0Format) + numEntries = len(data) // size + if numEntries != numGlyphs + 5: + diff = numEntries - numGlyphs - 5 + log.warning( + "Number of glyphPrograms differs from the number of glyphs in the font " + f"by {abs(diff)} ({numEntries - 5} programs vs. {numGlyphs} glyphs)." + ) + for _ in range(numEntries): + glyphID, textLength, textOffset = fixlongs( + *struct.unpack(tsi0Format, data[:size]) + ) + indices.append((glyphID, textLength, textOffset)) + data = data[size:] + assert len(data) == 0 + assert indices[-5] == (0xFFFE, 0, 0xABFC1F34), "bad magic number" + self.indices = indices[:-5] + self.extra_indices = indices[-4:] + + def compile(self, ttFont): + if not hasattr(self, "indices"): + # We have no corresponding table (TSI1 or TSI3); let's return + # no data, which effectively means "ignore us". + return b"" + data = b"" + for index, textLength, textOffset in self.indices: + data = data + struct.pack(tsi0Format, index, textLength, textOffset) + data = data + struct.pack(tsi0Format, 0xFFFE, 0, 0xABFC1F34) + for index, textLength, textOffset in self.extra_indices: + data = data + struct.pack(tsi0Format, index, textLength, textOffset) + return data + + def set(self, indices, extra_indices): + # gets called by 'TSI1' or 'TSI3' + self.indices = indices + self.extra_indices = extra_indices + + def toXML(self, writer, ttFont): + writer.comment("This table will be calculated by the compiler") + writer.newline() diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I__1.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I__1.py new file mode 100644 index 0000000000000000000000000000000000000000..19537dac9c512dc009a159cb25bb926eebca61ed --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I__1.py @@ -0,0 +1,163 @@ +""" TSI{0,1,2,3,5} are private tables used by Microsoft Visual TrueType (VTT) +tool to store its hinting source data. + +TSI1 contains the text of the glyph programs in the form of low-level assembly +code, as well as the 'extra' programs 'fpgm', 'ppgm' (i.e. 'prep'), and 'cvt'. + +See also https://learn.microsoft.com/en-us/typography/tools/vtt/tsi-tables +""" + +from . import DefaultTable +from fontTools.misc.loggingTools import LogMixin +from fontTools.misc.textTools import strjoin, tobytes, tostr + + +class table_T_S_I__1(LogMixin, DefaultTable.DefaultTable): + extras = {0xFFFA: "ppgm", 0xFFFB: "cvt", 0xFFFC: "reserved", 0xFFFD: "fpgm"} + + indextable = "TSI0" + + def decompile(self, data, ttFont): + totalLength = len(data) + indextable = ttFont[self.indextable] + for indices, isExtra in zip( + (indextable.indices, indextable.extra_indices), (False, True) + ): + programs = {} + for i, (glyphID, textLength, textOffset) in enumerate(indices): + if isExtra: + name = self.extras[glyphID] + else: + name = ttFont.getGlyphName(glyphID) + if textOffset > totalLength: + self.log.warning("textOffset > totalLength; %r skipped" % name) + continue + if textLength < 0x8000: + # If the length stored in the record is less than 32768, then use + # that as the length of the record. + pass + elif textLength == 0x8000: + # If the length is 32768, compute the actual length as follows: + isLast = i == (len(indices) - 1) + if isLast: + if isExtra: + # For the last "extra" record (the very last record of the + # table), the length is the difference between the total + # length of the TSI1 table and the textOffset of the final + # record. + nextTextOffset = totalLength + else: + # For the last "normal" record (the last record just prior + # to the record containing the "magic number"), the length + # is the difference between the textOffset of the record + # following the "magic number" (0xFFFE) record (i.e. the + # first "extra" record), and the textOffset of the last + # "normal" record. + nextTextOffset = indextable.extra_indices[0][2] + else: + # For all other records with a length of 0x8000, the length is + # the difference between the textOffset of the record in + # question and the textOffset of the next record. + nextTextOffset = indices[i + 1][2] + assert nextTextOffset >= textOffset, "entries not sorted by offset" + if nextTextOffset > totalLength: + self.log.warning( + "nextTextOffset > totalLength; %r truncated" % name + ) + nextTextOffset = totalLength + textLength = nextTextOffset - textOffset + else: + from fontTools import ttLib + + raise ttLib.TTLibError( + "%r textLength (%d) must not be > 32768" % (name, textLength) + ) + text = data[textOffset : textOffset + textLength] + assert len(text) == textLength + text = tostr(text, encoding="utf-8") + if text: + programs[name] = text + if isExtra: + self.extraPrograms = programs + else: + self.glyphPrograms = programs + + def compile(self, ttFont): + if not hasattr(self, "glyphPrograms"): + self.glyphPrograms = {} + self.extraPrograms = {} + data = b"" + indextable = ttFont[self.indextable] + glyphNames = ttFont.getGlyphOrder() + + indices = [] + for i, name in enumerate(glyphNames): + if len(data) % 2: + data = ( + data + b"\015" + ) # align on 2-byte boundaries, fill with return chars. Yum. + if name in self.glyphPrograms: + text = tobytes(self.glyphPrograms[name], encoding="utf-8") + else: + text = b"" + textLength = len(text) + if textLength >= 0x8000: + textLength = 0x8000 + indices.append((i, textLength, len(data))) + data = data + text + + extra_indices = [] + for code, name in sorted(self.extras.items()): + if len(data) % 2: + data = ( + data + b"\015" + ) # align on 2-byte boundaries, fill with return chars. + if name in self.extraPrograms: + text = tobytes(self.extraPrograms[name], encoding="utf-8") + else: + text = b"" + textLength = len(text) + if textLength >= 0x8000: + textLength = 0x8000 + extra_indices.append((code, textLength, len(data))) + data = data + text + indextable.set(indices, extra_indices) + return data + + def toXML(self, writer, ttFont): + names = sorted(self.glyphPrograms.keys()) + writer.newline() + for name in names: + text = self.glyphPrograms[name] + if not text: + continue + writer.begintag("glyphProgram", name=name) + writer.newline() + writer.write_noindent(text.replace("\r", "\n")) + writer.newline() + writer.endtag("glyphProgram") + writer.newline() + writer.newline() + extra_names = sorted(self.extraPrograms.keys()) + for name in extra_names: + text = self.extraPrograms[name] + if not text: + continue + writer.begintag("extraProgram", name=name) + writer.newline() + writer.write_noindent(text.replace("\r", "\n")) + writer.newline() + writer.endtag("extraProgram") + writer.newline() + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if not hasattr(self, "glyphPrograms"): + self.glyphPrograms = {} + self.extraPrograms = {} + lines = strjoin(content).replace("\r", "\n").split("\n") + text = "\r".join(lines[1:-1]) + if name == "glyphProgram": + self.glyphPrograms[attrs["name"]] = text + elif name == "extraProgram": + self.extraPrograms[attrs["name"]] = text diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I__2.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I__2.py new file mode 100644 index 0000000000000000000000000000000000000000..63608c60414c8e6cfd67aa6ab46caf4f14a918e1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I__2.py @@ -0,0 +1,17 @@ +""" TSI{0,1,2,3,5} are private tables used by Microsoft Visual TrueType (VTT) +tool to store its hinting source data. + +TSI2 is the index table containing the lengths and offsets for the glyph +programs that are contained in the TSI3 table. It uses the same format as +the TSI0 table. + +See also https://learn.microsoft.com/en-us/typography/tools/vtt/tsi-tables +""" + +from fontTools import ttLib + +superclass = ttLib.getTableClass("TSI0") + + +class table_T_S_I__2(superclass): + dependencies = ["TSI3"] diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I__3.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I__3.py new file mode 100644 index 0000000000000000000000000000000000000000..e866826db488d178833836f203f5e634cbdfbd3f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I__3.py @@ -0,0 +1,22 @@ +""" TSI{0,1,2,3,5} are private tables used by Microsoft Visual TrueType (VTT) +tool to store its hinting source data. + +TSI3 contains the text of the glyph programs in the form of 'VTTTalk' code. + +See also https://learn.microsoft.com/en-us/typography/tools/vtt/tsi-tables +""" + +from fontTools import ttLib + +superclass = ttLib.getTableClass("TSI1") + + +class table_T_S_I__3(superclass): + extras = { + 0xFFFA: "reserved0", + 0xFFFB: "reserved1", + 0xFFFC: "reserved2", + 0xFFFD: "reserved3", + } + + indextable = "TSI2" diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I__5.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I__5.py new file mode 100644 index 0000000000000000000000000000000000000000..8aa382e43ca0e4bb33994d2e093459a09ba12a9b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_S_I__5.py @@ -0,0 +1,60 @@ +"""TSI{0,1,2,3,5} are private tables used by Microsoft Visual TrueType (VTT) +tool to store its hinting source data. + +TSI5 contains the VTT character groups. + +See also https://learn.microsoft.com/en-us/typography/tools/vtt/tsi-tables +""" + +import array +import logging +import sys + +from fontTools.misc.textTools import safeEval + +from . import DefaultTable + +log = logging.getLogger(__name__) + + +class table_T_S_I__5(DefaultTable.DefaultTable): + def decompile(self, data, ttFont): + numGlyphs = ttFont["maxp"].numGlyphs + a = array.array("H") + a.frombytes(data) + if sys.byteorder != "big": + a.byteswap() + self.glyphGrouping = {} + numEntries = len(data) // 2 + if numEntries != numGlyphs: + diff = numEntries - numGlyphs + log.warning( + "Number of entries differs from the number of glyphs in the font " + f"by {abs(diff)} ({numEntries} entries vs. {numGlyphs} glyphs)." + ) + for i in range(numEntries): + self.glyphGrouping[ttFont.getGlyphName(i)] = a[i] + + def compile(self, ttFont): + glyphNames = ttFont.getGlyphOrder() + a = array.array("H") + for glyphName in glyphNames: + a.append(self.glyphGrouping.get(glyphName, 0)) + if sys.byteorder != "big": + a.byteswap() + return a.tobytes() + + def toXML(self, writer, ttFont): + names = sorted(self.glyphGrouping.keys()) + for glyphName in names: + writer.simpletag( + "glyphgroup", name=glyphName, value=self.glyphGrouping[glyphName] + ) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if not hasattr(self, "glyphGrouping"): + self.glyphGrouping = {} + if name != "glyphgroup": + return + self.glyphGrouping[attrs["name"]] = safeEval(attrs["value"]) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_T_F_A_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_T_F_A_.py new file mode 100644 index 0000000000000000000000000000000000000000..4b6b06871a91d9401bcf9fbd99aeb3c30ca0705f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/T_T_F_A_.py @@ -0,0 +1,14 @@ +from . import asciiTable + + +class table_T_T_F_A_(asciiTable.asciiTable): + """ttfautohint parameters table + + The ``TTFA`` table is used by the free-software `ttfautohint` program + to record the parameters that `ttfautohint` was called with when it + was used to auto-hint the font. + + See also http://freetype.org/ttfautohint/doc/ttfautohint.html#miscellaneous-1 + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/TupleVariation.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/TupleVariation.py new file mode 100644 index 0000000000000000000000000000000000000000..bd6217e2ed9fe4f1076b7a13378ccdaa1308c0f1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/TupleVariation.py @@ -0,0 +1,884 @@ +from fontTools.misc.fixedTools import ( + fixedToFloat as fi2fl, + floatToFixed as fl2fi, + floatToFixedToStr as fl2str, + strToFixedToFloat as str2fl, + otRound, +) +from fontTools.misc.textTools import safeEval +import array +from collections import Counter, defaultdict +import io +import logging +import struct +import sys + + +# https://www.microsoft.com/typography/otspec/otvarcommonformats.htm + +EMBEDDED_PEAK_TUPLE = 0x8000 +INTERMEDIATE_REGION = 0x4000 +PRIVATE_POINT_NUMBERS = 0x2000 + +DELTAS_ARE_ZERO = 0x80 +DELTAS_ARE_WORDS = 0x40 +DELTAS_ARE_LONGS = 0xC0 +DELTAS_SIZE_MASK = 0xC0 +DELTA_RUN_COUNT_MASK = 0x3F + +POINTS_ARE_WORDS = 0x80 +POINT_RUN_COUNT_MASK = 0x7F + +TUPLES_SHARE_POINT_NUMBERS = 0x8000 +TUPLE_COUNT_MASK = 0x0FFF +TUPLE_INDEX_MASK = 0x0FFF + +log = logging.getLogger(__name__) + + +class TupleVariation(object): + def __init__(self, axes, coordinates): + self.axes = axes.copy() + self.coordinates = list(coordinates) + + def __repr__(self): + axes = ",".join( + sorted(["%s=%s" % (name, value) for (name, value) in self.axes.items()]) + ) + return "<TupleVariation %s %s>" % (axes, self.coordinates) + + def __eq__(self, other): + return self.coordinates == other.coordinates and self.axes == other.axes + + def getUsedPoints(self): + # Empty set means "all points used". + if None not in self.coordinates: + return frozenset() + used = frozenset([i for i, p in enumerate(self.coordinates) if p is not None]) + # Return None if no points used. + return used if used else None + + def hasImpact(self): + """Returns True if this TupleVariation has any visible impact. + + If the result is False, the TupleVariation can be omitted from the font + without making any visible difference. + """ + return any(c is not None for c in self.coordinates) + + def toXML(self, writer, axisTags): + writer.begintag("tuple") + writer.newline() + for axis in axisTags: + value = self.axes.get(axis) + if value is not None: + minValue, value, maxValue = value + defaultMinValue = min(value, 0.0) # -0.3 --> -0.3; 0.7 --> 0.0 + defaultMaxValue = max(value, 0.0) # -0.3 --> 0.0; 0.7 --> 0.7 + if minValue == defaultMinValue and maxValue == defaultMaxValue: + writer.simpletag("coord", axis=axis, value=fl2str(value, 14)) + else: + attrs = [ + ("axis", axis), + ("min", fl2str(minValue, 14)), + ("value", fl2str(value, 14)), + ("max", fl2str(maxValue, 14)), + ] + writer.simpletag("coord", attrs) + writer.newline() + wrote_any_deltas = False + for i, delta in enumerate(self.coordinates): + if type(delta) == tuple and len(delta) == 2: + writer.simpletag("delta", pt=i, x=delta[0], y=delta[1]) + writer.newline() + wrote_any_deltas = True + elif type(delta) == int: + writer.simpletag("delta", cvt=i, value=delta) + writer.newline() + wrote_any_deltas = True + elif delta is not None: + log.error("bad delta format") + writer.comment("bad delta #%d" % i) + writer.newline() + wrote_any_deltas = True + if not wrote_any_deltas: + writer.comment("no deltas") + writer.newline() + writer.endtag("tuple") + writer.newline() + + def fromXML(self, name, attrs, _content): + if name == "coord": + axis = attrs["axis"] + value = str2fl(attrs["value"], 14) + defaultMinValue = min(value, 0.0) # -0.3 --> -0.3; 0.7 --> 0.0 + defaultMaxValue = max(value, 0.0) # -0.3 --> 0.0; 0.7 --> 0.7 + minValue = str2fl(attrs.get("min", defaultMinValue), 14) + maxValue = str2fl(attrs.get("max", defaultMaxValue), 14) + self.axes[axis] = (minValue, value, maxValue) + elif name == "delta": + if "pt" in attrs: + point = safeEval(attrs["pt"]) + x = safeEval(attrs["x"]) + y = safeEval(attrs["y"]) + self.coordinates[point] = (x, y) + elif "cvt" in attrs: + cvt = safeEval(attrs["cvt"]) + value = safeEval(attrs["value"]) + self.coordinates[cvt] = value + else: + log.warning("bad delta format: %s" % ", ".join(sorted(attrs.keys()))) + + def compile( + self, axisTags, sharedCoordIndices={}, pointData=None, *, optimizeSize=True + ): + assert set(self.axes.keys()) <= set(axisTags), ( + "Unknown axis tag found.", + self.axes.keys(), + axisTags, + ) + + tupleData = [] + auxData = [] + + if pointData is None: + usedPoints = self.getUsedPoints() + if usedPoints is None: # Nothing to encode + return b"", b"" + pointData = self.compilePoints(usedPoints) + + coord = self.compileCoord(axisTags) + flags = sharedCoordIndices.get(coord) + if flags is None: + flags = EMBEDDED_PEAK_TUPLE + tupleData.append(coord) + + intermediateCoord = self.compileIntermediateCoord(axisTags) + if intermediateCoord is not None: + flags |= INTERMEDIATE_REGION + tupleData.append(intermediateCoord) + + # pointData of b'' implies "use shared points". + if pointData: + flags |= PRIVATE_POINT_NUMBERS + auxData.append(pointData) + + auxData.append(self.compileDeltas(optimizeSize=optimizeSize)) + auxData = b"".join(auxData) + + tupleData.insert(0, struct.pack(">HH", len(auxData), flags)) + return b"".join(tupleData), auxData + + def compileCoord(self, axisTags): + result = [] + axes = self.axes + for axis in axisTags: + triple = axes.get(axis) + if triple is None: + result.append(b"\0\0") + else: + result.append(struct.pack(">h", fl2fi(triple[1], 14))) + return b"".join(result) + + def compileIntermediateCoord(self, axisTags): + needed = False + for axis in axisTags: + minValue, value, maxValue = self.axes.get(axis, (0.0, 0.0, 0.0)) + defaultMinValue = min(value, 0.0) # -0.3 --> -0.3; 0.7 --> 0.0 + defaultMaxValue = max(value, 0.0) # -0.3 --> 0.0; 0.7 --> 0.7 + if (minValue != defaultMinValue) or (maxValue != defaultMaxValue): + needed = True + break + if not needed: + return None + minCoords = [] + maxCoords = [] + for axis in axisTags: + minValue, value, maxValue = self.axes.get(axis, (0.0, 0.0, 0.0)) + minCoords.append(struct.pack(">h", fl2fi(minValue, 14))) + maxCoords.append(struct.pack(">h", fl2fi(maxValue, 14))) + return b"".join(minCoords + maxCoords) + + @staticmethod + def decompileCoord_(axisTags, data, offset): + coord = {} + pos = offset + for axis in axisTags: + coord[axis] = fi2fl(struct.unpack(">h", data[pos : pos + 2])[0], 14) + pos += 2 + return coord, pos + + @staticmethod + def compilePoints(points): + # If the set consists of all points in the glyph, it gets encoded with + # a special encoding: a single zero byte. + # + # To use this optimization, points passed in must be empty set. + # The following two lines are not strictly necessary as the main code + # below would emit the same. But this is most common and faster. + if not points: + return b"\0" + + # In the 'gvar' table, the packing of point numbers is a little surprising. + # It consists of multiple runs, each being a delta-encoded list of integers. + # For example, the point set {17, 18, 19, 20, 21, 22, 23} gets encoded as + # [6, 17, 1, 1, 1, 1, 1, 1]. The first value (6) is the run length minus 1. + # There are two types of runs, with values being either 8 or 16 bit unsigned + # integers. + points = list(points) + points.sort() + numPoints = len(points) + + result = bytearray() + # The binary representation starts with the total number of points in the set, + # encoded into one or two bytes depending on the value. + if numPoints < 0x80: + result.append(numPoints) + else: + result.append((numPoints >> 8) | 0x80) + result.append(numPoints & 0xFF) + + MAX_RUN_LENGTH = 127 + pos = 0 + lastValue = 0 + while pos < numPoints: + runLength = 0 + + headerPos = len(result) + result.append(0) + + useByteEncoding = None + while pos < numPoints and runLength <= MAX_RUN_LENGTH: + curValue = points[pos] + delta = curValue - lastValue + if useByteEncoding is None: + useByteEncoding = 0 <= delta <= 0xFF + if useByteEncoding and (delta > 0xFF or delta < 0): + # we need to start a new run (which will not use byte encoding) + break + # TODO This never switches back to a byte-encoding from a short-encoding. + # That's suboptimal. + if useByteEncoding: + result.append(delta) + else: + result.append(delta >> 8) + result.append(delta & 0xFF) + lastValue = curValue + pos += 1 + runLength += 1 + if useByteEncoding: + result[headerPos] = runLength - 1 + else: + result[headerPos] = (runLength - 1) | POINTS_ARE_WORDS + + return result + + @staticmethod + def decompilePoints_(numPoints, data, offset, tableTag): + """(numPoints, data, offset, tableTag) --> ([point1, point2, ...], newOffset)""" + assert tableTag in ("cvar", "gvar") + pos = offset + numPointsInData = data[pos] + pos += 1 + if (numPointsInData & POINTS_ARE_WORDS) != 0: + numPointsInData = (numPointsInData & POINT_RUN_COUNT_MASK) << 8 | data[pos] + pos += 1 + if numPointsInData == 0: + return (range(numPoints), pos) + + result = [] + while len(result) < numPointsInData: + runHeader = data[pos] + pos += 1 + numPointsInRun = (runHeader & POINT_RUN_COUNT_MASK) + 1 + point = 0 + if (runHeader & POINTS_ARE_WORDS) != 0: + points = array.array("H") + pointsSize = numPointsInRun * 2 + else: + points = array.array("B") + pointsSize = numPointsInRun + points.frombytes(data[pos : pos + pointsSize]) + if sys.byteorder != "big": + points.byteswap() + + assert len(points) == numPointsInRun + pos += pointsSize + + result.extend(points) + + # Convert relative to absolute + absolute = [] + current = 0 + for delta in result: + current += delta + absolute.append(current) + result = absolute + del absolute + + badPoints = {str(p) for p in result if p < 0 or p >= numPoints} + if badPoints: + log.warning( + "point %s out of range in '%s' table" + % (",".join(sorted(badPoints)), tableTag) + ) + return (result, pos) + + def compileDeltas(self, optimizeSize=True): + deltaX = [] + deltaY = [] + if self.getCoordWidth() == 2: + for c in self.coordinates: + if c is None: + continue + deltaX.append(c[0]) + deltaY.append(c[1]) + else: + for c in self.coordinates: + if c is None: + continue + deltaX.append(c) + bytearr = bytearray() + self.compileDeltaValues_(deltaX, bytearr, optimizeSize=optimizeSize) + self.compileDeltaValues_(deltaY, bytearr, optimizeSize=optimizeSize) + return bytearr + + @staticmethod + def compileDeltaValues_(deltas, bytearr=None, *, optimizeSize=True): + """[value1, value2, value3, ...] --> bytearray + + Emits a sequence of runs. Each run starts with a + byte-sized header whose 6 least significant bits + (header & 0x3F) indicate how many values are encoded + in this run. The stored length is the actual length + minus one; run lengths are thus in the range [1..64]. + If the header byte has its most significant bit (0x80) + set, all values in this run are zero, and no data + follows. Otherwise, the header byte is followed by + ((header & 0x3F) + 1) signed values. If (header & + 0x40) is clear, the delta values are stored as signed + bytes; if (header & 0x40) is set, the delta values are + signed 16-bit integers. + """ # Explaining the format because the 'gvar' spec is hard to understand. + if bytearr is None: + bytearr = bytearray() + + pos = 0 + numDeltas = len(deltas) + + if optimizeSize: + while pos < numDeltas: + value = deltas[pos] + if value == 0: + pos = TupleVariation.encodeDeltaRunAsZeroes_(deltas, pos, bytearr) + elif -128 <= value <= 127: + pos = TupleVariation.encodeDeltaRunAsBytes_(deltas, pos, bytearr) + elif -32768 <= value <= 32767: + pos = TupleVariation.encodeDeltaRunAsWords_(deltas, pos, bytearr) + else: + pos = TupleVariation.encodeDeltaRunAsLongs_(deltas, pos, bytearr) + else: + minVal, maxVal = min(deltas), max(deltas) + if minVal == 0 == maxVal: + pos = TupleVariation.encodeDeltaRunAsZeroes_(deltas, pos, bytearr) + elif -128 <= minVal <= maxVal <= 127: + pos = TupleVariation.encodeDeltaRunAsBytes_( + deltas, pos, bytearr, optimizeSize=False + ) + elif -32768 <= minVal <= maxVal <= 32767: + pos = TupleVariation.encodeDeltaRunAsWords_( + deltas, pos, bytearr, optimizeSize=False + ) + else: + pos = TupleVariation.encodeDeltaRunAsLongs_( + deltas, pos, bytearr, optimizeSize=False + ) + + assert pos == numDeltas, (pos, numDeltas) + + return bytearr + + @staticmethod + def encodeDeltaRunAsZeroes_(deltas, offset, bytearr): + pos = offset + numDeltas = len(deltas) + while pos < numDeltas and deltas[pos] == 0: + pos += 1 + runLength = pos - offset + while runLength >= 64: + bytearr.append(DELTAS_ARE_ZERO | 63) + runLength -= 64 + if runLength: + bytearr.append(DELTAS_ARE_ZERO | (runLength - 1)) + return pos + + @staticmethod + def encodeDeltaRunAsBytes_(deltas, offset, bytearr, optimizeSize=True): + pos = offset + numDeltas = len(deltas) + while pos < numDeltas: + value = deltas[pos] + if not (-128 <= value <= 127): + break + # Within a byte-encoded run of deltas, a single zero + # is best stored literally as 0x00 value. However, + # if are two or more zeroes in a sequence, it is + # better to start a new run. For example, the sequence + # of deltas [15, 15, 0, 15, 15] becomes 6 bytes + # (04 0F 0F 00 0F 0F) when storing the zero value + # literally, but 7 bytes (01 0F 0F 80 01 0F 0F) + # when starting a new run. + if ( + optimizeSize + and value == 0 + and pos + 1 < numDeltas + and deltas[pos + 1] == 0 + ): + break + pos += 1 + runLength = pos - offset + while runLength >= 64: + bytearr.append(63) + bytearr.extend(array.array("b", deltas[offset : offset + 64])) + offset += 64 + runLength -= 64 + if runLength: + bytearr.append(runLength - 1) + bytearr.extend(array.array("b", deltas[offset:pos])) + return pos + + @staticmethod + def encodeDeltaRunAsWords_(deltas, offset, bytearr, optimizeSize=True): + pos = offset + numDeltas = len(deltas) + while pos < numDeltas: + value = deltas[pos] + + # Within a word-encoded run of deltas, it is easiest + # to start a new run (with a different encoding) + # whenever we encounter a zero value. For example, + # the sequence [0x6666, 0, 0x7777] needs 7 bytes when + # storing the zero literally (42 66 66 00 00 77 77), + # and equally 7 bytes when starting a new run + # (40 66 66 80 40 77 77). + if optimizeSize and value == 0: + break + + # Within a word-encoded run of deltas, a single value + # in the range (-128..127) should be encoded literally + # because it is more compact. For example, the sequence + # [0x6666, 2, 0x7777] becomes 7 bytes when storing + # the value literally (42 66 66 00 02 77 77), but 8 bytes + # when starting a new run (40 66 66 00 02 40 77 77). + if ( + optimizeSize + and (-128 <= value <= 127) + and pos + 1 < numDeltas + and (-128 <= deltas[pos + 1] <= 127) + ): + break + + if not (-32768 <= value <= 32767): + break + + pos += 1 + runLength = pos - offset + while runLength >= 64: + bytearr.append(DELTAS_ARE_WORDS | 63) + a = array.array("h", deltas[offset : offset + 64]) + if sys.byteorder != "big": + a.byteswap() + bytearr.extend(a) + offset += 64 + runLength -= 64 + if runLength: + bytearr.append(DELTAS_ARE_WORDS | (runLength - 1)) + a = array.array("h", deltas[offset:pos]) + if sys.byteorder != "big": + a.byteswap() + bytearr.extend(a) + return pos + + @staticmethod + def encodeDeltaRunAsLongs_(deltas, offset, bytearr, optimizeSize=True): + pos = offset + numDeltas = len(deltas) + while pos < numDeltas: + value = deltas[pos] + if optimizeSize and -32768 <= value <= 32767: + break + pos += 1 + runLength = pos - offset + while runLength >= 64: + bytearr.append(DELTAS_ARE_LONGS | 63) + a = array.array("i", deltas[offset : offset + 64]) + if sys.byteorder != "big": + a.byteswap() + bytearr.extend(a) + offset += 64 + runLength -= 64 + if runLength: + bytearr.append(DELTAS_ARE_LONGS | (runLength - 1)) + a = array.array("i", deltas[offset:pos]) + if sys.byteorder != "big": + a.byteswap() + bytearr.extend(a) + return pos + + @staticmethod + def decompileDeltas_(numDeltas, data, offset=0): + """(numDeltas, data, offset) --> ([delta, delta, ...], newOffset)""" + result = [] + pos = offset + while len(result) < numDeltas if numDeltas is not None else pos < len(data): + runHeader = data[pos] + pos += 1 + numDeltasInRun = (runHeader & DELTA_RUN_COUNT_MASK) + 1 + if (runHeader & DELTAS_SIZE_MASK) == DELTAS_ARE_ZERO: + result.extend([0] * numDeltasInRun) + else: + if (runHeader & DELTAS_SIZE_MASK) == DELTAS_ARE_LONGS: + deltas = array.array("i") + deltasSize = numDeltasInRun * 4 + elif (runHeader & DELTAS_SIZE_MASK) == DELTAS_ARE_WORDS: + deltas = array.array("h") + deltasSize = numDeltasInRun * 2 + else: + deltas = array.array("b") + deltasSize = numDeltasInRun + deltas.frombytes(data[pos : pos + deltasSize]) + if sys.byteorder != "big": + deltas.byteswap() + assert len(deltas) == numDeltasInRun, (len(deltas), numDeltasInRun) + pos += deltasSize + result.extend(deltas) + assert numDeltas is None or len(result) == numDeltas + return (result, pos) + + @staticmethod + def getTupleSize_(flags, axisCount): + size = 4 + if (flags & EMBEDDED_PEAK_TUPLE) != 0: + size += axisCount * 2 + if (flags & INTERMEDIATE_REGION) != 0: + size += axisCount * 4 + return size + + def getCoordWidth(self): + """Return 2 if coordinates are (x, y) as in gvar, 1 if single values + as in cvar, or 0 if empty. + """ + firstDelta = next((c for c in self.coordinates if c is not None), None) + if firstDelta is None: + return 0 # empty or has no impact + if type(firstDelta) in (int, float): + return 1 + if type(firstDelta) is tuple and len(firstDelta) == 2: + return 2 + raise TypeError( + "invalid type of delta; expected (int or float) number, or " + "Tuple[number, number]: %r" % firstDelta + ) + + def scaleDeltas(self, scalar): + if scalar == 1.0: + return # no change + coordWidth = self.getCoordWidth() + self.coordinates = [ + ( + None + if d is None + else d * scalar if coordWidth == 1 else (d[0] * scalar, d[1] * scalar) + ) + for d in self.coordinates + ] + + def roundDeltas(self): + coordWidth = self.getCoordWidth() + self.coordinates = [ + ( + None + if d is None + else otRound(d) if coordWidth == 1 else (otRound(d[0]), otRound(d[1])) + ) + for d in self.coordinates + ] + + def calcInferredDeltas(self, origCoords, endPts): + from fontTools.varLib.iup import iup_delta + + if self.getCoordWidth() == 1: + raise TypeError("Only 'gvar' TupleVariation can have inferred deltas") + if None in self.coordinates: + if len(self.coordinates) != len(origCoords): + raise ValueError( + "Expected len(origCoords) == %d; found %d" + % (len(self.coordinates), len(origCoords)) + ) + self.coordinates = iup_delta(self.coordinates, origCoords, endPts) + + def optimize(self, origCoords, endPts, tolerance=0.5, isComposite=False): + from fontTools.varLib.iup import iup_delta_optimize + + if None in self.coordinates: + return # already optimized + + deltaOpt = iup_delta_optimize( + self.coordinates, origCoords, endPts, tolerance=tolerance + ) + if None in deltaOpt: + if isComposite and all(d is None for d in deltaOpt): + # Fix for macOS composites + # https://github.com/fonttools/fonttools/issues/1381 + deltaOpt = [(0, 0)] + [None] * (len(deltaOpt) - 1) + # Use "optimized" version only if smaller... + varOpt = TupleVariation(self.axes, deltaOpt) + + # Shouldn't matter that this is different from fvar...? + axisTags = sorted(self.axes.keys()) + tupleData, auxData = self.compile(axisTags) + unoptimizedLength = len(tupleData) + len(auxData) + tupleData, auxData = varOpt.compile(axisTags) + optimizedLength = len(tupleData) + len(auxData) + + if optimizedLength < unoptimizedLength: + self.coordinates = varOpt.coordinates + + def __imul__(self, scalar): + self.scaleDeltas(scalar) + return self + + def __iadd__(self, other): + if not isinstance(other, TupleVariation): + return NotImplemented + deltas1 = self.coordinates + length = len(deltas1) + deltas2 = other.coordinates + if len(deltas2) != length: + raise ValueError("cannot sum TupleVariation deltas with different lengths") + # 'None' values have different meanings in gvar vs cvar TupleVariations: + # within the gvar, when deltas are not provided explicitly for some points, + # they need to be inferred; whereas for the 'cvar' table, if deltas are not + # provided for some CVT values, then no adjustments are made (i.e. None == 0). + # Thus, we cannot sum deltas for gvar TupleVariations if they contain + # inferred inferred deltas (the latter need to be computed first using + # 'calcInferredDeltas' method), but we can treat 'None' values in cvar + # deltas as if they are zeros. + if self.getCoordWidth() == 2: + for i, d2 in zip(range(length), deltas2): + d1 = deltas1[i] + try: + deltas1[i] = (d1[0] + d2[0], d1[1] + d2[1]) + except TypeError: + raise ValueError("cannot sum gvar deltas with inferred points") + else: + for i, d2 in zip(range(length), deltas2): + d1 = deltas1[i] + if d1 is not None and d2 is not None: + deltas1[i] = d1 + d2 + elif d1 is None and d2 is not None: + deltas1[i] = d2 + # elif d2 is None do nothing + return self + + +def decompileSharedTuples(axisTags, sharedTupleCount, data, offset): + result = [] + for _ in range(sharedTupleCount): + t, offset = TupleVariation.decompileCoord_(axisTags, data, offset) + result.append(t) + return result + + +def compileSharedTuples( + axisTags, variations, MAX_NUM_SHARED_COORDS=TUPLE_INDEX_MASK + 1 +): + coordCount = Counter() + for var in variations: + coord = var.compileCoord(axisTags) + coordCount[coord] += 1 + # In python < 3.7, most_common() ordering is non-deterministic + # so apply a sort to make sure the ordering is consistent. + sharedCoords = sorted( + coordCount.most_common(MAX_NUM_SHARED_COORDS), + key=lambda item: (-item[1], item[0]), + ) + return [c[0] for c in sharedCoords if c[1] > 1] + + +def compileTupleVariationStore( + variations, + pointCount, + axisTags, + sharedTupleIndices, + useSharedPoints=True, + *, + optimizeSize=True, +): + # pointCount is actually unused. Keeping for API compat. + del pointCount + newVariations = [] + pointDatas = [] + # Compile all points and figure out sharing if desired + sharedPoints = None + + # Collect, count, and compile point-sets for all variation sets + pointSetCount = defaultdict(int) + for v in variations: + points = v.getUsedPoints() + if points is None: # Empty variations + continue + pointSetCount[points] += 1 + newVariations.append(v) + pointDatas.append(points) + variations = newVariations + del newVariations + + if not variations: + return (0, b"", b"") + + n = len(variations[0].coordinates) + assert all( + len(v.coordinates) == n for v in variations + ), "Variation sets have different sizes" + + compiledPoints = { + pointSet: TupleVariation.compilePoints(pointSet) for pointSet in pointSetCount + } + + tupleVariationCount = len(variations) + tuples = [] + data = [] + + if useSharedPoints: + # Find point-set which saves most bytes. + def key(pn): + pointSet = pn[0] + count = pn[1] + return len(compiledPoints[pointSet]) * (count - 1) + + sharedPoints = max(pointSetCount.items(), key=key)[0] + + data.append(compiledPoints[sharedPoints]) + tupleVariationCount |= TUPLES_SHARE_POINT_NUMBERS + + # b'' implies "use shared points" + pointDatas = [ + compiledPoints[points] if points != sharedPoints else b"" + for points in pointDatas + ] + + for v, p in zip(variations, pointDatas): + thisTuple, thisData = v.compile( + axisTags, sharedTupleIndices, pointData=p, optimizeSize=optimizeSize + ) + + tuples.append(thisTuple) + data.append(thisData) + + tuples = b"".join(tuples) + data = b"".join(data) + return tupleVariationCount, tuples, data + + +def decompileTupleVariationStore( + tableTag, + axisTags, + tupleVariationCount, + pointCount, + sharedTuples, + data, + pos, + dataPos, +): + numAxes = len(axisTags) + result = [] + if (tupleVariationCount & TUPLES_SHARE_POINT_NUMBERS) != 0: + sharedPoints, dataPos = TupleVariation.decompilePoints_( + pointCount, data, dataPos, tableTag + ) + else: + sharedPoints = [] + for _ in range(tupleVariationCount & TUPLE_COUNT_MASK): + dataSize, flags = struct.unpack(">HH", data[pos : pos + 4]) + tupleSize = TupleVariation.getTupleSize_(flags, numAxes) + tupleData = data[pos : pos + tupleSize] + pointDeltaData = data[dataPos : dataPos + dataSize] + result.append( + decompileTupleVariation_( + pointCount, + sharedTuples, + sharedPoints, + tableTag, + axisTags, + tupleData, + pointDeltaData, + ) + ) + pos += tupleSize + dataPos += dataSize + return result + + +def decompileTupleVariation_( + pointCount, sharedTuples, sharedPoints, tableTag, axisTags, data, tupleData +): + assert tableTag in ("cvar", "gvar"), tableTag + flags = struct.unpack(">H", data[2:4])[0] + pos = 4 + if (flags & EMBEDDED_PEAK_TUPLE) == 0: + peak = sharedTuples[flags & TUPLE_INDEX_MASK] + else: + peak, pos = TupleVariation.decompileCoord_(axisTags, data, pos) + if (flags & INTERMEDIATE_REGION) != 0: + start, pos = TupleVariation.decompileCoord_(axisTags, data, pos) + end, pos = TupleVariation.decompileCoord_(axisTags, data, pos) + else: + start, end = inferRegion_(peak) + axes = {} + for axis in axisTags: + region = start[axis], peak[axis], end[axis] + if region != (0.0, 0.0, 0.0): + axes[axis] = region + pos = 0 + if (flags & PRIVATE_POINT_NUMBERS) != 0: + points, pos = TupleVariation.decompilePoints_( + pointCount, tupleData, pos, tableTag + ) + else: + points = sharedPoints + + deltas = [None] * pointCount + + if tableTag == "cvar": + deltas_cvt, pos = TupleVariation.decompileDeltas_(len(points), tupleData, pos) + for p, delta in zip(points, deltas_cvt): + if 0 <= p < pointCount: + deltas[p] = delta + + elif tableTag == "gvar": + deltas_x, pos = TupleVariation.decompileDeltas_(len(points), tupleData, pos) + deltas_y, pos = TupleVariation.decompileDeltas_(len(points), tupleData, pos) + for p, x, y in zip(points, deltas_x, deltas_y): + if 0 <= p < pointCount: + deltas[p] = (x, y) + + return TupleVariation(axes, deltas) + + +def inferRegion_(peak): + """Infer start and end for a (non-intermediate) region + + This helper function computes the applicability region for + variation tuples whose INTERMEDIATE_REGION flag is not set in the + TupleVariationHeader structure. Variation tuples apply only to + certain regions of the variation space; outside that region, the + tuple has no effect. To make the binary encoding more compact, + TupleVariationHeaders can omit the intermediateStartTuple and + intermediateEndTuple fields. + """ + start, end = {}, {} + for axis, value in peak.items(): + start[axis] = min(value, 0.0) # -0.3 --> -0.3; 0.7 --> 0.0 + end[axis] = max(value, 0.0) # -0.3 --> 0.0; 0.7 --> 0.7 + return (start, end) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/V_A_R_C_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/V_A_R_C_.py new file mode 100644 index 0000000000000000000000000000000000000000..afc1497d14ffd4aed6668af4cb0587135e5562f9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/V_A_R_C_.py @@ -0,0 +1,12 @@ +from .otBase import BaseTTXConverter + + +class table_V_A_R_C_(BaseTTXConverter): + """Variable Components table + + The ``VARC`` table contains variation information for composite glyphs. + + See also https://github.com/harfbuzz/boring-expansion-spec/blob/main/VARC.md + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/V_D_M_X_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/V_D_M_X_.py new file mode 100644 index 0000000000000000000000000000000000000000..6f8abc46de903fbc300fc4ee4b803cb47bf03ba0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/V_D_M_X_.py @@ -0,0 +1,249 @@ +from . import DefaultTable +from fontTools.misc import sstruct +from fontTools.misc.textTools import safeEval +import struct + +VDMX_HeaderFmt = """ + > # big endian + version: H # Version number (0 or 1) + numRecs: H # Number of VDMX groups present + numRatios: H # Number of aspect ratio groupings +""" +# the VMDX header is followed by an array of RatRange[numRatios] (i.e. aspect +# ratio ranges); +VDMX_RatRangeFmt = """ + > # big endian + bCharSet: B # Character set + xRatio: B # Value to use for x-Ratio + yStartRatio: B # Starting y-Ratio value + yEndRatio: B # Ending y-Ratio value +""" +# followed by an array of offset[numRatios] from start of VDMX table to the +# VDMX Group for this ratio range (offsets will be re-calculated on compile); +# followed by an array of Group[numRecs] records; +VDMX_GroupFmt = """ + > # big endian + recs: H # Number of height records in this group + startsz: B # Starting yPelHeight + endsz: B # Ending yPelHeight +""" +# followed by an array of vTable[recs] records. +VDMX_vTableFmt = """ + > # big endian + yPelHeight: H # yPelHeight to which values apply + yMax: h # Maximum value (in pels) for this yPelHeight + yMin: h # Minimum value (in pels) for this yPelHeight +""" + + +class table_V_D_M_X_(DefaultTable.DefaultTable): + """Vertical Device Metrics table + + The ``VDMX`` table records changes to the vertical glyph minima + and maxima that result from Truetype instructions. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/vdmx + """ + + def decompile(self, data, ttFont): + pos = 0 # track current position from to start of VDMX table + dummy, data = sstruct.unpack2(VDMX_HeaderFmt, data, self) + pos += sstruct.calcsize(VDMX_HeaderFmt) + self.ratRanges = [] + for i in range(self.numRatios): + ratio, data = sstruct.unpack2(VDMX_RatRangeFmt, data) + pos += sstruct.calcsize(VDMX_RatRangeFmt) + # the mapping between a ratio and a group is defined further below + ratio["groupIndex"] = None + self.ratRanges.append(ratio) + lenOffset = struct.calcsize(">H") + _offsets = [] # temporarily store offsets to groups + for i in range(self.numRatios): + offset = struct.unpack(">H", data[0:lenOffset])[0] + data = data[lenOffset:] + pos += lenOffset + _offsets.append(offset) + self.groups = [] + for groupIndex in range(self.numRecs): + # the offset to this group from beginning of the VDMX table + currOffset = pos + group, data = sstruct.unpack2(VDMX_GroupFmt, data) + # the group lenght and bounding sizes are re-calculated on compile + recs = group.pop("recs") + startsz = group.pop("startsz") + endsz = group.pop("endsz") + pos += sstruct.calcsize(VDMX_GroupFmt) + for j in range(recs): + vTable, data = sstruct.unpack2(VDMX_vTableFmt, data) + vTableLength = sstruct.calcsize(VDMX_vTableFmt) + pos += vTableLength + # group is a dict of (yMax, yMin) tuples keyed by yPelHeight + group[vTable["yPelHeight"]] = (vTable["yMax"], vTable["yMin"]) + # make sure startsz and endsz match the calculated values + minSize = min(group.keys()) + maxSize = max(group.keys()) + assert ( + startsz == minSize + ), "startsz (%s) must equal min yPelHeight (%s): group %d" % ( + group.startsz, + minSize, + groupIndex, + ) + assert ( + endsz == maxSize + ), "endsz (%s) must equal max yPelHeight (%s): group %d" % ( + group.endsz, + maxSize, + groupIndex, + ) + self.groups.append(group) + # match the defined offsets with the current group's offset + for offsetIndex, offsetValue in enumerate(_offsets): + # when numRecs < numRatios there can more than one ratio range + # sharing the same VDMX group + if currOffset == offsetValue: + # map the group with the ratio range thas has the same + # index as the offset to that group (it took me a while..) + self.ratRanges[offsetIndex]["groupIndex"] = groupIndex + # check that all ratio ranges have a group + for i in range(self.numRatios): + ratio = self.ratRanges[i] + if ratio["groupIndex"] is None: + from fontTools import ttLib + + raise ttLib.TTLibError("no group defined for ratRange %d" % i) + + def _getOffsets(self): + """ + Calculate offsets to VDMX_Group records. + For each ratRange return a list of offset values from the beginning of + the VDMX table to a VDMX_Group. + """ + lenHeader = sstruct.calcsize(VDMX_HeaderFmt) + lenRatRange = sstruct.calcsize(VDMX_RatRangeFmt) + lenOffset = struct.calcsize(">H") + lenGroupHeader = sstruct.calcsize(VDMX_GroupFmt) + lenVTable = sstruct.calcsize(VDMX_vTableFmt) + # offset to the first group + pos = lenHeader + self.numRatios * lenRatRange + self.numRatios * lenOffset + groupOffsets = [] + for group in self.groups: + groupOffsets.append(pos) + lenGroup = lenGroupHeader + len(group) * lenVTable + pos += lenGroup # offset to next group + offsets = [] + for ratio in self.ratRanges: + groupIndex = ratio["groupIndex"] + offsets.append(groupOffsets[groupIndex]) + return offsets + + def compile(self, ttFont): + if not (self.version == 0 or self.version == 1): + from fontTools import ttLib + + raise ttLib.TTLibError( + "unknown format for VDMX table: version %s" % self.version + ) + data = sstruct.pack(VDMX_HeaderFmt, self) + for ratio in self.ratRanges: + data += sstruct.pack(VDMX_RatRangeFmt, ratio) + # recalculate offsets to VDMX groups + for offset in self._getOffsets(): + data += struct.pack(">H", offset) + for group in self.groups: + recs = len(group) + startsz = min(group.keys()) + endsz = max(group.keys()) + gHeader = {"recs": recs, "startsz": startsz, "endsz": endsz} + data += sstruct.pack(VDMX_GroupFmt, gHeader) + for yPelHeight, (yMax, yMin) in sorted(group.items()): + vTable = {"yPelHeight": yPelHeight, "yMax": yMax, "yMin": yMin} + data += sstruct.pack(VDMX_vTableFmt, vTable) + return data + + def toXML(self, writer, ttFont): + writer.simpletag("version", value=self.version) + writer.newline() + writer.begintag("ratRanges") + writer.newline() + for ratio in self.ratRanges: + groupIndex = ratio["groupIndex"] + writer.simpletag( + "ratRange", + bCharSet=ratio["bCharSet"], + xRatio=ratio["xRatio"], + yStartRatio=ratio["yStartRatio"], + yEndRatio=ratio["yEndRatio"], + groupIndex=groupIndex, + ) + writer.newline() + writer.endtag("ratRanges") + writer.newline() + writer.begintag("groups") + writer.newline() + for groupIndex in range(self.numRecs): + group = self.groups[groupIndex] + recs = len(group) + startsz = min(group.keys()) + endsz = max(group.keys()) + writer.begintag("group", index=groupIndex) + writer.newline() + writer.comment("recs=%d, startsz=%d, endsz=%d" % (recs, startsz, endsz)) + writer.newline() + for yPelHeight, (yMax, yMin) in sorted(group.items()): + writer.simpletag( + "record", + [("yPelHeight", yPelHeight), ("yMax", yMax), ("yMin", yMin)], + ) + writer.newline() + writer.endtag("group") + writer.newline() + writer.endtag("groups") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "version": + self.version = safeEval(attrs["value"]) + elif name == "ratRanges": + if not hasattr(self, "ratRanges"): + self.ratRanges = [] + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name == "ratRange": + if not hasattr(self, "numRatios"): + self.numRatios = 1 + else: + self.numRatios += 1 + ratio = { + "bCharSet": safeEval(attrs["bCharSet"]), + "xRatio": safeEval(attrs["xRatio"]), + "yStartRatio": safeEval(attrs["yStartRatio"]), + "yEndRatio": safeEval(attrs["yEndRatio"]), + "groupIndex": safeEval(attrs["groupIndex"]), + } + self.ratRanges.append(ratio) + elif name == "groups": + if not hasattr(self, "groups"): + self.groups = [] + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name == "group": + if not hasattr(self, "numRecs"): + self.numRecs = 1 + else: + self.numRecs += 1 + group = {} + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name == "record": + yPelHeight = safeEval(attrs["yPelHeight"]) + yMax = safeEval(attrs["yMax"]) + yMin = safeEval(attrs["yMin"]) + group[yPelHeight] = (yMax, yMin) + self.groups.append(group) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/V_O_R_G_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/V_O_R_G_.py new file mode 100644 index 0000000000000000000000000000000000000000..2c53acba431059f58f86dbb1b89755a03f699f94 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/V_O_R_G_.py @@ -0,0 +1,165 @@ +from fontTools.misc.textTools import bytesjoin, safeEval +from . import DefaultTable +import struct + + +class table_V_O_R_G_(DefaultTable.DefaultTable): + """Vertical Origin table + + The ``VORG`` table contains the vertical origin of each glyph + in a `CFF` or `CFF2` font. + + This table is structured so that you can treat it like a dictionary keyed by glyph name. + + ``ttFont['VORG'][<glyphName>]`` will return the vertical origin for any glyph. + + ``ttFont['VORG'][<glyphName>] = <value>`` will set the vertical origin for any glyph. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/vorg + """ + + def decompile(self, data, ttFont): + self.getGlyphName = ( + ttFont.getGlyphName + ) # for use in get/set item functions, for access by GID + ( + self.majorVersion, + self.minorVersion, + self.defaultVertOriginY, + self.numVertOriginYMetrics, + ) = struct.unpack(">HHhH", data[:8]) + assert ( + self.majorVersion <= 1 + ), "Major version of VORG table is higher than I know how to handle" + data = data[8:] + vids = [] + gids = [] + pos = 0 + for i in range(self.numVertOriginYMetrics): + gid, vOrigin = struct.unpack(">Hh", data[pos : pos + 4]) + pos += 4 + gids.append(gid) + vids.append(vOrigin) + + self.VOriginRecords = vOrig = {} + glyphOrder = ttFont.getGlyphOrder() + try: + names = [glyphOrder[gid] for gid in gids] + except IndexError: + getGlyphName = self.getGlyphName + names = map(getGlyphName, gids) + + for name, vid in zip(names, vids): + vOrig[name] = vid + + def compile(self, ttFont): + vorgs = list(self.VOriginRecords.values()) + names = list(self.VOriginRecords.keys()) + nameMap = ttFont.getReverseGlyphMap() + try: + gids = [nameMap[name] for name in names] + except KeyError: + nameMap = ttFont.getReverseGlyphMap(rebuild=True) + gids = [nameMap[name] for name in names] + vOriginTable = list(zip(gids, vorgs)) + self.numVertOriginYMetrics = len(vorgs) + vOriginTable.sort() # must be in ascending GID order + dataList = [struct.pack(">Hh", rec[0], rec[1]) for rec in vOriginTable] + header = struct.pack( + ">HHhH", + self.majorVersion, + self.minorVersion, + self.defaultVertOriginY, + self.numVertOriginYMetrics, + ) + dataList.insert(0, header) + data = bytesjoin(dataList) + return data + + def toXML(self, writer, ttFont): + writer.simpletag("majorVersion", value=self.majorVersion) + writer.newline() + writer.simpletag("minorVersion", value=self.minorVersion) + writer.newline() + writer.simpletag("defaultVertOriginY", value=self.defaultVertOriginY) + writer.newline() + writer.simpletag("numVertOriginYMetrics", value=self.numVertOriginYMetrics) + writer.newline() + vOriginTable = [] + glyphNames = self.VOriginRecords.keys() + for glyphName in glyphNames: + try: + gid = ttFont.getGlyphID(glyphName) + except: + assert 0, ( + "VORG table contains a glyph name not in ttFont.getGlyphNames(): " + + str(glyphName) + ) + vOriginTable.append([gid, glyphName, self.VOriginRecords[glyphName]]) + vOriginTable.sort() + for entry in vOriginTable: + vOriginRec = VOriginRecord(entry[1], entry[2]) + vOriginRec.toXML(writer, ttFont) + + def fromXML(self, name, attrs, content, ttFont): + if not hasattr(self, "VOriginRecords"): + self.VOriginRecords = {} + self.getGlyphName = ( + ttFont.getGlyphName + ) # for use in get/set item functions, for access by GID + if name == "VOriginRecord": + vOriginRec = VOriginRecord() + for element in content: + if isinstance(element, str): + continue + name, attrs, content = element + vOriginRec.fromXML(name, attrs, content, ttFont) + self.VOriginRecords[vOriginRec.glyphName] = vOriginRec.vOrigin + elif "value" in attrs: + setattr(self, name, safeEval(attrs["value"])) + + def __getitem__(self, glyphSelector): + if isinstance(glyphSelector, int): + # its a gid, convert to glyph name + glyphSelector = self.getGlyphName(glyphSelector) + + if glyphSelector not in self.VOriginRecords: + return self.defaultVertOriginY + + return self.VOriginRecords[glyphSelector] + + def __setitem__(self, glyphSelector, value): + if isinstance(glyphSelector, int): + # its a gid, convert to glyph name + glyphSelector = self.getGlyphName(glyphSelector) + + if value != self.defaultVertOriginY: + self.VOriginRecords[glyphSelector] = value + elif glyphSelector in self.VOriginRecords: + del self.VOriginRecords[glyphSelector] + + def __delitem__(self, glyphSelector): + del self.VOriginRecords[glyphSelector] + + +class VOriginRecord(object): + def __init__(self, name=None, vOrigin=None): + self.glyphName = name + self.vOrigin = vOrigin + + def toXML(self, writer, ttFont): + writer.begintag("VOriginRecord") + writer.newline() + writer.simpletag("glyphName", value=self.glyphName) + writer.newline() + writer.simpletag("vOrigin", value=self.vOrigin) + writer.newline() + writer.endtag("VOriginRecord") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + value = attrs["value"] + if name == "glyphName": + setattr(self, name, value) + else: + setattr(self, name, safeEval(value)) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/V_V_A_R_.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/V_V_A_R_.py new file mode 100644 index 0000000000000000000000000000000000000000..c0c94e348b2c6cdfc856b030477214604c95d7c4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/V_V_A_R_.py @@ -0,0 +1,13 @@ +from .otBase import BaseTTXConverter + + +class table_V_V_A_R_(BaseTTXConverter): + """Vertical Metrics Variations table + + The ``VVAR`` table contains variation data for per-glyph vertical metrics + in a variable font. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/vvar + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/__init__.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b111097a804e5c6563860f98a77c2f5c499d60f1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/__init__.py @@ -0,0 +1,98 @@ +# DON'T EDIT! This file is generated by MetaTools/buildTableList.py. +def _moduleFinderHint(): + """Dummy function to let modulefinder know what tables may be + dynamically imported. Generated by MetaTools/buildTableList.py. + + >>> _moduleFinderHint() + """ + from . import B_A_S_E_ + from . import C_B_D_T_ + from . import C_B_L_C_ + from . import C_F_F_ + from . import C_F_F__2 + from . import C_O_L_R_ + from . import C_P_A_L_ + from . import D_S_I_G_ + from . import D__e_b_g + from . import E_B_D_T_ + from . import E_B_L_C_ + from . import F_F_T_M_ + from . import F__e_a_t + from . import G_D_E_F_ + from . import G_M_A_P_ + from . import G_P_K_G_ + from . import G_P_O_S_ + from . import G_S_U_B_ + from . import G_V_A_R_ + from . import G__l_a_t + from . import G__l_o_c + from . import H_V_A_R_ + from . import J_S_T_F_ + from . import L_T_S_H_ + from . import M_A_T_H_ + from . import M_E_T_A_ + from . import M_V_A_R_ + from . import O_S_2f_2 + from . import S_I_N_G_ + from . import S_T_A_T_ + from . import S_V_G_ + from . import S__i_l_f + from . import S__i_l_l + from . import T_S_I_B_ + from . import T_S_I_C_ + from . import T_S_I_D_ + from . import T_S_I_J_ + from . import T_S_I_P_ + from . import T_S_I_S_ + from . import T_S_I_V_ + from . import T_S_I__0 + from . import T_S_I__1 + from . import T_S_I__2 + from . import T_S_I__3 + from . import T_S_I__5 + from . import T_T_F_A_ + from . import V_A_R_C_ + from . import V_D_M_X_ + from . import V_O_R_G_ + from . import V_V_A_R_ + from . import _a_n_k_r + from . import _a_v_a_r + from . import _b_s_l_n + from . import _c_i_d_g + from . import _c_m_a_p + from . import _c_v_a_r + from . import _c_v_t + from . import _f_e_a_t + from . import _f_p_g_m + from . import _f_v_a_r + from . import _g_a_s_p + from . import _g_c_i_d + from . import _g_l_y_f + from . import _g_v_a_r + from . import _h_d_m_x + from . import _h_e_a_d + from . import _h_h_e_a + from . import _h_m_t_x + from . import _k_e_r_n + from . import _l_c_a_r + from . import _l_o_c_a + from . import _l_t_a_g + from . import _m_a_x_p + from . import _m_e_t_a + from . import _m_o_r_t + from . import _m_o_r_x + from . import _n_a_m_e + from . import _o_p_b_d + from . import _p_o_s_t + from . import _p_r_e_p + from . import _p_r_o_p + from . import _s_b_i_x + from . import _t_r_a_k + from . import _v_h_e_a + from . import _v_m_t_x + + +if __name__ == "__main__": + import doctest, sys + + sys.exit(doctest.testmod().failed) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_a_n_k_r.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_a_n_k_r.py new file mode 100644 index 0000000000000000000000000000000000000000..5466d42d4117f9935b54def71e5351fa1a0ee6ab --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_a_n_k_r.py @@ -0,0 +1,15 @@ +from .otBase import BaseTTXConverter + + +class table__a_n_k_r(BaseTTXConverter): + """Anchor Point table + + The anchor point table provides a way to define anchor points. + These are points within the coordinate space of a given glyph, + independent of the control points used to render the glyph. + Anchor points are used in conjunction with the ``kerx`` table. + + See also https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6ankr.html + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_a_v_a_r.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_a_v_a_r.py new file mode 100644 index 0000000000000000000000000000000000000000..cb4593712c91388e085e371650e8bff8dfb24740 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_a_v_a_r.py @@ -0,0 +1,200 @@ +from __future__ import annotations + +from typing import Mapping, TYPE_CHECKING +from fontTools.misc import sstruct +from fontTools.misc.fixedTools import ( + fixedToFloat as fi2fl, + floatToFixed as fl2fi, + floatToFixedToStr as fl2str, + strToFixedToFloat as str2fl, +) +from fontTools.misc.textTools import bytesjoin, safeEval +from fontTools.misc.roundTools import otRound +from fontTools.varLib.models import piecewiseLinearMap +from fontTools.varLib.varStore import VarStoreInstancer, NO_VARIATION_INDEX +from fontTools.ttLib import TTLibError +from . import DefaultTable +from . import otTables +import struct +import logging + + +log = logging.getLogger(__name__) + +from .otBase import BaseTTXConverter + +if TYPE_CHECKING: + from ..ttFont import TTFont + + +class table__a_v_a_r(BaseTTXConverter): + """Axis Variations table + + This class represents the ``avar`` table of a variable font. The object has one + substantive attribute, ``segments``, which maps axis tags to a segments dictionary:: + + >>> font["avar"].segments # doctest: +SKIP + {'wght': {-1.0: -1.0, + 0.0: 0.0, + 0.125: 0.11444091796875, + 0.25: 0.23492431640625, + 0.5: 0.35540771484375, + 0.625: 0.5, + 0.75: 0.6566162109375, + 0.875: 0.81927490234375, + 1.0: 1.0}, + 'ital': {-1.0: -1.0, 0.0: 0.0, 1.0: 1.0}} + + Notice that the segments dictionary is made up of normalized values. A valid + ``avar`` segment mapping must contain the entries ``-1.0: -1.0, 0.0: 0.0, 1.0: 1.0``. + fontTools does not enforce this, so it is your responsibility to ensure that + mappings are valid. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/avar + """ + + dependencies = ["fvar"] + + def __init__(self, tag=None): + super().__init__(tag) + self.segments = {} + + def compile(self, ttFont): + axisTags = [axis.axisTag for axis in ttFont["fvar"].axes] + if not hasattr(self, "table"): + self.table = otTables.avar() + if not hasattr(self.table, "Reserved"): + self.table.Reserved = 0 + self.table.Version = (getattr(self, "majorVersion", 1) << 16) | getattr( + self, "minorVersion", 0 + ) + self.table.AxisCount = len(axisTags) + self.table.AxisSegmentMap = [] + for axis in axisTags: + mappings = self.segments[axis] + segmentMap = otTables.AxisSegmentMap() + segmentMap.PositionMapCount = len(mappings) + segmentMap.AxisValueMap = [] + for key, value in sorted(mappings.items()): + valueMap = otTables.AxisValueMap() + valueMap.FromCoordinate = key + valueMap.ToCoordinate = value + segmentMap.AxisValueMap.append(valueMap) + self.table.AxisSegmentMap.append(segmentMap) + return super().compile(ttFont) + + def decompile(self, data, ttFont): + super().decompile(data, ttFont) + self.majorVersion = self.table.Version >> 16 + self.minorVersion = self.table.Version & 0xFFFF + if self.majorVersion not in (1, 2): + raise NotImplementedError("Unknown avar table version") + axisTags = [axis.axisTag for axis in ttFont["fvar"].axes] + for axis in axisTags: + self.segments[axis] = {} + for axis, segmentMap in zip(axisTags, self.table.AxisSegmentMap): + segments = self.segments[axis] = {} + for segment in segmentMap.AxisValueMap: + segments[segment.FromCoordinate] = segment.ToCoordinate + + def toXML(self, writer, ttFont): + writer.simpletag( + "version", + major=getattr(self, "majorVersion", 1), + minor=getattr(self, "minorVersion", 0), + ) + writer.newline() + axisTags = [axis.axisTag for axis in ttFont["fvar"].axes] + for axis in axisTags: + writer.begintag("segment", axis=axis) + writer.newline() + for key, value in sorted(self.segments[axis].items()): + key = fl2str(key, 14) + value = fl2str(value, 14) + writer.simpletag("mapping", **{"from": key, "to": value}) + writer.newline() + writer.endtag("segment") + writer.newline() + if getattr(self, "majorVersion", 1) >= 2: + if self.table.VarIdxMap: + self.table.VarIdxMap.toXML(writer, ttFont, name="VarIdxMap") + if self.table.VarStore: + self.table.VarStore.toXML(writer, ttFont) + + def fromXML(self, name, attrs, content, ttFont): + if not hasattr(self, "table"): + self.table = otTables.avar() + if not hasattr(self.table, "Reserved"): + self.table.Reserved = 0 + if name == "version": + self.majorVersion = safeEval(attrs["major"]) + self.minorVersion = safeEval(attrs["minor"]) + self.table.Version = (getattr(self, "majorVersion", 1) << 16) | getattr( + self, "minorVersion", 0 + ) + elif name == "segment": + axis = attrs["axis"] + segment = self.segments[axis] = {} + for element in content: + if isinstance(element, tuple): + elementName, elementAttrs, _ = element + if elementName == "mapping": + fromValue = str2fl(elementAttrs["from"], 14) + toValue = str2fl(elementAttrs["to"], 14) + if fromValue in segment: + log.warning( + "duplicate entry for %s in axis '%s'", fromValue, axis + ) + segment[fromValue] = toValue + else: + super().fromXML(name, attrs, content, ttFont) + + def renormalizeLocation( + self, location: Mapping[str, float], font: TTFont, dropZeroes: bool = True + ) -> dict[str, float]: + majorVersion = getattr(self, "majorVersion", 1) + + if majorVersion not in (1, 2): + raise NotImplementedError("Unknown avar table version") + + avarSegments = self.segments + mappedLocation = {} + for axisTag, value in location.items(): + avarMapping = avarSegments.get(axisTag, None) + if avarMapping is not None: + value = piecewiseLinearMap(value, avarMapping) + mappedLocation[axisTag] = value + + if majorVersion < 2: + return mappedLocation + + # Version 2 + + varIdxMap = self.table.VarIdxMap + varStore = self.table.VarStore + axes = font["fvar"].axes + if varStore is not None: + instancer = VarStoreInstancer(varStore, axes, mappedLocation) + + coords = list(fl2fi(mappedLocation.get(axis.axisTag, 0), 14) for axis in axes) + + out = [] + for varIdx, v in enumerate(coords): + + if varIdxMap is not None: + varIdx = varIdxMap[varIdx] + + if varStore is not None: + delta = instancer[varIdx] + v += otRound(delta) + v = min(max(v, -(1 << 14)), +(1 << 14)) + + out.append(v) + + mappedLocation = { + axis.axisTag: fi2fl(v, 14) + for v, axis in zip(out, axes) + if v != 0 or not dropZeroes + } + + return mappedLocation diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_b_s_l_n.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_b_s_l_n.py new file mode 100644 index 0000000000000000000000000000000000000000..85796b0a0479d26104a3fb63d9fe6085be29853a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_b_s_l_n.py @@ -0,0 +1,15 @@ +from .otBase import BaseTTXConverter + + +# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bsln.html +class table__b_s_l_n(BaseTTXConverter): + """Baseline table + + The AAT ``bsln`` table is similar in purpose to the OpenType ``BASE`` + table; it stores per-script baselines to support automatic alignment + of lines of text. + + See also https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bsln.html + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_c_i_d_g.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_c_i_d_g.py new file mode 100644 index 0000000000000000000000000000000000000000..c283e5a4dd1619a621a78b20171d38b14752c836 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_c_i_d_g.py @@ -0,0 +1,24 @@ +# coding: utf-8 +from .otBase import BaseTTXConverter + + +class table__c_i_d_g(BaseTTXConverter): + """CID to Glyph ID table + + The AAT ``cidg`` table has almost the same structure as ``gidc``, + just mapping CIDs to GlyphIDs instead of the reverse direction. + + It is useful for fonts that may be used by a PDF renderer in lieu of + a font reference with a known glyph collection but no subsetted + glyphs. For instance, a PDF can say “please use a font conforming + to Adobe-Japan-1”; the ``cidg`` mapping is necessary if the font is, + say, a TrueType font. ``gidc`` is lossy for this purpose and is + obsoleted by ``cidg``. + + For example, the first font in ``/System/Library/Fonts/PingFang.ttc`` + (which Apple ships pre-installed on MacOS 10.12.6) has a ``cidg`` table. + + See also https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6gcid.html + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_c_m_a_p.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_c_m_a_p.py new file mode 100644 index 0000000000000000000000000000000000000000..e935313a18c1038dceba0218e118470fcbc19bb4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_c_m_a_p.py @@ -0,0 +1,1591 @@ +from fontTools.misc.textTools import bytesjoin, safeEval, readHex +from fontTools.misc.encodingTools import getEncoding +from fontTools.ttLib import getSearchRange +from fontTools.unicode import Unicode +from . import DefaultTable +import sys +import struct +import array +import logging + + +log = logging.getLogger(__name__) + + +def _make_map(font, chars, gids): + assert len(chars) == len(gids) + glyphNames = font.getGlyphNameMany(gids) + cmap = {} + for char, gid, name in zip(chars, gids, glyphNames): + if gid == 0: + continue + cmap[char] = name + return cmap + + +class table__c_m_a_p(DefaultTable.DefaultTable): + """Character to Glyph Index Mapping Table + + This class represents the `cmap <https://docs.microsoft.com/en-us/typography/opentype/spec/cmap>`_ + table, which maps between input characters (in Unicode or other system encodings) + and glyphs within the font. The ``cmap`` table contains one or more subtables + which determine the mapping of of characters to glyphs across different platforms + and encoding systems. + + ``table__c_m_a_p`` objects expose an accessor ``.tables`` which provides access + to the subtables, although it is normally easier to retrieve individual subtables + through the utility methods described below. To add new subtables to a font, + first determine the subtable format (if in doubt use format 4 for glyphs within + the BMP, format 12 for glyphs outside the BMP, and format 14 for Unicode Variation + Sequences) construct subtable objects with ``CmapSubtable.newSubtable(format)``, + and append them to the ``.tables`` list. + + Within a subtable, the mapping of characters to glyphs is provided by the ``.cmap`` + attribute. + + Example:: + + cmap4_0_3 = CmapSubtable.newSubtable(4) + cmap4_0_3.platformID = 0 + cmap4_0_3.platEncID = 3 + cmap4_0_3.language = 0 + cmap4_0_3.cmap = { 0xC1: "Aacute" } + + cmap = newTable("cmap") + cmap.tableVersion = 0 + cmap.tables = [cmap4_0_3] + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/cmap + """ + + def getcmap(self, platformID, platEncID): + """Returns the first subtable which matches the given platform and encoding. + + Args: + platformID (int): The platform ID. Use 0 for Unicode, 1 for Macintosh + (deprecated for new fonts), 2 for ISO (deprecated) and 3 for Windows. + encodingID (int): Encoding ID. Interpretation depends on the platform ID. + See the OpenType specification for details. + + Returns: + An object which is a subclass of :py:class:`CmapSubtable` if a matching + subtable is found within the font, or ``None`` otherwise. + """ + + for subtable in self.tables: + if subtable.platformID == platformID and subtable.platEncID == platEncID: + return subtable + return None # not found + + def getBestCmap( + self, + cmapPreferences=( + (3, 10), + (0, 6), + (0, 4), + (3, 1), + (0, 3), + (0, 2), + (0, 1), + (0, 0), + ), + ): + """Returns the 'best' Unicode cmap dictionary available in the font + or ``None``, if no Unicode cmap subtable is available. + + By default it will search for the following (platformID, platEncID) + pairs in order:: + + (3, 10), # Windows Unicode full repertoire + (0, 6), # Unicode full repertoire (format 13 subtable) + (0, 4), # Unicode 2.0 full repertoire + (3, 1), # Windows Unicode BMP + (0, 3), # Unicode 2.0 BMP + (0, 2), # Unicode ISO/IEC 10646 + (0, 1), # Unicode 1.1 + (0, 0) # Unicode 1.0 + + This particular order matches what HarfBuzz uses to choose what + subtable to use by default. This order prefers the largest-repertoire + subtable, and among those, prefers the Windows-platform over the + Unicode-platform as the former has wider support. + + This order can be customized via the ``cmapPreferences`` argument. + """ + for platformID, platEncID in cmapPreferences: + cmapSubtable = self.getcmap(platformID, platEncID) + if cmapSubtable is not None: + return cmapSubtable.cmap + return None # None of the requested cmap subtables were found + + def buildReversed(self): + """Builds a reverse mapping dictionary + + Iterates over all Unicode cmap tables and returns a dictionary mapping + glyphs to sets of codepoints, such as:: + + { + 'one': {0x31} + 'A': {0x41,0x391} + } + + The values are sets of Unicode codepoints because + some fonts map different codepoints to the same glyph. + For example, ``U+0041 LATIN CAPITAL LETTER A`` and ``U+0391 + GREEK CAPITAL LETTER ALPHA`` are sometimes the same glyph. + """ + result = {} + for subtable in self.tables: + if subtable.isUnicode(): + for codepoint, name in subtable.cmap.items(): + result.setdefault(name, set()).add(codepoint) + return result + + def buildReversedMin(self): + result = {} + for subtable in self.tables: + if subtable.isUnicode(): + for codepoint, name in subtable.cmap.items(): + if name in result: + result[name] = min(result[name], codepoint) + else: + result[name] = codepoint + return result + + def decompile(self, data, ttFont): + tableVersion, numSubTables = struct.unpack(">HH", data[:4]) + self.tableVersion = int(tableVersion) + self.tables = tables = [] + seenOffsets = {} + for i in range(numSubTables): + platformID, platEncID, offset = struct.unpack( + ">HHl", data[4 + i * 8 : 4 + (i + 1) * 8] + ) + platformID, platEncID = int(platformID), int(platEncID) + format, length = struct.unpack(">HH", data[offset : offset + 4]) + if format in [8, 10, 12, 13]: + format, reserved, length = struct.unpack( + ">HHL", data[offset : offset + 8] + ) + elif format in [14]: + format, length = struct.unpack(">HL", data[offset : offset + 6]) + + if not length: + log.error( + "cmap subtable is reported as having zero length: platformID %s, " + "platEncID %s, format %s offset %s. Skipping table.", + platformID, + platEncID, + format, + offset, + ) + continue + table = CmapSubtable.newSubtable(format) + table.platformID = platformID + table.platEncID = platEncID + # Note that by default we decompile only the subtable header info; + # any other data gets decompiled only when an attribute of the + # subtable is referenced. + table.decompileHeader(data[offset : offset + int(length)], ttFont) + if offset in seenOffsets: + table.data = None # Mark as decompiled + table.cmap = tables[seenOffsets[offset]].cmap + else: + seenOffsets[offset] = i + tables.append(table) + if ttFont.lazy is False: # Be lazy for None and True + self.ensureDecompiled() + + def ensureDecompiled(self, recurse=False): + # The recurse argument is unused, but part of the signature of + # ensureDecompiled across the library. + for st in self.tables: + st.ensureDecompiled() + + def compile(self, ttFont): + self.tables.sort() # sort according to the spec; see CmapSubtable.__lt__() + numSubTables = len(self.tables) + totalOffset = 4 + 8 * numSubTables + data = struct.pack(">HH", self.tableVersion, numSubTables) + tableData = b"" + seen = ( + {} + ) # Some tables are the same object reference. Don't compile them twice. + done = ( + {} + ) # Some tables are different objects, but compile to the same data chunk + for table in self.tables: + offset = seen.get(id(table.cmap)) + if offset is None: + chunk = table.compile(ttFont) + offset = done.get(chunk) + if offset is None: + offset = seen[id(table.cmap)] = done[chunk] = totalOffset + len( + tableData + ) + tableData = tableData + chunk + data = data + struct.pack(">HHl", table.platformID, table.platEncID, offset) + return data + tableData + + def toXML(self, writer, ttFont): + writer.simpletag("tableVersion", version=self.tableVersion) + writer.newline() + for table in self.tables: + table.toXML(writer, ttFont) + + def fromXML(self, name, attrs, content, ttFont): + if name == "tableVersion": + self.tableVersion = safeEval(attrs["version"]) + return + if name[:12] != "cmap_format_": + return + if not hasattr(self, "tables"): + self.tables = [] + format = safeEval(name[12:]) + table = CmapSubtable.newSubtable(format) + table.platformID = safeEval(attrs["platformID"]) + table.platEncID = safeEval(attrs["platEncID"]) + table.fromXML(name, attrs, content, ttFont) + self.tables.append(table) + + +class CmapSubtable(object): + """Base class for all cmap subtable formats. + + Subclasses which handle the individual subtable formats are named + ``cmap_format_0``, ``cmap_format_2`` etc. Use :py:meth:`getSubtableClass` + to retrieve the concrete subclass, or :py:meth:`newSubtable` to get a + new subtable object for a given format. + + The object exposes a ``.cmap`` attribute, which contains a dictionary mapping + character codepoints to glyph names. + """ + + @staticmethod + def getSubtableClass(format): + """Return the subtable class for a format.""" + return cmap_classes.get(format, cmap_format_unknown) + + @staticmethod + def newSubtable(format): + """Return a new instance of a subtable for the given format + .""" + subtableClass = CmapSubtable.getSubtableClass(format) + return subtableClass(format) + + def __init__(self, format): + self.format = format + self.data = None + self.ttFont = None + self.platformID = None #: The platform ID of this subtable + self.platEncID = None #: The encoding ID of this subtable (interpretation depends on ``platformID``) + self.language = ( + None #: The language ID of this subtable (Macintosh platform only) + ) + + def ensureDecompiled(self, recurse=False): + # The recurse argument is unused, but part of the signature of + # ensureDecompiled across the library. + if self.data is None: + return + self.decompile(None, None) # use saved data. + self.data = None # Once this table has been decompiled, make sure we don't + # just return the original data. Also avoids recursion when + # called with an attribute that the cmap subtable doesn't have. + + def __getattr__(self, attr): + # allow lazy decompilation of subtables. + if attr[:2] == "__": # don't handle requests for member functions like '__lt__' + raise AttributeError(attr) + if self.data is None: + raise AttributeError(attr) + self.ensureDecompiled() + return getattr(self, attr) + + def decompileHeader(self, data, ttFont): + format, length, language = struct.unpack(">HHH", data[:6]) + assert ( + len(data) == length + ), "corrupt cmap table format %d (data length: %d, header length: %d)" % ( + format, + len(data), + length, + ) + self.format = int(format) + self.length = int(length) + self.language = int(language) + self.data = data[6:] + self.ttFont = ttFont + + def toXML(self, writer, ttFont): + writer.begintag( + self.__class__.__name__, + [ + ("platformID", self.platformID), + ("platEncID", self.platEncID), + ("language", self.language), + ], + ) + writer.newline() + codes = sorted(self.cmap.items()) + self._writeCodes(codes, writer) + writer.endtag(self.__class__.__name__) + writer.newline() + + def getEncoding(self, default=None): + """Returns the Python encoding name for this cmap subtable based on its platformID, + platEncID, and language. If encoding for these values is not known, by default + ``None`` is returned. That can be overridden by passing a value to the ``default`` + argument. + + Note that if you want to choose a "preferred" cmap subtable, most of the time + ``self.isUnicode()`` is what you want as that one only returns true for the modern, + commonly used, Unicode-compatible triplets, not the legacy ones. + """ + return getEncoding(self.platformID, self.platEncID, self.language, default) + + def isUnicode(self): + """Returns true if the characters are interpreted as Unicode codepoints.""" + return self.platformID == 0 or ( + self.platformID == 3 and self.platEncID in [0, 1, 10] + ) + + def isSymbol(self): + """Returns true if the subtable is for the Symbol encoding (3,0)""" + return self.platformID == 3 and self.platEncID == 0 + + def _writeCodes(self, codes, writer): + isUnicode = self.isUnicode() + for code, name in codes: + writer.simpletag("map", code=hex(code), name=name) + if isUnicode: + writer.comment(Unicode[code]) + writer.newline() + + def __lt__(self, other): + if not isinstance(other, CmapSubtable): + return NotImplemented + + # implemented so that list.sort() sorts according to the spec. + selfTuple = ( + getattr(self, "platformID", None), + getattr(self, "platEncID", None), + getattr(self, "language", None), + self.__dict__, + ) + otherTuple = ( + getattr(other, "platformID", None), + getattr(other, "platEncID", None), + getattr(other, "language", None), + other.__dict__, + ) + return selfTuple < otherTuple + + +class cmap_format_0(CmapSubtable): + def decompile(self, data, ttFont): + # we usually get here indirectly from the subtable __getattr__ function, in which case both args must be None. + # If not, someone is calling the subtable decompile() directly, and must provide both args. + if data is not None and ttFont is not None: + self.decompileHeader(data, ttFont) + else: + assert ( + data is None and ttFont is None + ), "Need both data and ttFont arguments" + data = ( + self.data + ) # decompileHeader assigns the data after the header to self.data + assert 262 == self.length, "Format 0 cmap subtable not 262 bytes" + gids = array.array("B") + gids.frombytes(self.data) + charCodes = range(len(gids)) + self.cmap = _make_map(self.ttFont, charCodes, gids) + + def compile(self, ttFont): + if self.data: + return struct.pack(">HHH", 0, 262, self.language) + self.data + + cmap = self.cmap + assert set(cmap.keys()).issubset(range(256)) + getGlyphID = ttFont.getGlyphID + valueList = [getGlyphID(cmap[i]) if i in cmap else 0 for i in range(256)] + + gids = array.array("B", valueList) + data = struct.pack(">HHH", 0, 262, self.language) + gids.tobytes() + assert len(data) == 262 + return data + + def fromXML(self, name, attrs, content, ttFont): + self.language = safeEval(attrs["language"]) + if not hasattr(self, "cmap"): + self.cmap = {} + cmap = self.cmap + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name != "map": + continue + cmap[safeEval(attrs["code"])] = attrs["name"] + + +subHeaderFormat = ">HHhH" + + +class SubHeader(object): + def __init__(self): + self.firstCode = None + self.entryCount = None + self.idDelta = None + self.idRangeOffset = None + self.glyphIndexArray = [] + + +class cmap_format_2(CmapSubtable): + def setIDDelta(self, subHeader): + subHeader.idDelta = 0 + # find the minGI which is not zero. + minGI = subHeader.glyphIndexArray[0] + for gid in subHeader.glyphIndexArray: + if (gid != 0) and (gid < minGI): + minGI = gid + # The lowest gid in glyphIndexArray, after subtracting idDelta, must be 1. + # idDelta is a short, and must be between -32K and 32K. minGI can be between 1 and 64K. + # We would like to pick an idDelta such that the first glyphArray GID is 1, + # so that we are more likely to be able to combine glypharray GID subranges. + # This means that we have a problem when minGI is > 32K + # Since the final gi is reconstructed from the glyphArray GID by: + # (short)finalGID = (gid + idDelta) % 0x10000), + # we can get from a glypharray GID of 1 to a final GID of 65K by subtracting 2, and casting the + # negative number to an unsigned short. + + if minGI > 1: + if minGI > 0x7FFF: + subHeader.idDelta = -(0x10000 - minGI) - 1 + else: + subHeader.idDelta = minGI - 1 + idDelta = subHeader.idDelta + for i in range(subHeader.entryCount): + gid = subHeader.glyphIndexArray[i] + if gid > 0: + subHeader.glyphIndexArray[i] = gid - idDelta + + def decompile(self, data, ttFont): + # we usually get here indirectly from the subtable __getattr__ function, in which case both args must be None. + # If not, someone is calling the subtable decompile() directly, and must provide both args. + if data is not None and ttFont is not None: + self.decompileHeader(data, ttFont) + else: + assert ( + data is None and ttFont is None + ), "Need both data and ttFont arguments" + + data = ( + self.data + ) # decompileHeader assigns the data after the header to self.data + subHeaderKeys = [] + maxSubHeaderindex = 0 + # get the key array, and determine the number of subHeaders. + allKeys = array.array("H") + allKeys.frombytes(data[:512]) + data = data[512:] + if sys.byteorder != "big": + allKeys.byteswap() + subHeaderKeys = [key // 8 for key in allKeys] + maxSubHeaderindex = max(subHeaderKeys) + + # Load subHeaders + subHeaderList = [] + pos = 0 + for i in range(maxSubHeaderindex + 1): + subHeader = SubHeader() + ( + subHeader.firstCode, + subHeader.entryCount, + subHeader.idDelta, + subHeader.idRangeOffset, + ) = struct.unpack(subHeaderFormat, data[pos : pos + 8]) + pos += 8 + giDataPos = pos + subHeader.idRangeOffset - 2 + giList = array.array("H") + giList.frombytes(data[giDataPos : giDataPos + subHeader.entryCount * 2]) + if sys.byteorder != "big": + giList.byteswap() + subHeader.glyphIndexArray = giList + subHeaderList.append(subHeader) + # How this gets processed. + # Charcodes may be one or two bytes. + # The first byte of a charcode is mapped through the subHeaderKeys, to select + # a subHeader. For any subheader but 0, the next byte is then mapped through the + # selected subheader. If subheader Index 0 is selected, then the byte itself is + # mapped through the subheader, and there is no second byte. + # Then assume that the subsequent byte is the first byte of the next charcode,and repeat. + # + # Each subheader references a range in the glyphIndexArray whose length is entryCount. + # The range in glyphIndexArray referenced by a sunheader may overlap with the range in glyphIndexArray + # referenced by another subheader. + # The only subheader that will be referenced by more than one first-byte value is the subheader + # that maps the entire range of glyphID values to glyphIndex 0, e.g notdef: + # {firstChar 0, EntryCount 0,idDelta 0,idRangeOffset xx} + # A byte being mapped though a subheader is treated as in index into a mapping of array index to font glyphIndex. + # A subheader specifies a subrange within (0...256) by the + # firstChar and EntryCount values. If the byte value is outside the subrange, then the glyphIndex is zero + # (e.g. glyph not in font). + # If the byte index is in the subrange, then an offset index is calculated as (byteIndex - firstChar). + # The index to glyphIndex mapping is a subrange of the glyphIndexArray. You find the start of the subrange by + # counting idRangeOffset bytes from the idRangeOffset word. The first value in this subrange is the + # glyphIndex for the index firstChar. The offset index should then be used in this array to get the glyphIndex. + # Example for Logocut-Medium + # first byte of charcode = 129; selects subheader 1. + # subheader 1 = {firstChar 64, EntryCount 108,idDelta 42,idRangeOffset 0252} + # second byte of charCode = 66 + # the index offset = 66-64 = 2. + # The subrange of the glyphIndexArray starting at 0x0252 bytes from the idRangeOffset word is: + # [glyphIndexArray index], [subrange array index] = glyphIndex + # [256], [0]=1 from charcode [129, 64] + # [257], [1]=2 from charcode [129, 65] + # [258], [2]=3 from charcode [129, 66] + # [259], [3]=4 from charcode [129, 67] + # So, the glyphIndex = 3 from the array. Then if idDelta is not zero and the glyph ID is not zero, + # add it to the glyphID to get the final glyphIndex + # value. In this case the final glyph index = 3+ 42 -> 45 for the final glyphIndex. Whew! + + self.data = b"" + cmap = {} + notdefGI = 0 + for firstByte in range(256): + subHeadindex = subHeaderKeys[firstByte] + subHeader = subHeaderList[subHeadindex] + if subHeadindex == 0: + if (firstByte < subHeader.firstCode) or ( + firstByte >= subHeader.firstCode + subHeader.entryCount + ): + continue # gi is notdef. + else: + charCode = firstByte + offsetIndex = firstByte - subHeader.firstCode + gi = subHeader.glyphIndexArray[offsetIndex] + if gi != 0: + gi = (gi + subHeader.idDelta) % 0x10000 + else: + continue # gi is notdef. + cmap[charCode] = gi + else: + if subHeader.entryCount: + charCodeOffset = firstByte * 256 + subHeader.firstCode + for offsetIndex in range(subHeader.entryCount): + charCode = charCodeOffset + offsetIndex + gi = subHeader.glyphIndexArray[offsetIndex] + if gi != 0: + gi = (gi + subHeader.idDelta) % 0x10000 + else: + continue + cmap[charCode] = gi + # If not subHeader.entryCount, then all char codes with this first byte are + # mapped to .notdef. We can skip this subtable, and leave the glyphs un-encoded, which is the + # same as mapping it to .notdef. + + gids = list(cmap.values()) + charCodes = list(cmap.keys()) + self.cmap = _make_map(self.ttFont, charCodes, gids) + + def compile(self, ttFont): + if self.data: + return ( + struct.pack(">HHH", self.format, self.length, self.language) + self.data + ) + kEmptyTwoCharCodeRange = -1 + notdefGI = 0 + + items = sorted(self.cmap.items()) + charCodes = [item[0] for item in items] + names = [item[1] for item in items] + nameMap = ttFont.getReverseGlyphMap() + try: + gids = [nameMap[name] for name in names] + except KeyError: + nameMap = ttFont.getReverseGlyphMap(rebuild=True) + try: + gids = [nameMap[name] for name in names] + except KeyError: + # allow virtual GIDs in format 2 tables + gids = [] + for name in names: + try: + gid = nameMap[name] + except KeyError: + try: + if name[:3] == "gid": + gid = int(name[3:]) + else: + gid = ttFont.getGlyphID(name) + except: + raise KeyError(name) + + gids.append(gid) + + # Process the (char code to gid) item list in char code order. + # By definition, all one byte char codes map to subheader 0. + # For all the two byte char codes, we assume that the first byte maps maps to the empty subhead (with an entry count of 0, + # which defines all char codes in its range to map to notdef) unless proven otherwise. + # Note that since the char code items are processed in char code order, all the char codes with the + # same first byte are in sequential order. + + subHeaderKeys = [ + kEmptyTwoCharCodeRange for x in range(256) + ] # list of indices into subHeaderList. + subHeaderList = [] + + # We force this subheader entry 0 to exist in the subHeaderList in the case where some one comes up + # with a cmap where all the one byte char codes map to notdef, + # with the result that the subhead 0 would not get created just by processing the item list. + charCode = charCodes[0] + if charCode > 255: + subHeader = SubHeader() + subHeader.firstCode = 0 + subHeader.entryCount = 0 + subHeader.idDelta = 0 + subHeader.idRangeOffset = 0 + subHeaderList.append(subHeader) + + lastFirstByte = -1 + items = zip(charCodes, gids) + for charCode, gid in items: + if gid == 0: + continue + firstbyte = charCode >> 8 + secondByte = charCode & 0x00FF + + if ( + firstbyte != lastFirstByte + ): # Need to update the current subhead, and start a new one. + if lastFirstByte > -1: + # fix GI's and iDelta of current subheader. + self.setIDDelta(subHeader) + + # If it was sunheader 0 for one-byte charCodes, then we need to set the subHeaderKeys value to zero + # for the indices matching the char codes. + if lastFirstByte == 0: + for index in range(subHeader.entryCount): + charCode = subHeader.firstCode + index + subHeaderKeys[charCode] = 0 + + assert subHeader.entryCount == len( + subHeader.glyphIndexArray + ), "Error - subhead entry count does not match len of glyphID subrange." + # init new subheader + subHeader = SubHeader() + subHeader.firstCode = secondByte + subHeader.entryCount = 1 + subHeader.glyphIndexArray.append(gid) + subHeaderList.append(subHeader) + subHeaderKeys[firstbyte] = len(subHeaderList) - 1 + lastFirstByte = firstbyte + else: + # need to fill in with notdefs all the code points between the last charCode and the current charCode. + codeDiff = secondByte - (subHeader.firstCode + subHeader.entryCount) + for i in range(codeDiff): + subHeader.glyphIndexArray.append(notdefGI) + subHeader.glyphIndexArray.append(gid) + subHeader.entryCount = subHeader.entryCount + codeDiff + 1 + + # fix GI's and iDelta of last subheader that we we added to the subheader array. + self.setIDDelta(subHeader) + + # Now we add a final subheader for the subHeaderKeys which maps to empty two byte charcode ranges. + subHeader = SubHeader() + subHeader.firstCode = 0 + subHeader.entryCount = 0 + subHeader.idDelta = 0 + subHeader.idRangeOffset = 2 + subHeaderList.append(subHeader) + emptySubheadIndex = len(subHeaderList) - 1 + for index in range(256): + if subHeaderKeys[index] == kEmptyTwoCharCodeRange: + subHeaderKeys[index] = emptySubheadIndex + # Since this is the last subheader, the GlyphIndex Array starts two bytes after the start of the + # idRangeOffset word of this subHeader. We can safely point to the first entry in the GlyphIndexArray, + # since the first subrange of the GlyphIndexArray is for subHeader 0, which always starts with + # charcode 0 and GID 0. + + idRangeOffset = ( + len(subHeaderList) - 1 + ) * 8 + 2 # offset to beginning of glyphIDArray from first subheader idRangeOffset. + subheadRangeLen = ( + len(subHeaderList) - 1 + ) # skip last special empty-set subheader; we've already hardocodes its idRangeOffset to 2. + for index in range(subheadRangeLen): + subHeader = subHeaderList[index] + subHeader.idRangeOffset = 0 + for j in range(index): + prevSubhead = subHeaderList[j] + if ( + prevSubhead.glyphIndexArray == subHeader.glyphIndexArray + ): # use the glyphIndexArray subarray + subHeader.idRangeOffset = ( + prevSubhead.idRangeOffset - (index - j) * 8 + ) + subHeader.glyphIndexArray = [] + break + if subHeader.idRangeOffset == 0: # didn't find one. + subHeader.idRangeOffset = idRangeOffset + idRangeOffset = ( + idRangeOffset - 8 + ) + subHeader.entryCount * 2 # one less subheader, one more subArray. + else: + idRangeOffset = idRangeOffset - 8 # one less subheader + + # Now we can write out the data! + length = ( + 6 + 512 + 8 * len(subHeaderList) + ) # header, 256 subHeaderKeys, and subheader array. + for subhead in subHeaderList[:-1]: + length = ( + length + len(subhead.glyphIndexArray) * 2 + ) # We can't use subhead.entryCount, as some of the subhead may share subArrays. + dataList = [struct.pack(">HHH", 2, length, self.language)] + for index in subHeaderKeys: + dataList.append(struct.pack(">H", index * 8)) + for subhead in subHeaderList: + dataList.append( + struct.pack( + subHeaderFormat, + subhead.firstCode, + subhead.entryCount, + subhead.idDelta, + subhead.idRangeOffset, + ) + ) + for subhead in subHeaderList[:-1]: + for gi in subhead.glyphIndexArray: + dataList.append(struct.pack(">H", gi)) + data = bytesjoin(dataList) + assert len(data) == length, ( + "Error: cmap format 2 is not same length as calculated! actual: " + + str(len(data)) + + " calc : " + + str(length) + ) + return data + + def fromXML(self, name, attrs, content, ttFont): + self.language = safeEval(attrs["language"]) + if not hasattr(self, "cmap"): + self.cmap = {} + cmap = self.cmap + + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name != "map": + continue + cmap[safeEval(attrs["code"])] = attrs["name"] + + +cmap_format_4_format = ">7H" + +# uint16 endCode[segCount] # Ending character code for each segment, last = 0xFFFF. +# uint16 reservedPad # This value should be zero +# uint16 startCode[segCount] # Starting character code for each segment +# uint16 idDelta[segCount] # Delta for all character codes in segment +# uint16 idRangeOffset[segCount] # Offset in bytes to glyph indexArray, or 0 +# uint16 glyphIndexArray[variable] # Glyph index array + + +def splitRange(startCode, endCode, cmap): + # Try to split a range of character codes into subranges with consecutive + # glyph IDs in such a way that the cmap4 subtable can be stored "most" + # efficiently. I can't prove I've got the optimal solution, but it seems + # to do well with the fonts I tested: none became bigger, many became smaller. + if startCode == endCode: + return [], [endCode] + + lastID = cmap[startCode] + lastCode = startCode + inOrder = None + orderedBegin = None + subRanges = [] + + # Gather subranges in which the glyph IDs are consecutive. + for code in range(startCode + 1, endCode + 1): + glyphID = cmap[code] + + if glyphID - 1 == lastID: + if inOrder is None or not inOrder: + inOrder = 1 + orderedBegin = lastCode + else: + if inOrder: + inOrder = 0 + subRanges.append((orderedBegin, lastCode)) + orderedBegin = None + + lastID = glyphID + lastCode = code + + if inOrder: + subRanges.append((orderedBegin, lastCode)) + assert lastCode == endCode + + # Now filter out those new subranges that would only make the data bigger. + # A new segment cost 8 bytes, not using a new segment costs 2 bytes per + # character. + newRanges = [] + for b, e in subRanges: + if b == startCode and e == endCode: + break # the whole range, we're fine + if b == startCode or e == endCode: + threshold = 4 # split costs one more segment + else: + threshold = 8 # split costs two more segments + if (e - b + 1) > threshold: + newRanges.append((b, e)) + subRanges = newRanges + + if not subRanges: + return [], [endCode] + + if subRanges[0][0] != startCode: + subRanges.insert(0, (startCode, subRanges[0][0] - 1)) + if subRanges[-1][1] != endCode: + subRanges.append((subRanges[-1][1] + 1, endCode)) + + # Fill the "holes" in the segments list -- those are the segments in which + # the glyph IDs are _not_ consecutive. + i = 1 + while i < len(subRanges): + if subRanges[i - 1][1] + 1 != subRanges[i][0]: + subRanges.insert(i, (subRanges[i - 1][1] + 1, subRanges[i][0] - 1)) + i = i + 1 + i = i + 1 + + # Transform the ranges into startCode/endCode lists. + start = [] + end = [] + for b, e in subRanges: + start.append(b) + end.append(e) + start.pop(0) + + assert len(start) + 1 == len(end) + return start, end + + +class cmap_format_4(CmapSubtable): + def decompile(self, data, ttFont): + # we usually get here indirectly from the subtable __getattr__ function, in which case both args must be None. + # If not, someone is calling the subtable decompile() directly, and must provide both args. + if data is not None and ttFont is not None: + self.decompileHeader(data, ttFont) + else: + assert ( + data is None and ttFont is None + ), "Need both data and ttFont arguments" + + data = ( + self.data + ) # decompileHeader assigns the data after the header to self.data + (segCountX2, searchRange, entrySelector, rangeShift) = struct.unpack( + ">4H", data[:8] + ) + data = data[8:] + segCount = segCountX2 // 2 + + allCodes = array.array("H") + allCodes.frombytes(data) + self.data = data = None + + if sys.byteorder != "big": + allCodes.byteswap() + + # divide the data + endCode = allCodes[:segCount] + allCodes = allCodes[segCount + 1 :] # the +1 is skipping the reservedPad field + startCode = allCodes[:segCount] + allCodes = allCodes[segCount:] + idDelta = allCodes[:segCount] + allCodes = allCodes[segCount:] + idRangeOffset = allCodes[:segCount] + glyphIndexArray = allCodes[segCount:] + lenGIArray = len(glyphIndexArray) + + # build 2-byte character mapping + charCodes = [] + gids = [] + for i in range(len(startCode) - 1): # don't do 0xffff! + start = startCode[i] + delta = idDelta[i] + rangeOffset = idRangeOffset[i] + partial = rangeOffset // 2 - start + i - len(idRangeOffset) + + rangeCharCodes = list(range(startCode[i], endCode[i] + 1)) + charCodes.extend(rangeCharCodes) + if rangeOffset == 0: + gids.extend( + [(charCode + delta) & 0xFFFF for charCode in rangeCharCodes] + ) + else: + for charCode in rangeCharCodes: + index = charCode + partial + assert index < lenGIArray, ( + "In format 4 cmap, range (%d), the calculated index (%d) into the glyph index array is not less than the length of the array (%d) !" + % (i, index, lenGIArray) + ) + if glyphIndexArray[index] != 0: # if not missing glyph + glyphID = glyphIndexArray[index] + delta + else: + glyphID = 0 # missing glyph + gids.append(glyphID & 0xFFFF) + + self.cmap = _make_map(self.ttFont, charCodes, gids) + + def compile(self, ttFont): + if self.data: + return ( + struct.pack(">HHH", self.format, self.length, self.language) + self.data + ) + + charCodes = list(self.cmap.keys()) + if not charCodes: + startCode = [0xFFFF] + endCode = [0xFFFF] + else: + charCodes.sort() + names = [self.cmap[code] for code in charCodes] + nameMap = ttFont.getReverseGlyphMap() + try: + gids = [nameMap[name] for name in names] + except KeyError: + nameMap = ttFont.getReverseGlyphMap(rebuild=True) + try: + gids = [nameMap[name] for name in names] + except KeyError: + # allow virtual GIDs in format 4 tables + gids = [] + for name in names: + try: + gid = nameMap[name] + except KeyError: + try: + if name[:3] == "gid": + gid = int(name[3:]) + else: + gid = ttFont.getGlyphID(name) + except: + raise KeyError(name) + + gids.append(gid) + cmap = {} # code:glyphID mapping + for code, gid in zip(charCodes, gids): + cmap[code] = gid + + # Build startCode and endCode lists. + # Split the char codes in ranges of consecutive char codes, then split + # each range in more ranges of consecutive/not consecutive glyph IDs. + # See splitRange(). + lastCode = charCodes[0] + endCode = [] + startCode = [lastCode] + for charCode in charCodes[ + 1: + ]: # skip the first code, it's the first start code + if charCode == lastCode + 1: + lastCode = charCode + continue + start, end = splitRange(startCode[-1], lastCode, cmap) + startCode.extend(start) + endCode.extend(end) + startCode.append(charCode) + lastCode = charCode + start, end = splitRange(startCode[-1], lastCode, cmap) + startCode.extend(start) + endCode.extend(end) + startCode.append(0xFFFF) + endCode.append(0xFFFF) + + # build up rest of cruft + idDelta = [] + idRangeOffset = [] + glyphIndexArray = [] + for i in range(len(endCode) - 1): # skip the closing codes (0xffff) + indices = [] + for charCode in range(startCode[i], endCode[i] + 1): + indices.append(cmap[charCode]) + if indices == list(range(indices[0], indices[0] + len(indices))): + idDelta.append((indices[0] - startCode[i]) % 0x10000) + idRangeOffset.append(0) + else: + idDelta.append(0) + idRangeOffset.append(2 * (len(endCode) + len(glyphIndexArray) - i)) + glyphIndexArray.extend(indices) + idDelta.append(1) # 0xffff + 1 == (tadaa!) 0. So this end code maps to .notdef + idRangeOffset.append(0) + + # Insane. + segCount = len(endCode) + segCountX2 = segCount * 2 + searchRange, entrySelector, rangeShift = getSearchRange(segCount, 2) + + charCodeArray = array.array("H", endCode + [0] + startCode) + idDeltaArray = array.array("H", idDelta) + restArray = array.array("H", idRangeOffset + glyphIndexArray) + if sys.byteorder != "big": + charCodeArray.byteswap() + if sys.byteorder != "big": + idDeltaArray.byteswap() + if sys.byteorder != "big": + restArray.byteswap() + data = charCodeArray.tobytes() + idDeltaArray.tobytes() + restArray.tobytes() + + length = struct.calcsize(cmap_format_4_format) + len(data) + header = struct.pack( + cmap_format_4_format, + self.format, + length, + self.language, + segCountX2, + searchRange, + entrySelector, + rangeShift, + ) + return header + data + + def fromXML(self, name, attrs, content, ttFont): + self.language = safeEval(attrs["language"]) + if not hasattr(self, "cmap"): + self.cmap = {} + cmap = self.cmap + + for element in content: + if not isinstance(element, tuple): + continue + nameMap, attrsMap, dummyContent = element + if nameMap != "map": + assert 0, "Unrecognized keyword in cmap subtable" + cmap[safeEval(attrsMap["code"])] = attrsMap["name"] + + +class cmap_format_6(CmapSubtable): + def decompile(self, data, ttFont): + # we usually get here indirectly from the subtable __getattr__ function, in which case both args must be None. + # If not, someone is calling the subtable decompile() directly, and must provide both args. + if data is not None and ttFont is not None: + self.decompileHeader(data, ttFont) + else: + assert ( + data is None and ttFont is None + ), "Need both data and ttFont arguments" + + data = ( + self.data + ) # decompileHeader assigns the data after the header to self.data + firstCode, entryCount = struct.unpack(">HH", data[:4]) + firstCode = int(firstCode) + data = data[4:] + # assert len(data) == 2 * entryCount # XXX not true in Apple's Helvetica!!! + gids = array.array("H") + gids.frombytes(data[: 2 * int(entryCount)]) + if sys.byteorder != "big": + gids.byteswap() + self.data = data = None + + charCodes = list(range(firstCode, firstCode + len(gids))) + self.cmap = _make_map(self.ttFont, charCodes, gids) + + def compile(self, ttFont): + if self.data: + return ( + struct.pack(">HHH", self.format, self.length, self.language) + self.data + ) + cmap = self.cmap + codes = sorted(cmap.keys()) + if codes: # yes, there are empty cmap tables. + codes = list(range(codes[0], codes[-1] + 1)) + firstCode = codes[0] + valueList = [ + ttFont.getGlyphID(cmap[code]) if code in cmap else 0 for code in codes + ] + gids = array.array("H", valueList) + if sys.byteorder != "big": + gids.byteswap() + data = gids.tobytes() + else: + data = b"" + firstCode = 0 + header = struct.pack( + ">HHHHH", 6, len(data) + 10, self.language, firstCode, len(codes) + ) + return header + data + + def fromXML(self, name, attrs, content, ttFont): + self.language = safeEval(attrs["language"]) + if not hasattr(self, "cmap"): + self.cmap = {} + cmap = self.cmap + + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name != "map": + continue + cmap[safeEval(attrs["code"])] = attrs["name"] + + +class cmap_format_12_or_13(CmapSubtable): + def __init__(self, format): + self.format = format + self.reserved = 0 + self.data = None + self.ttFont = None + + def decompileHeader(self, data, ttFont): + format, reserved, length, language, nGroups = struct.unpack(">HHLLL", data[:16]) + assert ( + len(data) == (16 + nGroups * 12) == (length) + ), "corrupt cmap table format %d (data length: %d, header length: %d)" % ( + self.format, + len(data), + length, + ) + self.format = format + self.reserved = reserved + self.length = length + self.language = language + self.nGroups = nGroups + self.data = data[16:] + self.ttFont = ttFont + + def decompile(self, data, ttFont): + # we usually get here indirectly from the subtable __getattr__ function, in which case both args must be None. + # If not, someone is calling the subtable decompile() directly, and must provide both args. + if data is not None and ttFont is not None: + self.decompileHeader(data, ttFont) + else: + assert ( + data is None and ttFont is None + ), "Need both data and ttFont arguments" + + data = ( + self.data + ) # decompileHeader assigns the data after the header to self.data + charCodes = [] + gids = [] + pos = 0 + groups = array.array("I", data[: self.nGroups * 12]) + if sys.byteorder != "big": + groups.byteswap() + for i in range(self.nGroups): + startCharCode = groups[i * 3] + endCharCode = groups[i * 3 + 1] + glyphID = groups[i * 3 + 2] + lenGroup = 1 + endCharCode - startCharCode + charCodes.extend(range(startCharCode, endCharCode + 1)) + gids.extend(self._computeGIDs(glyphID, lenGroup)) + self.data = data = None + self.cmap = _make_map(self.ttFont, charCodes, gids) + + def compile(self, ttFont): + if self.data: + return ( + struct.pack( + ">HHLLL", + self.format, + self.reserved, + self.length, + self.language, + self.nGroups, + ) + + self.data + ) + charCodes = list(self.cmap.keys()) + names = list(self.cmap.values()) + nameMap = ttFont.getReverseGlyphMap() + try: + gids = [nameMap[name] for name in names] + except KeyError: + nameMap = ttFont.getReverseGlyphMap(rebuild=True) + try: + gids = [nameMap[name] for name in names] + except KeyError: + # allow virtual GIDs in format 12 tables + gids = [] + for name in names: + try: + gid = nameMap[name] + except KeyError: + try: + if name[:3] == "gid": + gid = int(name[3:]) + else: + gid = ttFont.getGlyphID(name) + except: + raise KeyError(name) + + gids.append(gid) + + cmap = {} # code:glyphID mapping + for code, gid in zip(charCodes, gids): + cmap[code] = gid + + charCodes.sort() + index = 0 + startCharCode = charCodes[0] + startGlyphID = cmap[startCharCode] + lastGlyphID = startGlyphID - self._format_step + lastCharCode = startCharCode - 1 + nGroups = 0 + dataList = [] + maxIndex = len(charCodes) + for index in range(maxIndex): + charCode = charCodes[index] + glyphID = cmap[charCode] + if not self._IsInSameRun(glyphID, lastGlyphID, charCode, lastCharCode): + dataList.append( + struct.pack(">LLL", startCharCode, lastCharCode, startGlyphID) + ) + startCharCode = charCode + startGlyphID = glyphID + nGroups = nGroups + 1 + lastGlyphID = glyphID + lastCharCode = charCode + dataList.append(struct.pack(">LLL", startCharCode, lastCharCode, startGlyphID)) + nGroups = nGroups + 1 + data = bytesjoin(dataList) + lengthSubtable = len(data) + 16 + assert len(data) == (nGroups * 12) == (lengthSubtable - 16) + return ( + struct.pack( + ">HHLLL", + self.format, + self.reserved, + lengthSubtable, + self.language, + nGroups, + ) + + data + ) + + def toXML(self, writer, ttFont): + writer.begintag( + self.__class__.__name__, + [ + ("platformID", self.platformID), + ("platEncID", self.platEncID), + ("format", self.format), + ("reserved", self.reserved), + ("length", self.length), + ("language", self.language), + ("nGroups", self.nGroups), + ], + ) + writer.newline() + codes = sorted(self.cmap.items()) + self._writeCodes(codes, writer) + writer.endtag(self.__class__.__name__) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + self.format = safeEval(attrs["format"]) + self.reserved = safeEval(attrs["reserved"]) + self.length = safeEval(attrs["length"]) + self.language = safeEval(attrs["language"]) + self.nGroups = safeEval(attrs["nGroups"]) + if not hasattr(self, "cmap"): + self.cmap = {} + cmap = self.cmap + + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name != "map": + continue + cmap[safeEval(attrs["code"])] = attrs["name"] + + +class cmap_format_12(cmap_format_12_or_13): + _format_step = 1 + + def __init__(self, format=12): + cmap_format_12_or_13.__init__(self, format) + + def _computeGIDs(self, startingGlyph, numberOfGlyphs): + return range(startingGlyph, startingGlyph + numberOfGlyphs) + + def _IsInSameRun(self, glyphID, lastGlyphID, charCode, lastCharCode): + return (glyphID == 1 + lastGlyphID) and (charCode == 1 + lastCharCode) + + +class cmap_format_13(cmap_format_12_or_13): + _format_step = 0 + + def __init__(self, format=13): + cmap_format_12_or_13.__init__(self, format) + + def _computeGIDs(self, startingGlyph, numberOfGlyphs): + return [startingGlyph] * numberOfGlyphs + + def _IsInSameRun(self, glyphID, lastGlyphID, charCode, lastCharCode): + return (glyphID == lastGlyphID) and (charCode == 1 + lastCharCode) + + +def cvtToUVS(threeByteString): + data = b"\0" + threeByteString + (val,) = struct.unpack(">L", data) + return val + + +def cvtFromUVS(val): + assert 0 <= val < 0x1000000 + fourByteString = struct.pack(">L", val) + return fourByteString[1:] + + +class cmap_format_14(CmapSubtable): + def decompileHeader(self, data, ttFont): + format, length, numVarSelectorRecords = struct.unpack(">HLL", data[:10]) + self.data = data[10:] + self.length = length + self.numVarSelectorRecords = numVarSelectorRecords + self.ttFont = ttFont + self.language = 0xFF # has no language. + + def decompile(self, data, ttFont): + if data is not None and ttFont is not None: + self.decompileHeader(data, ttFont) + else: + assert ( + data is None and ttFont is None + ), "Need both data and ttFont arguments" + data = self.data + + self.cmap = ( + {} + ) # so that clients that expect this to exist in a cmap table won't fail. + uvsDict = {} + recOffset = 0 + for n in range(self.numVarSelectorRecords): + uvs, defOVSOffset, nonDefUVSOffset = struct.unpack( + ">3sLL", data[recOffset : recOffset + 11] + ) + recOffset += 11 + varUVS = cvtToUVS(uvs) + if defOVSOffset: + startOffset = defOVSOffset - 10 + (numValues,) = struct.unpack(">L", data[startOffset : startOffset + 4]) + startOffset += 4 + for r in range(numValues): + uv, addtlCnt = struct.unpack( + ">3sB", data[startOffset : startOffset + 4] + ) + startOffset += 4 + firstBaseUV = cvtToUVS(uv) + cnt = addtlCnt + 1 + baseUVList = list(range(firstBaseUV, firstBaseUV + cnt)) + glyphList = [None] * cnt + localUVList = zip(baseUVList, glyphList) + try: + uvsDict[varUVS].extend(localUVList) + except KeyError: + uvsDict[varUVS] = list(localUVList) + + if nonDefUVSOffset: + startOffset = nonDefUVSOffset - 10 + (numRecs,) = struct.unpack(">L", data[startOffset : startOffset + 4]) + startOffset += 4 + localUVList = [] + for r in range(numRecs): + uv, gid = struct.unpack(">3sH", data[startOffset : startOffset + 5]) + startOffset += 5 + uv = cvtToUVS(uv) + glyphName = self.ttFont.getGlyphName(gid) + localUVList.append((uv, glyphName)) + try: + uvsDict[varUVS].extend(localUVList) + except KeyError: + uvsDict[varUVS] = localUVList + + self.uvsDict = uvsDict + + def toXML(self, writer, ttFont): + writer.begintag( + self.__class__.__name__, + [ + ("platformID", self.platformID), + ("platEncID", self.platEncID), + ], + ) + writer.newline() + uvsDict = self.uvsDict + uvsList = sorted(uvsDict.keys()) + for uvs in uvsList: + uvList = uvsDict[uvs] + uvList.sort(key=lambda item: (item[1] is not None, item[0], item[1])) + for uv, gname in uvList: + attrs = [("uv", hex(uv)), ("uvs", hex(uvs))] + if gname is not None: + attrs.append(("name", gname)) + writer.simpletag("map", attrs) + writer.newline() + writer.endtag(self.__class__.__name__) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + self.language = 0xFF # provide a value so that CmapSubtable.__lt__() won't fail + if not hasattr(self, "cmap"): + self.cmap = ( + {} + ) # so that clients that expect this to exist in a cmap table won't fail. + if not hasattr(self, "uvsDict"): + self.uvsDict = {} + uvsDict = self.uvsDict + + # For backwards compatibility reasons we accept "None" as an indicator + # for "default mapping", unless the font actually has a glyph named + # "None". + _hasGlyphNamedNone = None + + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name != "map": + continue + uvs = safeEval(attrs["uvs"]) + uv = safeEval(attrs["uv"]) + gname = attrs.get("name") + if gname == "None": + if _hasGlyphNamedNone is None: + _hasGlyphNamedNone = "None" in ttFont.getGlyphOrder() + if not _hasGlyphNamedNone: + gname = None + try: + uvsDict[uvs].append((uv, gname)) + except KeyError: + uvsDict[uvs] = [(uv, gname)] + + def compile(self, ttFont): + if self.data: + return ( + struct.pack( + ">HLL", self.format, self.length, self.numVarSelectorRecords + ) + + self.data + ) + + uvsDict = self.uvsDict + uvsList = sorted(uvsDict.keys()) + self.numVarSelectorRecords = len(uvsList) + offset = ( + 10 + self.numVarSelectorRecords * 11 + ) # current value is end of VarSelectorRecords block. + data = [] + varSelectorRecords = [] + for uvs in uvsList: + entryList = uvsDict[uvs] + + defList = [entry for entry in entryList if entry[1] is None] + if defList: + defList = [entry[0] for entry in defList] + defOVSOffset = offset + defList.sort() + + lastUV = defList[0] + cnt = -1 + defRecs = [] + for defEntry in defList: + cnt += 1 + if (lastUV + cnt) != defEntry: + rec = struct.pack(">3sB", cvtFromUVS(lastUV), cnt - 1) + lastUV = defEntry + defRecs.append(rec) + cnt = 0 + + rec = struct.pack(">3sB", cvtFromUVS(lastUV), cnt) + defRecs.append(rec) + + numDefRecs = len(defRecs) + data.append(struct.pack(">L", numDefRecs)) + data.extend(defRecs) + offset += 4 + numDefRecs * 4 + else: + defOVSOffset = 0 + + ndefList = [entry for entry in entryList if entry[1] is not None] + if ndefList: + nonDefUVSOffset = offset + ndefList.sort() + numNonDefRecs = len(ndefList) + data.append(struct.pack(">L", numNonDefRecs)) + offset += 4 + numNonDefRecs * 5 + + for uv, gname in ndefList: + gid = ttFont.getGlyphID(gname) + ndrec = struct.pack(">3sH", cvtFromUVS(uv), gid) + data.append(ndrec) + else: + nonDefUVSOffset = 0 + + vrec = struct.pack(">3sLL", cvtFromUVS(uvs), defOVSOffset, nonDefUVSOffset) + varSelectorRecords.append(vrec) + + data = bytesjoin(varSelectorRecords) + bytesjoin(data) + self.length = 10 + len(data) + headerdata = struct.pack( + ">HLL", self.format, self.length, self.numVarSelectorRecords + ) + + return headerdata + data + + +class cmap_format_unknown(CmapSubtable): + def toXML(self, writer, ttFont): + cmapName = self.__class__.__name__[:12] + str(self.format) + writer.begintag( + cmapName, + [ + ("platformID", self.platformID), + ("platEncID", self.platEncID), + ], + ) + writer.newline() + writer.dumphex(self.data) + writer.endtag(cmapName) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + self.data = readHex(content) + self.cmap = {} + + def decompileHeader(self, data, ttFont): + self.language = 0 # dummy value + self.data = data + + def decompile(self, data, ttFont): + # we usually get here indirectly from the subtable __getattr__ function, in which case both args must be None. + # If not, someone is calling the subtable decompile() directly, and must provide both args. + if data is not None and ttFont is not None: + self.decompileHeader(data, ttFont) + else: + assert ( + data is None and ttFont is None + ), "Need both data and ttFont arguments" + + def compile(self, ttFont): + if self.data: + return self.data + else: + return None + + +cmap_classes = { + 0: cmap_format_0, + 2: cmap_format_2, + 4: cmap_format_4, + 6: cmap_format_6, + 12: cmap_format_12, + 13: cmap_format_13, + 14: cmap_format_14, +} diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_c_v_a_r.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_c_v_a_r.py new file mode 100644 index 0000000000000000000000000000000000000000..872710c8f0c93ade86e8be8640205a91b7b397af --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_c_v_a_r.py @@ -0,0 +1,94 @@ +from . import DefaultTable +from fontTools.misc import sstruct +from fontTools.misc.textTools import bytesjoin +from fontTools.ttLib.tables.TupleVariation import ( + compileTupleVariationStore, + decompileTupleVariationStore, + TupleVariation, +) + + +# https://www.microsoft.com/typography/otspec/cvar.htm +# https://www.microsoft.com/typography/otspec/otvarcommonformats.htm +# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cvar.html + +CVAR_HEADER_FORMAT = """ + > # big endian + majorVersion: H + minorVersion: H + tupleVariationCount: H + offsetToData: H +""" + +CVAR_HEADER_SIZE = sstruct.calcsize(CVAR_HEADER_FORMAT) + + +class table__c_v_a_r(DefaultTable.DefaultTable): + """Control Value Table (CVT) variations table + + The ``cvar`` table contains variations for the values in a ``cvt`` + table. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/cvar + """ + + dependencies = ["cvt ", "fvar"] + + def __init__(self, tag=None): + DefaultTable.DefaultTable.__init__(self, tag) + self.majorVersion, self.minorVersion = 1, 0 + self.variations = [] + + def compile(self, ttFont, useSharedPoints=False): + tupleVariationCount, tuples, data = compileTupleVariationStore( + variations=[v for v in self.variations if v.hasImpact()], + pointCount=len(ttFont["cvt "].values), + axisTags=[axis.axisTag for axis in ttFont["fvar"].axes], + sharedTupleIndices={}, + useSharedPoints=useSharedPoints, + ) + header = { + "majorVersion": self.majorVersion, + "minorVersion": self.minorVersion, + "tupleVariationCount": tupleVariationCount, + "offsetToData": CVAR_HEADER_SIZE + len(tuples), + } + return b"".join([sstruct.pack(CVAR_HEADER_FORMAT, header), tuples, data]) + + def decompile(self, data, ttFont): + axisTags = [axis.axisTag for axis in ttFont["fvar"].axes] + header = {} + sstruct.unpack(CVAR_HEADER_FORMAT, data[0:CVAR_HEADER_SIZE], header) + self.majorVersion = header["majorVersion"] + self.minorVersion = header["minorVersion"] + assert self.majorVersion == 1, self.majorVersion + self.variations = decompileTupleVariationStore( + tableTag=self.tableTag, + axisTags=axisTags, + tupleVariationCount=header["tupleVariationCount"], + pointCount=len(ttFont["cvt "].values), + sharedTuples=None, + data=data, + pos=CVAR_HEADER_SIZE, + dataPos=header["offsetToData"], + ) + + def fromXML(self, name, attrs, content, ttFont): + if name == "version": + self.majorVersion = int(attrs.get("major", "1")) + self.minorVersion = int(attrs.get("minor", "0")) + elif name == "tuple": + valueCount = len(ttFont["cvt "].values) + var = TupleVariation({}, [None] * valueCount) + self.variations.append(var) + for tupleElement in content: + if isinstance(tupleElement, tuple): + tupleName, tupleAttrs, tupleContent = tupleElement + var.fromXML(tupleName, tupleAttrs, tupleContent) + + def toXML(self, writer, ttFont): + axisTags = [axis.axisTag for axis in ttFont["fvar"].axes] + writer.simpletag("version", major=self.majorVersion, minor=self.minorVersion) + writer.newline() + for var in self.variations: + var.toXML(writer, axisTags) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_c_v_t.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_c_v_t.py new file mode 100644 index 0000000000000000000000000000000000000000..c89fe2c239a0ab72fe763a1c0f700540d6b4126e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_c_v_t.py @@ -0,0 +1,56 @@ +from fontTools.misc.textTools import safeEval +from . import DefaultTable +import sys +import array + + +class table__c_v_t(DefaultTable.DefaultTable): + """Control Value Table + + The Control Value Table holds a list of values that can be referenced + by TrueType font instructions. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/cvt + """ + + def decompile(self, data, ttFont): + values = array.array("h") + values.frombytes(data) + if sys.byteorder != "big": + values.byteswap() + self.values = values + + def compile(self, ttFont): + if not hasattr(self, "values"): + return b"" + values = self.values[:] + if sys.byteorder != "big": + values.byteswap() + return values.tobytes() + + def toXML(self, writer, ttFont): + for i, value in enumerate(self.values): + writer.simpletag("cv", value=value, index=i) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if not hasattr(self, "values"): + self.values = array.array("h") + if name == "cv": + index = safeEval(attrs["index"]) + value = safeEval(attrs["value"]) + for i in range(1 + index - len(self.values)): + self.values.append(0) + self.values[index] = value + + def __len__(self): + return len(self.values) + + def __getitem__(self, index): + return self.values[index] + + def __setitem__(self, index, value): + self.values[index] = value + + def __delitem__(self, index): + del self.values[index] diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_f_e_a_t.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_f_e_a_t.py new file mode 100644 index 0000000000000000000000000000000000000000..8e279db0059613d5c0e0ac061dc9b2b62aefe73b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_f_e_a_t.py @@ -0,0 +1,15 @@ +from .otBase import BaseTTXConverter + + +class table__f_e_a_t(BaseTTXConverter): + """Feature name table + + The feature name table is an AAT (Apple Advanced Typography) table for + storing font features, settings, and their human-readable names. It should + not be confused with the ``Feat`` table or the OpenType Layout ``GSUB``/``GPOS`` + tables. + + See also https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6feat.html + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_f_p_g_m.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_f_p_g_m.py new file mode 100644 index 0000000000000000000000000000000000000000..c21a9d4b6817d33bc68aabb8d866708657d1e068 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_f_p_g_m.py @@ -0,0 +1,62 @@ +from . import DefaultTable +from . import ttProgram + + +class table__f_p_g_m(DefaultTable.DefaultTable): + """Font Program table + + The ``fpgm`` table typically contains function defintions that are + used by font instructions. This Font Program is similar to the Control + Value Program that is stored in the ``prep`` table, but + the ``fpgm`` table is only executed one time, when the font is first + used. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/fpgm + """ + + def decompile(self, data, ttFont): + program = ttProgram.Program() + program.fromBytecode(data) + self.program = program + + def compile(self, ttFont): + if hasattr(self, "program"): + return self.program.getBytecode() + return b"" + + def toXML(self, writer, ttFont): + self.program.toXML(writer, ttFont) + + def fromXML(self, name, attrs, content, ttFont): + program = ttProgram.Program() + program.fromXML(name, attrs, content, ttFont) + self.program = program + + def __bool__(self): + """ + >>> fpgm = table__f_p_g_m() + >>> bool(fpgm) + False + >>> p = ttProgram.Program() + >>> fpgm.program = p + >>> bool(fpgm) + False + >>> bc = bytearray([0]) + >>> p.fromBytecode(bc) + >>> bool(fpgm) + True + >>> p.bytecode.pop() + 0 + >>> bool(fpgm) + False + """ + return hasattr(self, "program") and bool(self.program) + + __nonzero__ = __bool__ + + +if __name__ == "__main__": + import sys + import doctest + + sys.exit(doctest.testmod().failed) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_f_v_a_r.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_f_v_a_r.py new file mode 100644 index 0000000000000000000000000000000000000000..f2536cb288a9140f59b298246daa2aea9b6d356f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_f_v_a_r.py @@ -0,0 +1,261 @@ +from fontTools.misc import sstruct +from fontTools.misc.fixedTools import ( + fixedToFloat as fi2fl, + floatToFixed as fl2fi, + floatToFixedToStr as fl2str, + strToFixedToFloat as str2fl, +) +from fontTools.misc.textTools import Tag, bytesjoin, safeEval +from fontTools.ttLib import TTLibError +from . import DefaultTable +import struct + + +# Apple's documentation of 'fvar': +# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6fvar.html + +FVAR_HEADER_FORMAT = """ + > # big endian + version: L + offsetToData: H + countSizePairs: H + axisCount: H + axisSize: H + instanceCount: H + instanceSize: H +""" + +FVAR_AXIS_FORMAT = """ + > # big endian + axisTag: 4s + minValue: 16.16F + defaultValue: 16.16F + maxValue: 16.16F + flags: H + axisNameID: H +""" + +FVAR_INSTANCE_FORMAT = """ + > # big endian + subfamilyNameID: H + flags: H +""" + + +class table__f_v_a_r(DefaultTable.DefaultTable): + """FonT Variations table + + The ``fvar`` table contains records of the variation axes and of the + named instances in a variable font. + + See also https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6fvar.html + """ + + dependencies = ["name"] + + def __init__(self, tag=None): + DefaultTable.DefaultTable.__init__(self, tag) + self.axes = [] + self.instances = [] + + def compile(self, ttFont): + instanceSize = sstruct.calcsize(FVAR_INSTANCE_FORMAT) + (len(self.axes) * 4) + includePostScriptNames = any( + instance.postscriptNameID != 0xFFFF for instance in self.instances + ) + if includePostScriptNames: + instanceSize += 2 + header = { + "version": 0x00010000, + "offsetToData": sstruct.calcsize(FVAR_HEADER_FORMAT), + "countSizePairs": 2, + "axisCount": len(self.axes), + "axisSize": sstruct.calcsize(FVAR_AXIS_FORMAT), + "instanceCount": len(self.instances), + "instanceSize": instanceSize, + } + result = [sstruct.pack(FVAR_HEADER_FORMAT, header)] + result.extend([axis.compile() for axis in self.axes]) + axisTags = [axis.axisTag for axis in self.axes] + for instance in self.instances: + result.append(instance.compile(axisTags, includePostScriptNames)) + return bytesjoin(result) + + def decompile(self, data, ttFont): + header = {} + headerSize = sstruct.calcsize(FVAR_HEADER_FORMAT) + header = sstruct.unpack(FVAR_HEADER_FORMAT, data[0:headerSize]) + if header["version"] != 0x00010000: + raise TTLibError("unsupported 'fvar' version %04x" % header["version"]) + pos = header["offsetToData"] + axisSize = header["axisSize"] + for _ in range(header["axisCount"]): + axis = Axis() + axis.decompile(data[pos : pos + axisSize]) + self.axes.append(axis) + pos += axisSize + instanceSize = header["instanceSize"] + axisTags = [axis.axisTag for axis in self.axes] + for _ in range(header["instanceCount"]): + instance = NamedInstance() + instance.decompile(data[pos : pos + instanceSize], axisTags) + self.instances.append(instance) + pos += instanceSize + + def toXML(self, writer, ttFont): + for axis in self.axes: + axis.toXML(writer, ttFont) + for instance in self.instances: + instance.toXML(writer, ttFont) + + def fromXML(self, name, attrs, content, ttFont): + if name == "Axis": + axis = Axis() + axis.fromXML(name, attrs, content, ttFont) + self.axes.append(axis) + elif name == "NamedInstance": + instance = NamedInstance() + instance.fromXML(name, attrs, content, ttFont) + self.instances.append(instance) + + def getAxes(self): + return {a.axisTag: (a.minValue, a.defaultValue, a.maxValue) for a in self.axes} + + +class Axis(object): + def __init__(self): + self.axisTag = None + self.axisNameID = 0 + self.flags = 0 + self.minValue = -1.0 + self.defaultValue = 0.0 + self.maxValue = 1.0 + + def compile(self): + return sstruct.pack(FVAR_AXIS_FORMAT, self) + + def decompile(self, data): + sstruct.unpack2(FVAR_AXIS_FORMAT, data, self) + + def toXML(self, writer, ttFont): + name = ( + ttFont["name"].getDebugName(self.axisNameID) if "name" in ttFont else None + ) + if name is not None: + writer.newline() + writer.comment(name) + writer.newline() + writer.begintag("Axis") + writer.newline() + for tag, value in [ + ("AxisTag", self.axisTag), + ("Flags", "0x%X" % self.flags), + ("MinValue", fl2str(self.minValue, 16)), + ("DefaultValue", fl2str(self.defaultValue, 16)), + ("MaxValue", fl2str(self.maxValue, 16)), + ("AxisNameID", str(self.axisNameID)), + ]: + writer.begintag(tag) + writer.write(value) + writer.endtag(tag) + writer.newline() + writer.endtag("Axis") + writer.newline() + + def fromXML(self, name, _attrs, content, ttFont): + assert name == "Axis" + for tag, _, value in filter(lambda t: type(t) is tuple, content): + value = "".join(value) + if tag == "AxisTag": + self.axisTag = Tag(value) + elif tag in {"Flags", "MinValue", "DefaultValue", "MaxValue", "AxisNameID"}: + setattr( + self, + tag[0].lower() + tag[1:], + str2fl(value, 16) if tag.endswith("Value") else safeEval(value), + ) + + +class NamedInstance(object): + def __init__(self): + self.subfamilyNameID = 0 + self.postscriptNameID = 0xFFFF + self.flags = 0 + self.coordinates = {} + + def compile(self, axisTags, includePostScriptName): + result = [sstruct.pack(FVAR_INSTANCE_FORMAT, self)] + for axis in axisTags: + fixedCoord = fl2fi(self.coordinates[axis], 16) + result.append(struct.pack(">l", fixedCoord)) + if includePostScriptName: + result.append(struct.pack(">H", self.postscriptNameID)) + return bytesjoin(result) + + def decompile(self, data, axisTags): + sstruct.unpack2(FVAR_INSTANCE_FORMAT, data, self) + pos = sstruct.calcsize(FVAR_INSTANCE_FORMAT) + for axis in axisTags: + value = struct.unpack(">l", data[pos : pos + 4])[0] + self.coordinates[axis] = fi2fl(value, 16) + pos += 4 + if pos + 2 <= len(data): + self.postscriptNameID = struct.unpack(">H", data[pos : pos + 2])[0] + else: + self.postscriptNameID = 0xFFFF + + def toXML(self, writer, ttFont): + name = ( + ttFont["name"].getDebugName(self.subfamilyNameID) + if "name" in ttFont + else None + ) + if name is not None: + writer.newline() + writer.comment(name) + writer.newline() + psname = ( + ttFont["name"].getDebugName(self.postscriptNameID) + if "name" in ttFont + else None + ) + if psname is not None: + writer.comment("PostScript: " + psname) + writer.newline() + if self.postscriptNameID == 0xFFFF: + writer.begintag( + "NamedInstance", + flags=("0x%X" % self.flags), + subfamilyNameID=self.subfamilyNameID, + ) + else: + writer.begintag( + "NamedInstance", + flags=("0x%X" % self.flags), + subfamilyNameID=self.subfamilyNameID, + postscriptNameID=self.postscriptNameID, + ) + writer.newline() + for axis in ttFont["fvar"].axes: + writer.simpletag( + "coord", + axis=axis.axisTag, + value=fl2str(self.coordinates[axis.axisTag], 16), + ) + writer.newline() + writer.endtag("NamedInstance") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + assert name == "NamedInstance" + self.subfamilyNameID = safeEval(attrs["subfamilyNameID"]) + self.flags = safeEval(attrs.get("flags", "0")) + if "postscriptNameID" in attrs: + self.postscriptNameID = safeEval(attrs["postscriptNameID"]) + else: + self.postscriptNameID = 0xFFFF + + for tag, elementAttrs, _ in filter(lambda t: type(t) is tuple, content): + if tag == "coord": + value = str2fl(elementAttrs["value"], 16) + self.coordinates[elementAttrs["axis"]] = value diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_g_a_s_p.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_g_a_s_p.py new file mode 100644 index 0000000000000000000000000000000000000000..1f605771e9b7d98da4384e0d6a5f692646f6c07d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_g_a_s_p.py @@ -0,0 +1,63 @@ +from fontTools.misc.textTools import safeEval +from . import DefaultTable +import struct + + +GASP_SYMMETRIC_GRIDFIT = 0x0004 +GASP_SYMMETRIC_SMOOTHING = 0x0008 +GASP_DOGRAY = 0x0002 +GASP_GRIDFIT = 0x0001 + + +class table__g_a_s_p(DefaultTable.DefaultTable): + """Grid-fitting and Scan-conversion Procedure table + + The ``gasp`` table defines the preferred rasterization settings for + the font when rendered on monochrome and greyscale output devices. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/gasp + """ + + def decompile(self, data, ttFont): + self.version, numRanges = struct.unpack(">HH", data[:4]) + assert 0 <= self.version <= 1, "unknown 'gasp' format: %s" % self.version + data = data[4:] + self.gaspRange = {} + for i in range(numRanges): + rangeMaxPPEM, rangeGaspBehavior = struct.unpack(">HH", data[:4]) + self.gaspRange[int(rangeMaxPPEM)] = int(rangeGaspBehavior) + data = data[4:] + assert not data, "too much data" + + def compile(self, ttFont): + version = 0 # ignore self.version + numRanges = len(self.gaspRange) + data = b"" + items = sorted(self.gaspRange.items()) + for rangeMaxPPEM, rangeGaspBehavior in items: + data = data + struct.pack(">HH", rangeMaxPPEM, rangeGaspBehavior) + if rangeGaspBehavior & ~(GASP_GRIDFIT | GASP_DOGRAY): + version = 1 + data = struct.pack(">HH", version, numRanges) + data + return data + + def toXML(self, writer, ttFont): + items = sorted(self.gaspRange.items()) + for rangeMaxPPEM, rangeGaspBehavior in items: + writer.simpletag( + "gaspRange", + [ + ("rangeMaxPPEM", rangeMaxPPEM), + ("rangeGaspBehavior", rangeGaspBehavior), + ], + ) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name != "gaspRange": + return + if not hasattr(self, "gaspRange"): + self.gaspRange = {} + self.gaspRange[safeEval(attrs["rangeMaxPPEM"])] = safeEval( + attrs["rangeGaspBehavior"] + ) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_g_c_i_d.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_g_c_i_d.py new file mode 100644 index 0000000000000000000000000000000000000000..9d6d6ae425384b47613c146d567847c00660a5cc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_g_c_i_d.py @@ -0,0 +1,13 @@ +from .otBase import BaseTTXConverter + + +# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6gcid.html +class table__g_c_i_d(BaseTTXConverter): + """Glyph ID to CID table + + The AAT ``gcid`` table stores glyphID-to-CID mappings. + + See also https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6gcid.html + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_g_l_y_f.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_g_l_y_f.py new file mode 100644 index 0000000000000000000000000000000000000000..3dea653baa0673a0327b8c7080e7b62c33e5a726 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_g_l_y_f.py @@ -0,0 +1,2311 @@ +"""_g_l_y_f.py -- Converter classes for the 'glyf' table.""" + +from collections import namedtuple +from fontTools.misc import sstruct +from fontTools import ttLib +from fontTools import version +from fontTools.misc.transform import DecomposedTransform +from fontTools.misc.textTools import tostr, safeEval, pad +from fontTools.misc.arrayTools import updateBounds, pointInRect +from fontTools.misc.bezierTools import calcQuadraticBounds +from fontTools.misc.fixedTools import ( + fixedToFloat as fi2fl, + floatToFixed as fl2fi, + floatToFixedToStr as fl2str, + strToFixedToFloat as str2fl, +) +from fontTools.misc.roundTools import noRound, otRound +from fontTools.misc.vector import Vector +from numbers import Number +from . import DefaultTable +from . import ttProgram +import sys +import struct +import array +import logging +import math +import os +from fontTools.misc import xmlWriter +from fontTools.misc.filenames import userNameToFileName +from fontTools.misc.loggingTools import deprecateFunction +from enum import IntFlag +from functools import partial +from types import SimpleNamespace +from typing import Set + +log = logging.getLogger(__name__) + +# We compute the version the same as is computed in ttlib/__init__ +# so that we can write 'ttLibVersion' attribute of the glyf TTX files +# when glyf is written to separate files. +version = ".".join(version.split(".")[:2]) + +# +# The Apple and MS rasterizers behave differently for +# scaled composite components: one does scale first and then translate +# and the other does it vice versa. MS defined some flags to indicate +# the difference, but it seems nobody actually _sets_ those flags. +# +# Funny thing: Apple seems to _only_ do their thing in the +# WE_HAVE_A_SCALE (eg. Chicago) case, and not when it's WE_HAVE_AN_X_AND_Y_SCALE +# (eg. Charcoal)... +# +SCALE_COMPONENT_OFFSET_DEFAULT = 0 # 0 == MS, 1 == Apple + + +class table__g_l_y_f(DefaultTable.DefaultTable): + """Glyph Data table + + This class represents the `glyf <https://docs.microsoft.com/en-us/typography/opentype/spec/glyf>`_ + table, which contains outlines for glyphs in TrueType format. In many cases, + it is easier to access and manipulate glyph outlines through the ``GlyphSet`` + object returned from :py:meth:`fontTools.ttLib.ttFont.getGlyphSet`:: + + >> from fontTools.pens.boundsPen import BoundsPen + >> glyphset = font.getGlyphSet() + >> bp = BoundsPen(glyphset) + >> glyphset["A"].draw(bp) + >> bp.bounds + (19, 0, 633, 716) + + However, this class can be used for low-level access to the ``glyf`` table data. + Objects of this class support dictionary-like access, mapping glyph names to + :py:class:`Glyph` objects:: + + >> glyf = font["glyf"] + >> len(glyf["Aacute"].components) + 2 + + Note that when adding glyphs to the font via low-level access to the ``glyf`` + table, the new glyphs must also be added to the ``hmtx``/``vmtx`` table:: + + >> font["glyf"]["divisionslash"] = Glyph() + >> font["hmtx"]["divisionslash"] = (640, 0) + + """ + + dependencies = ["fvar"] + + # this attribute controls the amount of padding applied to glyph data upon compile. + # Glyph lenghts are aligned to multiples of the specified value. + # Allowed values are (0, 1, 2, 4). '0' means no padding; '1' (default) also means + # no padding, except for when padding would allow to use short loca offsets. + padding = 1 + + def decompile(self, data, ttFont): + self.axisTags = ( + [axis.axisTag for axis in ttFont["fvar"].axes] if "fvar" in ttFont else [] + ) + loca = ttFont["loca"] + pos = int(loca[0]) + nextPos = 0 + noname = 0 + self.glyphs = {} + self.glyphOrder = glyphOrder = ttFont.getGlyphOrder() + self._reverseGlyphOrder = {} + for i in range(0, len(loca) - 1): + try: + glyphName = glyphOrder[i] + except IndexError: + noname = noname + 1 + glyphName = "ttxautoglyph%s" % i + nextPos = int(loca[i + 1]) + glyphdata = data[pos:nextPos] + if len(glyphdata) != (nextPos - pos): + raise ttLib.TTLibError("not enough 'glyf' table data") + glyph = Glyph(glyphdata) + self.glyphs[glyphName] = glyph + pos = nextPos + if len(data) - nextPos >= 4: + log.warning( + "too much 'glyf' table data: expected %d, received %d bytes", + nextPos, + len(data), + ) + if noname: + log.warning("%s glyphs have no name", noname) + if ttFont.lazy is False: # Be lazy for None and True + self.ensureDecompiled() + + def ensureDecompiled(self, recurse=False): + # The recurse argument is unused, but part of the signature of + # ensureDecompiled across the library. + for glyph in self.glyphs.values(): + glyph.expand(self) + + def compile(self, ttFont): + optimizeSpeed = ttFont.cfg[ttLib.OPTIMIZE_FONT_SPEED] + + self.axisTags = ( + [axis.axisTag for axis in ttFont["fvar"].axes] if "fvar" in ttFont else [] + ) + if not hasattr(self, "glyphOrder"): + self.glyphOrder = ttFont.getGlyphOrder() + padding = self.padding + assert padding in (0, 1, 2, 4) + locations = [] + currentLocation = 0 + dataList = [] + recalcBBoxes = ttFont.recalcBBoxes + boundsDone = set() + for glyphName in self.glyphOrder: + glyph = self.glyphs[glyphName] + glyphData = glyph.compile( + self, + recalcBBoxes, + boundsDone=boundsDone, + optimizeSize=not optimizeSpeed, + ) + if padding > 1: + glyphData = pad(glyphData, size=padding) + locations.append(currentLocation) + currentLocation = currentLocation + len(glyphData) + dataList.append(glyphData) + locations.append(currentLocation) + + if padding == 1 and currentLocation < 0x20000: + # See if we can pad any odd-lengthed glyphs to allow loca + # table to use the short offsets. + indices = [ + i for i, glyphData in enumerate(dataList) if len(glyphData) % 2 == 1 + ] + if indices and currentLocation + len(indices) < 0x20000: + # It fits. Do it. + for i in indices: + dataList[i] += b"\0" + currentLocation = 0 + for i, glyphData in enumerate(dataList): + locations[i] = currentLocation + currentLocation += len(glyphData) + locations[len(dataList)] = currentLocation + + data = b"".join(dataList) + if "loca" in ttFont: + ttFont["loca"].set(locations) + if "maxp" in ttFont: + ttFont["maxp"].numGlyphs = len(self.glyphs) + if not data: + # As a special case when all glyph in the font are empty, add a zero byte + # to the table, so that OTS doesn’t reject it, and to make the table work + # on Windows as well. + # See https://github.com/khaledhosny/ots/issues/52 + data = b"\0" + return data + + def toXML(self, writer, ttFont, splitGlyphs=False): + notice = ( + "The xMin, yMin, xMax and yMax values\n" + "will be recalculated by the compiler." + ) + glyphNames = ttFont.getGlyphNames() + if not splitGlyphs: + writer.newline() + writer.comment(notice) + writer.newline() + writer.newline() + numGlyphs = len(glyphNames) + if splitGlyphs: + path, ext = os.path.splitext(writer.file.name) + existingGlyphFiles = set() + for glyphName in glyphNames: + glyph = self.get(glyphName) + if glyph is None: + log.warning("glyph '%s' does not exist in glyf table", glyphName) + continue + if glyph.numberOfContours: + if splitGlyphs: + glyphPath = userNameToFileName( + tostr(glyphName, "utf-8"), + existingGlyphFiles, + prefix=path + ".", + suffix=ext, + ) + existingGlyphFiles.add(glyphPath.lower()) + glyphWriter = xmlWriter.XMLWriter( + glyphPath, + idlefunc=writer.idlefunc, + newlinestr=writer.newlinestr, + ) + glyphWriter.begintag("ttFont", ttLibVersion=version) + glyphWriter.newline() + glyphWriter.begintag("glyf") + glyphWriter.newline() + glyphWriter.comment(notice) + glyphWriter.newline() + writer.simpletag("TTGlyph", src=os.path.basename(glyphPath)) + else: + glyphWriter = writer + glyphWriter.begintag( + "TTGlyph", + [ + ("name", glyphName), + ("xMin", glyph.xMin), + ("yMin", glyph.yMin), + ("xMax", glyph.xMax), + ("yMax", glyph.yMax), + ], + ) + glyphWriter.newline() + glyph.toXML(glyphWriter, ttFont) + glyphWriter.endtag("TTGlyph") + glyphWriter.newline() + if splitGlyphs: + glyphWriter.endtag("glyf") + glyphWriter.newline() + glyphWriter.endtag("ttFont") + glyphWriter.newline() + glyphWriter.close() + else: + writer.simpletag("TTGlyph", name=glyphName) + writer.comment("contains no outline data") + if not splitGlyphs: + writer.newline() + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name != "TTGlyph": + return + if not hasattr(self, "glyphs"): + self.glyphs = {} + if not hasattr(self, "glyphOrder"): + self.glyphOrder = ttFont.getGlyphOrder() + glyphName = attrs["name"] + log.debug("unpacking glyph '%s'", glyphName) + glyph = Glyph() + for attr in ["xMin", "yMin", "xMax", "yMax"]: + setattr(glyph, attr, safeEval(attrs.get(attr, "0"))) + self.glyphs[glyphName] = glyph + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + glyph.fromXML(name, attrs, content, ttFont) + if not ttFont.recalcBBoxes: + glyph.compact(self, 0) + + def setGlyphOrder(self, glyphOrder): + """Sets the glyph order + + Args: + glyphOrder ([str]): List of glyph names in order. + """ + self.glyphOrder = glyphOrder + self._reverseGlyphOrder = {} + + def getGlyphName(self, glyphID): + """Returns the name for the glyph with the given ID. + + Raises a ``KeyError`` if the glyph name is not found in the font. + """ + return self.glyphOrder[glyphID] + + def _buildReverseGlyphOrderDict(self): + self._reverseGlyphOrder = d = {} + for glyphID, glyphName in enumerate(self.glyphOrder): + d[glyphName] = glyphID + + def getGlyphID(self, glyphName): + """Returns the ID of the glyph with the given name. + + Raises a ``ValueError`` if the glyph is not found in the font. + """ + glyphOrder = self.glyphOrder + id = getattr(self, "_reverseGlyphOrder", {}).get(glyphName) + if id is None or id >= len(glyphOrder) or glyphOrder[id] != glyphName: + self._buildReverseGlyphOrderDict() + id = self._reverseGlyphOrder.get(glyphName) + if id is None: + raise ValueError(glyphName) + return id + + def removeHinting(self): + """Removes TrueType hints from all glyphs in the glyphset. + + See :py:meth:`Glyph.removeHinting`. + """ + for glyph in self.glyphs.values(): + glyph.removeHinting() + + def keys(self): + return self.glyphs.keys() + + def has_key(self, glyphName): + return glyphName in self.glyphs + + __contains__ = has_key + + def get(self, glyphName, default=None): + glyph = self.glyphs.get(glyphName, default) + if glyph is not None: + glyph.expand(self) + return glyph + + def __getitem__(self, glyphName): + glyph = self.glyphs[glyphName] + glyph.expand(self) + return glyph + + def __setitem__(self, glyphName, glyph): + self.glyphs[glyphName] = glyph + if glyphName not in self.glyphOrder: + self.glyphOrder.append(glyphName) + + def __delitem__(self, glyphName): + del self.glyphs[glyphName] + self.glyphOrder.remove(glyphName) + + def __len__(self): + assert len(self.glyphOrder) == len(self.glyphs) + return len(self.glyphs) + + def _getPhantomPoints(self, glyphName, hMetrics, vMetrics=None): + """Compute the four "phantom points" for the given glyph from its bounding box + and the horizontal and vertical advance widths and sidebearings stored in the + ttFont's "hmtx" and "vmtx" tables. + + 'hMetrics' should be ttFont['hmtx'].metrics. + + 'vMetrics' should be ttFont['vmtx'].metrics if there is "vmtx" or None otherwise. + If there is no vMetrics passed in, vertical phantom points are set to the zero coordinate. + + https://docs.microsoft.com/en-us/typography/opentype/spec/tt_instructing_glyphs#phantoms + """ + glyph = self[glyphName] + if not hasattr(glyph, "xMin"): + glyph.recalcBounds(self) + + horizontalAdvanceWidth, leftSideBearing = hMetrics[glyphName] + leftSideX = glyph.xMin - leftSideBearing + rightSideX = leftSideX + horizontalAdvanceWidth + + if vMetrics: + verticalAdvanceWidth, topSideBearing = vMetrics[glyphName] + topSideY = topSideBearing + glyph.yMax + bottomSideY = topSideY - verticalAdvanceWidth + else: + bottomSideY = topSideY = 0 + + return [ + (leftSideX, 0), + (rightSideX, 0), + (0, topSideY), + (0, bottomSideY), + ] + + def _getCoordinatesAndControls( + self, glyphName, hMetrics, vMetrics=None, *, round=otRound + ): + """Return glyph coordinates and controls as expected by "gvar" table. + + The coordinates includes four "phantom points" for the glyph metrics, + as mandated by the "gvar" spec. + + The glyph controls is a namedtuple with the following attributes: + - numberOfContours: -1 for composite glyphs. + - endPts: list of indices of end points for each contour in simple + glyphs, or component indices in composite glyphs (used for IUP + optimization). + - flags: array of contour point flags for simple glyphs (None for + composite glyphs). + - components: list of base glyph names (str) for each component in + composite glyphs (None for simple glyphs). + + The "hMetrics" and vMetrics are used to compute the "phantom points" (see + the "_getPhantomPoints" method). + + Return None if the requested glyphName is not present. + """ + glyph = self.get(glyphName) + if glyph is None: + return None + if glyph.isComposite(): + coords = GlyphCoordinates( + [(getattr(c, "x", 0), getattr(c, "y", 0)) for c in glyph.components] + ) + controls = _GlyphControls( + numberOfContours=glyph.numberOfContours, + endPts=list(range(len(glyph.components))), + flags=None, + components=[ + (c.glyphName, getattr(c, "transform", None)) + for c in glyph.components + ], + ) + else: + coords, endPts, flags = glyph.getCoordinates(self) + coords = coords.copy() + controls = _GlyphControls( + numberOfContours=glyph.numberOfContours, + endPts=endPts, + flags=flags, + components=None, + ) + # Add phantom points for (left, right, top, bottom) positions. + phantomPoints = self._getPhantomPoints(glyphName, hMetrics, vMetrics) + coords.extend(phantomPoints) + coords.toInt(round=round) + return coords, controls + + def _setCoordinates(self, glyphName, coord, hMetrics, vMetrics=None): + """Set coordinates and metrics for the given glyph. + + "coord" is an array of GlyphCoordinates which must include the "phantom + points" as the last four coordinates. + + Both the horizontal/vertical advances and left/top sidebearings in "hmtx" + and "vmtx" tables (if any) are updated from four phantom points and + the glyph's bounding boxes. + + The "hMetrics" and vMetrics are used to propagate "phantom points" + into "hmtx" and "vmtx" tables if desired. (see the "_getPhantomPoints" + method). + """ + glyph = self[glyphName] + + # Handle phantom points for (left, right, top, bottom) positions. + assert len(coord) >= 4 + leftSideX = coord[-4][0] + rightSideX = coord[-3][0] + topSideY = coord[-2][1] + bottomSideY = coord[-1][1] + + coord = coord[:-4] + + if glyph.isComposite(): + assert len(coord) == len(glyph.components) + for p, comp in zip(coord, glyph.components): + if hasattr(comp, "x"): + comp.x, comp.y = p + elif glyph.numberOfContours == 0: + assert len(coord) == 0 + else: + assert len(coord) == len(glyph.coordinates) + glyph.coordinates = GlyphCoordinates(coord) + + glyph.recalcBounds(self, boundsDone=set()) + + horizontalAdvanceWidth = otRound(rightSideX - leftSideX) + if horizontalAdvanceWidth < 0: + # unlikely, but it can happen, see: + # https://github.com/fonttools/fonttools/pull/1198 + horizontalAdvanceWidth = 0 + leftSideBearing = otRound(glyph.xMin - leftSideX) + hMetrics[glyphName] = horizontalAdvanceWidth, leftSideBearing + + if vMetrics is not None: + verticalAdvanceWidth = otRound(topSideY - bottomSideY) + if verticalAdvanceWidth < 0: # unlikely but do the same as horizontal + verticalAdvanceWidth = 0 + topSideBearing = otRound(topSideY - glyph.yMax) + vMetrics[glyphName] = verticalAdvanceWidth, topSideBearing + + # Deprecated + + def _synthesizeVMetrics(self, glyphName, ttFont, defaultVerticalOrigin): + """This method is wrong and deprecated. + For rationale see: + https://github.com/fonttools/fonttools/pull/2266/files#r613569473 + """ + vMetrics = getattr(ttFont.get("vmtx"), "metrics", None) + if vMetrics is None: + verticalAdvanceWidth = ttFont["head"].unitsPerEm + topSideY = getattr(ttFont.get("hhea"), "ascent", None) + if topSideY is None: + if defaultVerticalOrigin is not None: + topSideY = defaultVerticalOrigin + else: + topSideY = verticalAdvanceWidth + glyph = self[glyphName] + glyph.recalcBounds(self) + topSideBearing = otRound(topSideY - glyph.yMax) + vMetrics = {glyphName: (verticalAdvanceWidth, topSideBearing)} + return vMetrics + + @deprecateFunction("use '_getPhantomPoints' instead", category=DeprecationWarning) + def getPhantomPoints(self, glyphName, ttFont, defaultVerticalOrigin=None): + """Old public name for self._getPhantomPoints(). + See: https://github.com/fonttools/fonttools/pull/2266""" + hMetrics = ttFont["hmtx"].metrics + vMetrics = self._synthesizeVMetrics(glyphName, ttFont, defaultVerticalOrigin) + return self._getPhantomPoints(glyphName, hMetrics, vMetrics) + + @deprecateFunction( + "use '_getCoordinatesAndControls' instead", category=DeprecationWarning + ) + def getCoordinatesAndControls(self, glyphName, ttFont, defaultVerticalOrigin=None): + """Old public name for self._getCoordinatesAndControls(). + See: https://github.com/fonttools/fonttools/pull/2266""" + hMetrics = ttFont["hmtx"].metrics + vMetrics = self._synthesizeVMetrics(glyphName, ttFont, defaultVerticalOrigin) + return self._getCoordinatesAndControls(glyphName, hMetrics, vMetrics) + + @deprecateFunction("use '_setCoordinates' instead", category=DeprecationWarning) + def setCoordinates(self, glyphName, ttFont): + """Old public name for self._setCoordinates(). + See: https://github.com/fonttools/fonttools/pull/2266""" + hMetrics = ttFont["hmtx"].metrics + vMetrics = getattr(ttFont.get("vmtx"), "metrics", None) + self._setCoordinates(glyphName, hMetrics, vMetrics) + + +_GlyphControls = namedtuple( + "_GlyphControls", "numberOfContours endPts flags components" +) + + +glyphHeaderFormat = """ + > # big endian + numberOfContours: h + xMin: h + yMin: h + xMax: h + yMax: h +""" + +# flags +flagOnCurve = 0x01 +flagXShort = 0x02 +flagYShort = 0x04 +flagRepeat = 0x08 +flagXsame = 0x10 +flagYsame = 0x20 +flagOverlapSimple = 0x40 +flagCubic = 0x80 + +# These flags are kept for XML output after decompiling the coordinates +keepFlags = flagOnCurve + flagOverlapSimple + flagCubic + +_flagSignBytes = { + 0: 2, + flagXsame: 0, + flagXShort | flagXsame: +1, + flagXShort: -1, + flagYsame: 0, + flagYShort | flagYsame: +1, + flagYShort: -1, +} + + +def flagBest(x, y, onCurve): + """For a given x,y delta pair, returns the flag that packs this pair + most efficiently, as well as the number of byte cost of such flag.""" + + flag = flagOnCurve if onCurve else 0 + cost = 0 + # do x + if x == 0: + flag = flag | flagXsame + elif -255 <= x <= 255: + flag = flag | flagXShort + if x > 0: + flag = flag | flagXsame + cost += 1 + else: + cost += 2 + # do y + if y == 0: + flag = flag | flagYsame + elif -255 <= y <= 255: + flag = flag | flagYShort + if y > 0: + flag = flag | flagYsame + cost += 1 + else: + cost += 2 + return flag, cost + + +def flagFits(newFlag, oldFlag, mask): + newBytes = _flagSignBytes[newFlag & mask] + oldBytes = _flagSignBytes[oldFlag & mask] + return newBytes == oldBytes or abs(newBytes) > abs(oldBytes) + + +def flagSupports(newFlag, oldFlag): + return ( + (oldFlag & flagOnCurve) == (newFlag & flagOnCurve) + and flagFits(newFlag, oldFlag, flagXsame | flagXShort) + and flagFits(newFlag, oldFlag, flagYsame | flagYShort) + ) + + +def flagEncodeCoord(flag, mask, coord, coordBytes): + byteCount = _flagSignBytes[flag & mask] + if byteCount == 1: + coordBytes.append(coord) + elif byteCount == -1: + coordBytes.append(-coord) + elif byteCount == 2: + coordBytes.extend(struct.pack(">h", coord)) + + +def flagEncodeCoords(flag, x, y, xBytes, yBytes): + flagEncodeCoord(flag, flagXsame | flagXShort, x, xBytes) + flagEncodeCoord(flag, flagYsame | flagYShort, y, yBytes) + + +ARG_1_AND_2_ARE_WORDS = 0x0001 # if set args are words otherwise they are bytes +ARGS_ARE_XY_VALUES = 0x0002 # if set args are xy values, otherwise they are points +ROUND_XY_TO_GRID = 0x0004 # for the xy values if above is true +WE_HAVE_A_SCALE = 0x0008 # Sx = Sy, otherwise scale == 1.0 +NON_OVERLAPPING = 0x0010 # set to same value for all components (obsolete!) +MORE_COMPONENTS = 0x0020 # indicates at least one more glyph after this one +WE_HAVE_AN_X_AND_Y_SCALE = 0x0040 # Sx, Sy +WE_HAVE_A_TWO_BY_TWO = 0x0080 # t00, t01, t10, t11 +WE_HAVE_INSTRUCTIONS = 0x0100 # instructions follow +USE_MY_METRICS = 0x0200 # apply these metrics to parent glyph +OVERLAP_COMPOUND = 0x0400 # used by Apple in GX fonts +SCALED_COMPONENT_OFFSET = 0x0800 # composite designed to have the component offset scaled (designed for Apple) +UNSCALED_COMPONENT_OFFSET = 0x1000 # composite designed not to have the component offset scaled (designed for MS) + + +CompositeMaxpValues = namedtuple( + "CompositeMaxpValues", ["nPoints", "nContours", "maxComponentDepth"] +) + + +class Glyph(object): + """This class represents an individual TrueType glyph. + + TrueType glyph objects come in two flavours: simple and composite. Simple + glyph objects contain contours, represented via the ``.coordinates``, + ``.flags``, ``.numberOfContours``, and ``.endPtsOfContours`` attributes; + composite glyphs contain components, available through the ``.components`` + attributes. + + Because the ``.coordinates`` attribute (and other simple glyph attributes mentioned + above) is only set on simple glyphs and the ``.components`` attribute is only + set on composite glyphs, it is necessary to use the :py:meth:`isComposite` + method to test whether a glyph is simple or composite before attempting to + access its data. + + For a composite glyph, the components can also be accessed via array-like access:: + + >> assert(font["glyf"]["Aacute"].isComposite()) + >> font["glyf"]["Aacute"][0] + <fontTools.ttLib.tables._g_l_y_f.GlyphComponent at 0x1027b2ee0> + + """ + + def __init__(self, data=b""): + if not data: + # empty char + self.numberOfContours = 0 + return + self.data = data + + def compact(self, glyfTable, recalcBBoxes=True): + data = self.compile(glyfTable, recalcBBoxes) + self.__dict__.clear() + self.data = data + + def expand(self, glyfTable): + if not hasattr(self, "data"): + # already unpacked + return + if not self.data: + # empty char + del self.data + self.numberOfContours = 0 + return + dummy, data = sstruct.unpack2(glyphHeaderFormat, self.data, self) + del self.data + # Some fonts (eg. Neirizi.ttf) have a 0 for numberOfContours in + # some glyphs; decompileCoordinates assumes that there's at least + # one, so short-circuit here. + if self.numberOfContours == 0: + return + if self.isComposite(): + self.decompileComponents(data, glyfTable) + else: + self.decompileCoordinates(data) + + def compile( + self, glyfTable, recalcBBoxes=True, *, boundsDone=None, optimizeSize=True + ): + if hasattr(self, "data"): + if recalcBBoxes: + # must unpack glyph in order to recalculate bounding box + self.expand(glyfTable) + else: + return self.data + if self.numberOfContours == 0: + return b"" + + if recalcBBoxes: + self.recalcBounds(glyfTable, boundsDone=boundsDone) + + data = sstruct.pack(glyphHeaderFormat, self) + if self.isComposite(): + data = data + self.compileComponents(glyfTable) + else: + data = data + self.compileCoordinates(optimizeSize=optimizeSize) + return data + + def toXML(self, writer, ttFont): + if self.isComposite(): + for compo in self.components: + compo.toXML(writer, ttFont) + haveInstructions = hasattr(self, "program") + else: + last = 0 + for i in range(self.numberOfContours): + writer.begintag("contour") + writer.newline() + for j in range(last, self.endPtsOfContours[i] + 1): + attrs = [ + ("x", self.coordinates[j][0]), + ("y", self.coordinates[j][1]), + ("on", self.flags[j] & flagOnCurve), + ] + if self.flags[j] & flagOverlapSimple: + # Apple's rasterizer uses flagOverlapSimple in the first contour/first pt to flag glyphs that contain overlapping contours + attrs.append(("overlap", 1)) + if self.flags[j] & flagCubic: + attrs.append(("cubic", 1)) + writer.simpletag("pt", attrs) + writer.newline() + last = self.endPtsOfContours[i] + 1 + writer.endtag("contour") + writer.newline() + haveInstructions = self.numberOfContours > 0 + if haveInstructions: + if self.program: + writer.begintag("instructions") + writer.newline() + self.program.toXML(writer, ttFont) + writer.endtag("instructions") + else: + writer.simpletag("instructions") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "contour": + if self.numberOfContours < 0: + raise ttLib.TTLibError("can't mix composites and contours in glyph") + self.numberOfContours = self.numberOfContours + 1 + coordinates = GlyphCoordinates() + flags = bytearray() + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name != "pt": + continue # ignore anything but "pt" + coordinates.append((safeEval(attrs["x"]), safeEval(attrs["y"]))) + flag = bool(safeEval(attrs["on"])) + if "overlap" in attrs and bool(safeEval(attrs["overlap"])): + flag |= flagOverlapSimple + if "cubic" in attrs and bool(safeEval(attrs["cubic"])): + flag |= flagCubic + flags.append(flag) + if not hasattr(self, "coordinates"): + self.coordinates = coordinates + self.flags = flags + self.endPtsOfContours = [len(coordinates) - 1] + else: + self.coordinates.extend(coordinates) + self.flags.extend(flags) + self.endPtsOfContours.append(len(self.coordinates) - 1) + elif name == "component": + if self.numberOfContours > 0: + raise ttLib.TTLibError("can't mix composites and contours in glyph") + self.numberOfContours = -1 + if not hasattr(self, "components"): + self.components = [] + component = GlyphComponent() + self.components.append(component) + component.fromXML(name, attrs, content, ttFont) + elif name == "instructions": + self.program = ttProgram.Program() + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + self.program.fromXML(name, attrs, content, ttFont) + + def getCompositeMaxpValues(self, glyfTable, maxComponentDepth=1): + assert self.isComposite() + nContours = 0 + nPoints = 0 + initialMaxComponentDepth = maxComponentDepth + for compo in self.components: + baseGlyph = glyfTable[compo.glyphName] + if baseGlyph.numberOfContours == 0: + continue + elif baseGlyph.numberOfContours > 0: + nP, nC = baseGlyph.getMaxpValues() + else: + nP, nC, componentDepth = baseGlyph.getCompositeMaxpValues( + glyfTable, initialMaxComponentDepth + 1 + ) + maxComponentDepth = max(maxComponentDepth, componentDepth) + nPoints = nPoints + nP + nContours = nContours + nC + return CompositeMaxpValues(nPoints, nContours, maxComponentDepth) + + def getMaxpValues(self): + assert self.numberOfContours > 0 + return len(self.coordinates), len(self.endPtsOfContours) + + def decompileComponents(self, data, glyfTable): + self.components = [] + more = 1 + haveInstructions = 0 + while more: + component = GlyphComponent() + more, haveInstr, data = component.decompile(data, glyfTable) + haveInstructions = haveInstructions | haveInstr + self.components.append(component) + if haveInstructions: + (numInstructions,) = struct.unpack(">h", data[:2]) + data = data[2:] + self.program = ttProgram.Program() + self.program.fromBytecode(data[:numInstructions]) + data = data[numInstructions:] + if len(data) >= 4: + log.warning( + "too much glyph data at the end of composite glyph: %d excess bytes", + len(data), + ) + + def decompileCoordinates(self, data): + endPtsOfContours = array.array("H") + endPtsOfContours.frombytes(data[: 2 * self.numberOfContours]) + if sys.byteorder != "big": + endPtsOfContours.byteswap() + self.endPtsOfContours = endPtsOfContours.tolist() + + pos = 2 * self.numberOfContours + (instructionLength,) = struct.unpack(">h", data[pos : pos + 2]) + self.program = ttProgram.Program() + self.program.fromBytecode(data[pos + 2 : pos + 2 + instructionLength]) + pos += 2 + instructionLength + nCoordinates = self.endPtsOfContours[-1] + 1 + flags, xCoordinates, yCoordinates = self.decompileCoordinatesRaw( + nCoordinates, data, pos + ) + + # fill in repetitions and apply signs + self.coordinates = coordinates = GlyphCoordinates.zeros(nCoordinates) + xIndex = 0 + yIndex = 0 + for i in range(nCoordinates): + flag = flags[i] + # x coordinate + if flag & flagXShort: + if flag & flagXsame: + x = xCoordinates[xIndex] + else: + x = -xCoordinates[xIndex] + xIndex = xIndex + 1 + elif flag & flagXsame: + x = 0 + else: + x = xCoordinates[xIndex] + xIndex = xIndex + 1 + # y coordinate + if flag & flagYShort: + if flag & flagYsame: + y = yCoordinates[yIndex] + else: + y = -yCoordinates[yIndex] + yIndex = yIndex + 1 + elif flag & flagYsame: + y = 0 + else: + y = yCoordinates[yIndex] + yIndex = yIndex + 1 + coordinates[i] = (x, y) + assert xIndex == len(xCoordinates) + assert yIndex == len(yCoordinates) + coordinates.relativeToAbsolute() + # discard all flags except "keepFlags" + for i in range(len(flags)): + flags[i] &= keepFlags + self.flags = flags + + def decompileCoordinatesRaw(self, nCoordinates, data, pos=0): + # unpack flags and prepare unpacking of coordinates + flags = bytearray(nCoordinates) + # Warning: deep Python trickery going on. We use the struct module to unpack + # the coordinates. We build a format string based on the flags, so we can + # unpack the coordinates in one struct.unpack() call. + xFormat = ">" # big endian + yFormat = ">" # big endian + j = 0 + while True: + flag = data[pos] + pos += 1 + repeat = 1 + if flag & flagRepeat: + repeat = data[pos] + 1 + pos += 1 + for k in range(repeat): + if flag & flagXShort: + xFormat = xFormat + "B" + elif not (flag & flagXsame): + xFormat = xFormat + "h" + if flag & flagYShort: + yFormat = yFormat + "B" + elif not (flag & flagYsame): + yFormat = yFormat + "h" + flags[j] = flag + j = j + 1 + if j >= nCoordinates: + break + assert j == nCoordinates, "bad glyph flags" + # unpack raw coordinates, krrrrrr-tching! + xDataLen = struct.calcsize(xFormat) + yDataLen = struct.calcsize(yFormat) + if len(data) - pos - (xDataLen + yDataLen) >= 4: + log.warning( + "too much glyph data: %d excess bytes", + len(data) - pos - (xDataLen + yDataLen), + ) + xCoordinates = struct.unpack(xFormat, data[pos : pos + xDataLen]) + yCoordinates = struct.unpack( + yFormat, data[pos + xDataLen : pos + xDataLen + yDataLen] + ) + return flags, xCoordinates, yCoordinates + + def compileComponents(self, glyfTable): + data = b"" + lastcomponent = len(self.components) - 1 + more = 1 + haveInstructions = 0 + for i, compo in enumerate(self.components): + if i == lastcomponent: + haveInstructions = hasattr(self, "program") + more = 0 + data = data + compo.compile(more, haveInstructions, glyfTable) + if haveInstructions: + instructions = self.program.getBytecode() + data = data + struct.pack(">h", len(instructions)) + instructions + return data + + def compileCoordinates(self, *, optimizeSize=True): + assert len(self.coordinates) == len(self.flags) + data = [] + endPtsOfContours = array.array("H", self.endPtsOfContours) + if sys.byteorder != "big": + endPtsOfContours.byteswap() + data.append(endPtsOfContours.tobytes()) + instructions = self.program.getBytecode() + data.append(struct.pack(">h", len(instructions))) + data.append(instructions) + + deltas = self.coordinates.copy() + deltas.toInt() + deltas.absoluteToRelative() + + if optimizeSize: + # TODO(behdad): Add a configuration option for this? + deltas = self.compileDeltasGreedy(self.flags, deltas) + # deltas = self.compileDeltasOptimal(self.flags, deltas) + else: + deltas = self.compileDeltasForSpeed(self.flags, deltas) + + data.extend(deltas) + return b"".join(data) + + def compileDeltasGreedy(self, flags, deltas): + # Implements greedy algorithm for packing coordinate deltas: + # uses shortest representation one coordinate at a time. + compressedFlags = bytearray() + compressedXs = bytearray() + compressedYs = bytearray() + lastflag = None + repeat = 0 + for flag, (x, y) in zip(flags, deltas): + # Oh, the horrors of TrueType + # do x + if x == 0: + flag = flag | flagXsame + elif -255 <= x <= 255: + flag = flag | flagXShort + if x > 0: + flag = flag | flagXsame + else: + x = -x + compressedXs.append(x) + else: + compressedXs.extend(struct.pack(">h", x)) + # do y + if y == 0: + flag = flag | flagYsame + elif -255 <= y <= 255: + flag = flag | flagYShort + if y > 0: + flag = flag | flagYsame + else: + y = -y + compressedYs.append(y) + else: + compressedYs.extend(struct.pack(">h", y)) + # handle repeating flags + if flag == lastflag and repeat != 255: + repeat = repeat + 1 + if repeat == 1: + compressedFlags.append(flag) + else: + compressedFlags[-2] = flag | flagRepeat + compressedFlags[-1] = repeat + else: + repeat = 0 + compressedFlags.append(flag) + lastflag = flag + return (compressedFlags, compressedXs, compressedYs) + + def compileDeltasOptimal(self, flags, deltas): + # Implements optimal, dynaic-programming, algorithm for packing coordinate + # deltas. The savings are negligible :(. + candidates = [] + bestTuple = None + bestCost = 0 + repeat = 0 + for flag, (x, y) in zip(flags, deltas): + # Oh, the horrors of TrueType + flag, coordBytes = flagBest(x, y, flag) + bestCost += 1 + coordBytes + newCandidates = [ + (bestCost, bestTuple, flag, coordBytes), + (bestCost + 1, bestTuple, (flag | flagRepeat), coordBytes), + ] + for lastCost, lastTuple, lastFlag, coordBytes in candidates: + if ( + lastCost + coordBytes <= bestCost + 1 + and (lastFlag & flagRepeat) + and (lastFlag < 0xFF00) + and flagSupports(lastFlag, flag) + ): + if (lastFlag & 0xFF) == ( + flag | flagRepeat + ) and lastCost == bestCost + 1: + continue + newCandidates.append( + (lastCost + coordBytes, lastTuple, lastFlag + 256, coordBytes) + ) + candidates = newCandidates + bestTuple = min(candidates, key=lambda t: t[0]) + bestCost = bestTuple[0] + + flags = [] + while bestTuple: + cost, bestTuple, flag, coordBytes = bestTuple + flags.append(flag) + flags.reverse() + + compressedFlags = bytearray() + compressedXs = bytearray() + compressedYs = bytearray() + coords = iter(deltas) + ff = [] + for flag in flags: + repeatCount, flag = flag >> 8, flag & 0xFF + compressedFlags.append(flag) + if flag & flagRepeat: + assert repeatCount > 0 + compressedFlags.append(repeatCount) + else: + assert repeatCount == 0 + for i in range(1 + repeatCount): + x, y = next(coords) + flagEncodeCoords(flag, x, y, compressedXs, compressedYs) + ff.append(flag) + try: + next(coords) + raise Exception("internal error") + except StopIteration: + pass + + return (compressedFlags, compressedXs, compressedYs) + + def compileDeltasForSpeed(self, flags, deltas): + # uses widest representation needed, for all deltas. + compressedFlags = bytearray() + compressedXs = bytearray() + compressedYs = bytearray() + + # Compute the necessary width for each axis + xs = [d[0] for d in deltas] + ys = [d[1] for d in deltas] + minX, minY, maxX, maxY = min(xs), min(ys), max(xs), max(ys) + xZero = minX == 0 and maxX == 0 + yZero = minY == 0 and maxY == 0 + xShort = -255 <= minX <= maxX <= 255 + yShort = -255 <= minY <= maxY <= 255 + + lastflag = None + repeat = 0 + for flag, (x, y) in zip(flags, deltas): + # Oh, the horrors of TrueType + # do x + if xZero: + flag = flag | flagXsame + elif xShort: + flag = flag | flagXShort + if x > 0: + flag = flag | flagXsame + else: + x = -x + compressedXs.append(x) + else: + compressedXs.extend(struct.pack(">h", x)) + # do y + if yZero: + flag = flag | flagYsame + elif yShort: + flag = flag | flagYShort + if y > 0: + flag = flag | flagYsame + else: + y = -y + compressedYs.append(y) + else: + compressedYs.extend(struct.pack(">h", y)) + # handle repeating flags + if flag == lastflag and repeat != 255: + repeat = repeat + 1 + if repeat == 1: + compressedFlags.append(flag) + else: + compressedFlags[-2] = flag | flagRepeat + compressedFlags[-1] = repeat + else: + repeat = 0 + compressedFlags.append(flag) + lastflag = flag + return (compressedFlags, compressedXs, compressedYs) + + def recalcBounds(self, glyfTable, *, boundsDone=None): + """Recalculates the bounds of the glyph. + + Each glyph object stores its bounding box in the + ``xMin``/``yMin``/``xMax``/``yMax`` attributes. These bounds must be + recomputed when the ``coordinates`` change. The ``table__g_l_y_f`` bounds + must be provided to resolve component bounds. + """ + if self.isComposite() and self.tryRecalcBoundsComposite( + glyfTable, boundsDone=boundsDone + ): + return + try: + coords, endPts, flags = self.getCoordinates(glyfTable, round=otRound) + self.xMin, self.yMin, self.xMax, self.yMax = coords.calcIntBounds() + except NotImplementedError: + pass + + def tryRecalcBoundsComposite(self, glyfTable, *, boundsDone=None): + """Try recalculating the bounds of a composite glyph that has + certain constrained properties. Namely, none of the components + have a transform other than an integer translate, and none + uses the anchor points. + + Each glyph object stores its bounding box in the + ``xMin``/``yMin``/``xMax``/``yMax`` attributes. These bounds must be + recomputed when the ``coordinates`` change. The ``table__g_l_y_f`` bounds + must be provided to resolve component bounds. + + Return True if bounds were calculated, False otherwise. + """ + for compo in self.components: + if not compo._hasOnlyIntegerTranslate(): + return False + + # All components are untransformed and have an integer x/y translate + bounds = None + for compo in self.components: + glyphName = compo.glyphName + g = glyfTable[glyphName] + + if boundsDone is None or glyphName not in boundsDone: + g.recalcBounds(glyfTable, boundsDone=boundsDone) + if boundsDone is not None: + boundsDone.add(glyphName) + # empty components shouldn't update the bounds of the parent glyph + if g.yMin == g.yMax and g.xMin == g.xMax: + continue + + x, y = compo.x, compo.y + bounds = updateBounds(bounds, (g.xMin + x, g.yMin + y)) + bounds = updateBounds(bounds, (g.xMax + x, g.yMax + y)) + + if bounds is None: + bounds = (0, 0, 0, 0) + self.xMin, self.yMin, self.xMax, self.yMax = bounds + return True + + def isComposite(self): + """Test whether a glyph has components""" + if hasattr(self, "data"): + return struct.unpack(">h", self.data[:2])[0] == -1 if self.data else False + else: + return self.numberOfContours == -1 + + def getCoordinates(self, glyfTable, *, round=noRound): + """Return the coordinates, end points and flags + + This method returns three values: A :py:class:`GlyphCoordinates` object, + a list of the indexes of the final points of each contour (allowing you + to split up the coordinates list into contours) and a list of flags. + + On simple glyphs, this method returns information from the glyph's own + contours; on composite glyphs, it "flattens" all components recursively + to return a list of coordinates representing all the components involved + in the glyph. + + To interpret the flags for each point, see the "Simple Glyph Flags" + section of the `glyf table specification <https://docs.microsoft.com/en-us/typography/opentype/spec/glyf#simple-glyph-description>`. + """ + + if self.numberOfContours > 0: + return self.coordinates, self.endPtsOfContours, self.flags + elif self.isComposite(): + # it's a composite + allCoords = GlyphCoordinates() + allFlags = bytearray() + allEndPts = [] + for compo in self.components: + g = glyfTable[compo.glyphName] + try: + coordinates, endPts, flags = g.getCoordinates( + glyfTable, round=round + ) + except RecursionError: + raise ttLib.TTLibError( + "glyph '%s' contains a recursive component reference" + % compo.glyphName + ) + coordinates = GlyphCoordinates(coordinates) + # if asked to round e.g. while computing bboxes, it's important we + # do it immediately before a component transform is applied to a + # simple glyph's coordinates in case these might still contain floats; + # however, if the referenced component glyph is another composite, we + # must not round here but only at the end, after all the nested + # transforms have been applied, or else rounding errors will compound. + if round is not noRound and g.numberOfContours > 0: + coordinates.toInt(round=round) + if hasattr(compo, "firstPt"): + # component uses two reference points: we apply the transform _before_ + # computing the offset between the points + if hasattr(compo, "transform"): + coordinates.transform(compo.transform) + x1, y1 = allCoords[compo.firstPt] + x2, y2 = coordinates[compo.secondPt] + move = x1 - x2, y1 - y2 + coordinates.translate(move) + else: + # component uses XY offsets + move = compo.x, compo.y + if not hasattr(compo, "transform"): + coordinates.translate(move) + else: + apple_way = compo.flags & SCALED_COMPONENT_OFFSET + ms_way = compo.flags & UNSCALED_COMPONENT_OFFSET + assert not (apple_way and ms_way) + if not (apple_way or ms_way): + scale_component_offset = ( + SCALE_COMPONENT_OFFSET_DEFAULT # see top of this file + ) + else: + scale_component_offset = apple_way + if scale_component_offset: + # the Apple way: first move, then scale (ie. scale the component offset) + coordinates.translate(move) + coordinates.transform(compo.transform) + else: + # the MS way: first scale, then move + coordinates.transform(compo.transform) + coordinates.translate(move) + offset = len(allCoords) + allEndPts.extend(e + offset for e in endPts) + allCoords.extend(coordinates) + allFlags.extend(flags) + return allCoords, allEndPts, allFlags + else: + return GlyphCoordinates(), [], bytearray() + + def getComponentNames(self, glyfTable): + """Returns a list of names of component glyphs used in this glyph + + This method can be used on simple glyphs (in which case it returns an + empty list) or composite glyphs. + """ + if not hasattr(self, "data"): + if self.isComposite(): + return [c.glyphName for c in self.components] + else: + return [] + + # Extract components without expanding glyph + + if not self.data or struct.unpack(">h", self.data[:2])[0] >= 0: + return [] # Not composite + + data = self.data + i = 10 + components = [] + more = 1 + while more: + flags, glyphID = struct.unpack(">HH", data[i : i + 4]) + i += 4 + flags = int(flags) + components.append(glyfTable.getGlyphName(int(glyphID))) + + if flags & ARG_1_AND_2_ARE_WORDS: + i += 4 + else: + i += 2 + if flags & WE_HAVE_A_SCALE: + i += 2 + elif flags & WE_HAVE_AN_X_AND_Y_SCALE: + i += 4 + elif flags & WE_HAVE_A_TWO_BY_TWO: + i += 8 + more = flags & MORE_COMPONENTS + + return components + + def trim(self, remove_hinting=False): + """Remove padding and, if requested, hinting, from a glyph. + This works on both expanded and compacted glyphs, without + expanding it.""" + if not hasattr(self, "data"): + if remove_hinting: + if self.isComposite(): + if hasattr(self, "program"): + del self.program + else: + self.program = ttProgram.Program() + self.program.fromBytecode([]) + # No padding to trim. + return + if not self.data: + return + numContours = struct.unpack(">h", self.data[:2])[0] + data = bytearray(self.data) + i = 10 + if numContours >= 0: + i += 2 * numContours # endPtsOfContours + nCoordinates = ((data[i - 2] << 8) | data[i - 1]) + 1 + instructionLen = (data[i] << 8) | data[i + 1] + if remove_hinting: + # Zero instruction length + data[i] = data[i + 1] = 0 + i += 2 + if instructionLen: + # Splice it out + data = data[:i] + data[i + instructionLen :] + instructionLen = 0 + else: + i += 2 + instructionLen + + coordBytes = 0 + j = 0 + while True: + flag = data[i] + i = i + 1 + repeat = 1 + if flag & flagRepeat: + repeat = data[i] + 1 + i = i + 1 + xBytes = yBytes = 0 + if flag & flagXShort: + xBytes = 1 + elif not (flag & flagXsame): + xBytes = 2 + if flag & flagYShort: + yBytes = 1 + elif not (flag & flagYsame): + yBytes = 2 + coordBytes += (xBytes + yBytes) * repeat + j += repeat + if j >= nCoordinates: + break + assert j == nCoordinates, "bad glyph flags" + i += coordBytes + # Remove padding + data = data[:i] + elif self.isComposite(): + more = 1 + we_have_instructions = False + while more: + flags = (data[i] << 8) | data[i + 1] + if remove_hinting: + flags &= ~WE_HAVE_INSTRUCTIONS + if flags & WE_HAVE_INSTRUCTIONS: + we_have_instructions = True + data[i + 0] = flags >> 8 + data[i + 1] = flags & 0xFF + i += 4 + flags = int(flags) + + if flags & ARG_1_AND_2_ARE_WORDS: + i += 4 + else: + i += 2 + if flags & WE_HAVE_A_SCALE: + i += 2 + elif flags & WE_HAVE_AN_X_AND_Y_SCALE: + i += 4 + elif flags & WE_HAVE_A_TWO_BY_TWO: + i += 8 + more = flags & MORE_COMPONENTS + if we_have_instructions: + instructionLen = (data[i] << 8) | data[i + 1] + i += 2 + instructionLen + # Remove padding + data = data[:i] + + self.data = data + + def removeHinting(self): + """Removes TrueType hinting instructions from the glyph.""" + self.trim(remove_hinting=True) + + def draw(self, pen, glyfTable, offset=0): + """Draws the glyph using the supplied pen object. + + Arguments: + pen: An object conforming to the pen protocol. + glyfTable: A :py:class:`table__g_l_y_f` object, to resolve components. + offset (int): A horizontal offset. If provided, all coordinates are + translated by this offset. + """ + + if self.isComposite(): + for component in self.components: + glyphName, transform = component.getComponentInfo() + pen.addComponent(glyphName, transform) + return + + self.expand(glyfTable) + coordinates, endPts, flags = self.getCoordinates(glyfTable) + if offset: + coordinates = coordinates.copy() + coordinates.translate((offset, 0)) + start = 0 + maybeInt = lambda v: int(v) if v == int(v) else v + for end in endPts: + end = end + 1 + contour = coordinates[start:end] + cFlags = [flagOnCurve & f for f in flags[start:end]] + cuFlags = [flagCubic & f for f in flags[start:end]] + start = end + if 1 not in cFlags: + assert all(cuFlags) or not any(cuFlags) + cubic = all(cuFlags) + if cubic: + count = len(contour) + assert count % 2 == 0, "Odd number of cubic off-curves undefined" + l = contour[-1] + f = contour[0] + p0 = (maybeInt((l[0] + f[0]) * 0.5), maybeInt((l[1] + f[1]) * 0.5)) + pen.moveTo(p0) + for i in range(0, count, 2): + p1 = contour[i] + p2 = contour[i + 1] + p4 = contour[i + 2 if i + 2 < count else 0] + p3 = ( + maybeInt((p2[0] + p4[0]) * 0.5), + maybeInt((p2[1] + p4[1]) * 0.5), + ) + pen.curveTo(p1, p2, p3) + else: + # There is not a single on-curve point on the curve, + # use pen.qCurveTo's special case by specifying None + # as the on-curve point. + contour.append(None) + pen.qCurveTo(*contour) + else: + # Shuffle the points so that the contour is guaranteed + # to *end* in an on-curve point, which we'll use for + # the moveTo. + firstOnCurve = cFlags.index(1) + 1 + contour = contour[firstOnCurve:] + contour[:firstOnCurve] + cFlags = cFlags[firstOnCurve:] + cFlags[:firstOnCurve] + cuFlags = cuFlags[firstOnCurve:] + cuFlags[:firstOnCurve] + pen.moveTo(contour[-1]) + while contour: + nextOnCurve = cFlags.index(1) + 1 + if nextOnCurve == 1: + # Skip a final lineTo(), as it is implied by + # pen.closePath() + if len(contour) > 1: + pen.lineTo(contour[0]) + else: + cubicFlags = [f for f in cuFlags[: nextOnCurve - 1]] + assert all(cubicFlags) or not any(cubicFlags) + cubic = any(cubicFlags) + if cubic: + assert all( + cubicFlags + ), "Mixed cubic and quadratic segment undefined" + + count = nextOnCurve + assert ( + count >= 3 + ), "At least two cubic off-curve points required" + assert ( + count - 1 + ) % 2 == 0, "Odd number of cubic off-curves undefined" + for i in range(0, count - 3, 2): + p1 = contour[i] + p2 = contour[i + 1] + p4 = contour[i + 2] + p3 = ( + maybeInt((p2[0] + p4[0]) * 0.5), + maybeInt((p2[1] + p4[1]) * 0.5), + ) + lastOnCurve = p3 + pen.curveTo(p1, p2, p3) + pen.curveTo(*contour[count - 3 : count]) + else: + pen.qCurveTo(*contour[:nextOnCurve]) + contour = contour[nextOnCurve:] + cFlags = cFlags[nextOnCurve:] + cuFlags = cuFlags[nextOnCurve:] + pen.closePath() + + def drawPoints(self, pen, glyfTable, offset=0): + """Draw the glyph using the supplied pointPen. As opposed to Glyph.draw(), + this will not change the point indices. + """ + + if self.isComposite(): + for component in self.components: + glyphName, transform = component.getComponentInfo() + pen.addComponent(glyphName, transform) + return + + coordinates, endPts, flags = self.getCoordinates(glyfTable) + if offset: + coordinates = coordinates.copy() + coordinates.translate((offset, 0)) + start = 0 + for end in endPts: + end = end + 1 + contour = coordinates[start:end] + cFlags = flags[start:end] + start = end + pen.beginPath() + # Start with the appropriate segment type based on the final segment + + if cFlags[-1] & flagOnCurve: + segmentType = "line" + elif cFlags[-1] & flagCubic: + segmentType = "curve" + else: + segmentType = "qcurve" + for i, pt in enumerate(contour): + if cFlags[i] & flagOnCurve: + pen.addPoint(pt, segmentType=segmentType) + segmentType = "line" + else: + pen.addPoint(pt) + segmentType = "curve" if cFlags[i] & flagCubic else "qcurve" + pen.endPath() + + def __eq__(self, other): + if type(self) != type(other): + return NotImplemented + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + result = self.__eq__(other) + return result if result is NotImplemented else not result + + +# Vector.__round__ uses the built-in (Banker's) `round` but we want +# to use otRound below +_roundv = partial(Vector.__round__, round=otRound) + + +def _is_mid_point(p0: tuple, p1: tuple, p2: tuple) -> bool: + # True if p1 is in the middle of p0 and p2, either before or after rounding + p0 = Vector(p0) + p1 = Vector(p1) + p2 = Vector(p2) + return ((p0 + p2) * 0.5).isclose(p1) or _roundv(p0) + _roundv(p2) == _roundv(p1) * 2 + + +def dropImpliedOnCurvePoints(*interpolatable_glyphs: Glyph) -> Set[int]: + """Drop impliable on-curve points from the (simple) glyph or glyphs. + + In TrueType glyf outlines, on-curve points can be implied when they are located at + the midpoint of the line connecting two consecutive off-curve points. + + If more than one glyphs are passed, these are assumed to be interpolatable masters + of the same glyph impliable, and thus only the on-curve points that are impliable + for all of them will actually be implied. + Composite glyphs or empty glyphs are skipped, only simple glyphs with 1 or more + contours are considered. + The input glyph(s) is/are modified in-place. + + Args: + interpolatable_glyphs: The glyph or glyphs to modify in-place. + + Returns: + The set of point indices that were dropped if any. + + Raises: + ValueError if simple glyphs are not in fact interpolatable because they have + different point flags or number of contours. + + Reference: + https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html + """ + staticAttributes = SimpleNamespace( + numberOfContours=None, flags=None, endPtsOfContours=None + ) + drop = None + simple_glyphs = [] + for i, glyph in enumerate(interpolatable_glyphs): + if glyph.numberOfContours < 1: + # ignore composite or empty glyphs + continue + + for attr in staticAttributes.__dict__: + expected = getattr(staticAttributes, attr) + found = getattr(glyph, attr) + if expected is None: + setattr(staticAttributes, attr, found) + elif expected != found: + raise ValueError( + f"Incompatible {attr} for glyph at master index {i}: " + f"expected {expected}, found {found}" + ) + + may_drop = set() + start = 0 + coords = glyph.coordinates + flags = staticAttributes.flags + endPtsOfContours = staticAttributes.endPtsOfContours + for last in endPtsOfContours: + for i in range(start, last + 1): + if not (flags[i] & flagOnCurve): + continue + prv = i - 1 if i > start else last + nxt = i + 1 if i < last else start + if (flags[prv] & flagOnCurve) or flags[prv] != flags[nxt]: + continue + # we may drop the ith on-curve if halfway between previous/next off-curves + if not _is_mid_point(coords[prv], coords[i], coords[nxt]): + continue + + may_drop.add(i) + start = last + 1 + # we only want to drop if ALL interpolatable glyphs have the same implied oncurves + if drop is None: + drop = may_drop + else: + drop.intersection_update(may_drop) + + simple_glyphs.append(glyph) + + if drop: + # Do the actual dropping + flags = staticAttributes.flags + assert flags is not None + newFlags = array.array( + "B", (flags[i] for i in range(len(flags)) if i not in drop) + ) + + endPts = staticAttributes.endPtsOfContours + assert endPts is not None + newEndPts = [] + i = 0 + delta = 0 + for d in sorted(drop): + while d > endPts[i]: + newEndPts.append(endPts[i] - delta) + i += 1 + delta += 1 + while i < len(endPts): + newEndPts.append(endPts[i] - delta) + i += 1 + + for glyph in simple_glyphs: + coords = glyph.coordinates + glyph.coordinates = GlyphCoordinates( + coords[i] for i in range(len(coords)) if i not in drop + ) + glyph.flags = newFlags + glyph.endPtsOfContours = newEndPts + + return drop if drop is not None else set() + + +class GlyphComponent(object): + """Represents a component within a composite glyph. + + The component is represented internally with four attributes: ``glyphName``, + ``x``, ``y`` and ``transform``. If there is no "two-by-two" matrix (i.e + no scaling, reflection, or rotation; only translation), the ``transform`` + attribute is not present. + """ + + # The above documentation is not *completely* true, but is *true enough* because + # the rare firstPt/lastPt attributes are not totally supported and nobody seems to + # mind - see below. + + def __init__(self): + pass + + def getComponentInfo(self): + """Return information about the component + + This method returns a tuple of two values: the glyph name of the component's + base glyph, and a transformation matrix. As opposed to accessing the attributes + directly, ``getComponentInfo`` always returns a six-element tuple of the + component's transformation matrix, even when the two-by-two ``.transform`` + matrix is not present. + """ + # XXX Ignoring self.firstPt & self.lastpt for now: I need to implement + # something equivalent in fontTools.objects.glyph (I'd rather not + # convert it to an absolute offset, since it is valuable information). + # This method will now raise "AttributeError: x" on glyphs that use + # this TT feature. + if hasattr(self, "transform"): + [[xx, xy], [yx, yy]] = self.transform + trans = (xx, xy, yx, yy, self.x, self.y) + else: + trans = (1, 0, 0, 1, self.x, self.y) + return self.glyphName, trans + + def decompile(self, data, glyfTable): + flags, glyphID = struct.unpack(">HH", data[:4]) + self.flags = int(flags) + glyphID = int(glyphID) + self.glyphName = glyfTable.getGlyphName(int(glyphID)) + data = data[4:] + + if self.flags & ARG_1_AND_2_ARE_WORDS: + if self.flags & ARGS_ARE_XY_VALUES: + self.x, self.y = struct.unpack(">hh", data[:4]) + else: + x, y = struct.unpack(">HH", data[:4]) + self.firstPt, self.secondPt = int(x), int(y) + data = data[4:] + else: + if self.flags & ARGS_ARE_XY_VALUES: + self.x, self.y = struct.unpack(">bb", data[:2]) + else: + x, y = struct.unpack(">BB", data[:2]) + self.firstPt, self.secondPt = int(x), int(y) + data = data[2:] + + if self.flags & WE_HAVE_A_SCALE: + (scale,) = struct.unpack(">h", data[:2]) + self.transform = [ + [fi2fl(scale, 14), 0], + [0, fi2fl(scale, 14)], + ] # fixed 2.14 + data = data[2:] + elif self.flags & WE_HAVE_AN_X_AND_Y_SCALE: + xscale, yscale = struct.unpack(">hh", data[:4]) + self.transform = [ + [fi2fl(xscale, 14), 0], + [0, fi2fl(yscale, 14)], + ] # fixed 2.14 + data = data[4:] + elif self.flags & WE_HAVE_A_TWO_BY_TWO: + (xscale, scale01, scale10, yscale) = struct.unpack(">hhhh", data[:8]) + self.transform = [ + [fi2fl(xscale, 14), fi2fl(scale01, 14)], + [fi2fl(scale10, 14), fi2fl(yscale, 14)], + ] # fixed 2.14 + data = data[8:] + more = self.flags & MORE_COMPONENTS + haveInstructions = self.flags & WE_HAVE_INSTRUCTIONS + self.flags = self.flags & ( + ROUND_XY_TO_GRID + | USE_MY_METRICS + | SCALED_COMPONENT_OFFSET + | UNSCALED_COMPONENT_OFFSET + | NON_OVERLAPPING + | OVERLAP_COMPOUND + ) + return more, haveInstructions, data + + def compile(self, more, haveInstructions, glyfTable): + data = b"" + + # reset all flags we will calculate ourselves + flags = self.flags & ( + ROUND_XY_TO_GRID + | USE_MY_METRICS + | SCALED_COMPONENT_OFFSET + | UNSCALED_COMPONENT_OFFSET + | NON_OVERLAPPING + | OVERLAP_COMPOUND + ) + if more: + flags = flags | MORE_COMPONENTS + if haveInstructions: + flags = flags | WE_HAVE_INSTRUCTIONS + + if hasattr(self, "firstPt"): + if (0 <= self.firstPt <= 255) and (0 <= self.secondPt <= 255): + data = data + struct.pack(">BB", self.firstPt, self.secondPt) + else: + data = data + struct.pack(">HH", self.firstPt, self.secondPt) + flags = flags | ARG_1_AND_2_ARE_WORDS + else: + x = otRound(self.x) + y = otRound(self.y) + flags = flags | ARGS_ARE_XY_VALUES + if (-128 <= x <= 127) and (-128 <= y <= 127): + data = data + struct.pack(">bb", x, y) + else: + data = data + struct.pack(">hh", x, y) + flags = flags | ARG_1_AND_2_ARE_WORDS + + if hasattr(self, "transform"): + transform = [[fl2fi(x, 14) for x in row] for row in self.transform] + if transform[0][1] or transform[1][0]: + flags = flags | WE_HAVE_A_TWO_BY_TWO + data = data + struct.pack( + ">hhhh", + transform[0][0], + transform[0][1], + transform[1][0], + transform[1][1], + ) + elif transform[0][0] != transform[1][1]: + flags = flags | WE_HAVE_AN_X_AND_Y_SCALE + data = data + struct.pack(">hh", transform[0][0], transform[1][1]) + else: + flags = flags | WE_HAVE_A_SCALE + data = data + struct.pack(">h", transform[0][0]) + + glyphID = glyfTable.getGlyphID(self.glyphName) + return struct.pack(">HH", flags, glyphID) + data + + def toXML(self, writer, ttFont): + attrs = [("glyphName", self.glyphName)] + if not hasattr(self, "firstPt"): + attrs = attrs + [("x", self.x), ("y", self.y)] + else: + attrs = attrs + [("firstPt", self.firstPt), ("secondPt", self.secondPt)] + + if hasattr(self, "transform"): + transform = self.transform + if transform[0][1] or transform[1][0]: + attrs = attrs + [ + ("scalex", fl2str(transform[0][0], 14)), + ("scale01", fl2str(transform[0][1], 14)), + ("scale10", fl2str(transform[1][0], 14)), + ("scaley", fl2str(transform[1][1], 14)), + ] + elif transform[0][0] != transform[1][1]: + attrs = attrs + [ + ("scalex", fl2str(transform[0][0], 14)), + ("scaley", fl2str(transform[1][1], 14)), + ] + else: + attrs = attrs + [("scale", fl2str(transform[0][0], 14))] + attrs = attrs + [("flags", hex(self.flags))] + writer.simpletag("component", attrs) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + self.glyphName = attrs["glyphName"] + if "firstPt" in attrs: + self.firstPt = safeEval(attrs["firstPt"]) + self.secondPt = safeEval(attrs["secondPt"]) + else: + self.x = safeEval(attrs["x"]) + self.y = safeEval(attrs["y"]) + if "scale01" in attrs: + scalex = str2fl(attrs["scalex"], 14) + scale01 = str2fl(attrs["scale01"], 14) + scale10 = str2fl(attrs["scale10"], 14) + scaley = str2fl(attrs["scaley"], 14) + self.transform = [[scalex, scale01], [scale10, scaley]] + elif "scalex" in attrs: + scalex = str2fl(attrs["scalex"], 14) + scaley = str2fl(attrs["scaley"], 14) + self.transform = [[scalex, 0], [0, scaley]] + elif "scale" in attrs: + scale = str2fl(attrs["scale"], 14) + self.transform = [[scale, 0], [0, scale]] + self.flags = safeEval(attrs["flags"]) + + def __eq__(self, other): + if type(self) != type(other): + return NotImplemented + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + result = self.__eq__(other) + return result if result is NotImplemented else not result + + def _hasOnlyIntegerTranslate(self): + """Return True if it's a 'simple' component. + + That is, it has no anchor points and no transform other than integer translate. + """ + return ( + not hasattr(self, "firstPt") + and not hasattr(self, "transform") + and float(self.x).is_integer() + and float(self.y).is_integer() + ) + + +class GlyphCoordinates(object): + """A list of glyph coordinates. + + Unlike an ordinary list, this is a numpy-like matrix object which supports + matrix addition, scalar multiplication and other operations described below. + """ + + def __init__(self, iterable=[]): + self._a = array.array("d") + self.extend(iterable) + + @property + def array(self): + """Returns the underlying array of coordinates""" + return self._a + + @staticmethod + def zeros(count): + """Creates a new ``GlyphCoordinates`` object with all coordinates set to (0,0)""" + g = GlyphCoordinates() + g._a.frombytes(bytes(count * 2 * g._a.itemsize)) + return g + + def copy(self): + """Creates a new ``GlyphCoordinates`` object which is a copy of the current one.""" + c = GlyphCoordinates() + c._a.extend(self._a) + return c + + def __len__(self): + """Returns the number of coordinates in the array.""" + return len(self._a) // 2 + + def __getitem__(self, k): + """Returns a two element tuple (x,y)""" + a = self._a + if isinstance(k, slice): + indices = range(*k.indices(len(self))) + # Instead of calling ourselves recursively, duplicate code; faster + ret = [] + for k in indices: + x = a[2 * k] + y = a[2 * k + 1] + ret.append( + (int(x) if x.is_integer() else x, int(y) if y.is_integer() else y) + ) + return ret + x = a[2 * k] + y = a[2 * k + 1] + return (int(x) if x.is_integer() else x, int(y) if y.is_integer() else y) + + def __setitem__(self, k, v): + """Sets a point's coordinates to a two element tuple (x,y)""" + if isinstance(k, slice): + indices = range(*k.indices(len(self))) + # XXX This only works if len(v) == len(indices) + for j, i in enumerate(indices): + self[i] = v[j] + return + self._a[2 * k], self._a[2 * k + 1] = v + + def __delitem__(self, i): + """Removes a point from the list""" + i = (2 * i) % len(self._a) + del self._a[i] + del self._a[i] + + def __repr__(self): + return "GlyphCoordinates([" + ",".join(str(c) for c in self) + "])" + + def append(self, p): + self._a.extend(tuple(p)) + + def extend(self, iterable): + for p in iterable: + self._a.extend(p) + + def toInt(self, *, round=otRound): + if round is noRound: + return + a = self._a + for i, value in enumerate(a): + a[i] = round(value) + + def calcBounds(self): + a = self._a + if not a: + return 0, 0, 0, 0 + xs = a[0::2] + ys = a[1::2] + return min(xs), min(ys), max(xs), max(ys) + + def calcIntBounds(self, round=otRound): + return tuple(round(v) for v in self.calcBounds()) + + def relativeToAbsolute(self): + a = self._a + x, y = 0, 0 + for i in range(0, len(a), 2): + a[i] = x = a[i] + x + a[i + 1] = y = a[i + 1] + y + + def absoluteToRelative(self): + a = self._a + x, y = 0, 0 + for i in range(0, len(a), 2): + nx = a[i] + ny = a[i + 1] + a[i] = nx - x + a[i + 1] = ny - y + x = nx + y = ny + + def translate(self, p): + """ + >>> GlyphCoordinates([(1,2)]).translate((.5,0)) + """ + x, y = p + if x == 0 and y == 0: + return + a = self._a + for i in range(0, len(a), 2): + a[i] += x + a[i + 1] += y + + def scale(self, p): + """ + >>> GlyphCoordinates([(1,2)]).scale((.5,0)) + """ + x, y = p + if x == 1 and y == 1: + return + a = self._a + for i in range(0, len(a), 2): + a[i] *= x + a[i + 1] *= y + + def transform(self, t): + """ + >>> GlyphCoordinates([(1,2)]).transform(((.5,0),(.2,.5))) + """ + a = self._a + for i in range(0, len(a), 2): + x = a[i] + y = a[i + 1] + px = x * t[0][0] + y * t[1][0] + py = x * t[0][1] + y * t[1][1] + a[i] = px + a[i + 1] = py + + def __eq__(self, other): + """ + >>> g = GlyphCoordinates([(1,2)]) + >>> g2 = GlyphCoordinates([(1.0,2)]) + >>> g3 = GlyphCoordinates([(1.5,2)]) + >>> g == g2 + True + >>> g == g3 + False + >>> g2 == g3 + False + """ + if type(self) != type(other): + return NotImplemented + return self._a == other._a + + def __ne__(self, other): + """ + >>> g = GlyphCoordinates([(1,2)]) + >>> g2 = GlyphCoordinates([(1.0,2)]) + >>> g3 = GlyphCoordinates([(1.5,2)]) + >>> g != g2 + False + >>> g != g3 + True + >>> g2 != g3 + True + """ + result = self.__eq__(other) + return result if result is NotImplemented else not result + + # Math operations + + def __pos__(self): + """ + >>> g = GlyphCoordinates([(1,2)]) + >>> g + GlyphCoordinates([(1, 2)]) + >>> g2 = +g + >>> g2 + GlyphCoordinates([(1, 2)]) + >>> g2.translate((1,0)) + >>> g2 + GlyphCoordinates([(2, 2)]) + >>> g + GlyphCoordinates([(1, 2)]) + """ + return self.copy() + + def __neg__(self): + """ + >>> g = GlyphCoordinates([(1,2)]) + >>> g + GlyphCoordinates([(1, 2)]) + >>> g2 = -g + >>> g2 + GlyphCoordinates([(-1, -2)]) + >>> g + GlyphCoordinates([(1, 2)]) + """ + r = self.copy() + a = r._a + for i, value in enumerate(a): + a[i] = -value + return r + + def __round__(self, *, round=otRound): + r = self.copy() + r.toInt(round=round) + return r + + def __add__(self, other): + return self.copy().__iadd__(other) + + def __sub__(self, other): + return self.copy().__isub__(other) + + def __mul__(self, other): + return self.copy().__imul__(other) + + def __truediv__(self, other): + return self.copy().__itruediv__(other) + + __radd__ = __add__ + __rmul__ = __mul__ + + def __rsub__(self, other): + return other + (-self) + + def __iadd__(self, other): + """ + >>> g = GlyphCoordinates([(1,2)]) + >>> g += (.5,0) + >>> g + GlyphCoordinates([(1.5, 2)]) + >>> g2 = GlyphCoordinates([(3,4)]) + >>> g += g2 + >>> g + GlyphCoordinates([(4.5, 6)]) + """ + if isinstance(other, tuple): + assert len(other) == 2 + self.translate(other) + return self + if isinstance(other, GlyphCoordinates): + other = other._a + a = self._a + assert len(a) == len(other) + for i, value in enumerate(other): + a[i] += value + return self + return NotImplemented + + def __isub__(self, other): + """ + >>> g = GlyphCoordinates([(1,2)]) + >>> g -= (.5,0) + >>> g + GlyphCoordinates([(0.5, 2)]) + >>> g2 = GlyphCoordinates([(3,4)]) + >>> g -= g2 + >>> g + GlyphCoordinates([(-2.5, -2)]) + """ + if isinstance(other, tuple): + assert len(other) == 2 + self.translate((-other[0], -other[1])) + return self + if isinstance(other, GlyphCoordinates): + other = other._a + a = self._a + assert len(a) == len(other) + for i, value in enumerate(other): + a[i] -= value + return self + return NotImplemented + + def __imul__(self, other): + """ + >>> g = GlyphCoordinates([(1,2)]) + >>> g *= (2,.5) + >>> g *= 2 + >>> g + GlyphCoordinates([(4, 2)]) + >>> g = GlyphCoordinates([(1,2)]) + >>> g *= 2 + >>> g + GlyphCoordinates([(2, 4)]) + """ + if isinstance(other, tuple): + assert len(other) == 2 + self.scale(other) + return self + if isinstance(other, Number): + if other == 1: + return self + a = self._a + for i in range(len(a)): + a[i] *= other + return self + return NotImplemented + + def __itruediv__(self, other): + """ + >>> g = GlyphCoordinates([(1,3)]) + >>> g /= (.5,1.5) + >>> g /= 2 + >>> g + GlyphCoordinates([(1, 1)]) + """ + if isinstance(other, Number): + other = (other, other) + if isinstance(other, tuple): + if other == (1, 1): + return self + assert len(other) == 2 + self.scale((1.0 / other[0], 1.0 / other[1])) + return self + return NotImplemented + + def __bool__(self): + """ + >>> g = GlyphCoordinates([]) + >>> bool(g) + False + >>> g = GlyphCoordinates([(0,0), (0.,0)]) + >>> bool(g) + True + >>> g = GlyphCoordinates([(0,0), (1,0)]) + >>> bool(g) + True + >>> g = GlyphCoordinates([(0,.5), (0,0)]) + >>> bool(g) + True + """ + return bool(self._a) + + __nonzero__ = __bool__ + + +if __name__ == "__main__": + import doctest, sys + + sys.exit(doctest.testmod().failed) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_g_v_a_r.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_g_v_a_r.py new file mode 100644 index 0000000000000000000000000000000000000000..15cc6fab5bd1b92fa0f778eb6d9952b195843786 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_g_v_a_r.py @@ -0,0 +1,340 @@ +from collections import deque +from functools import partial +from fontTools.misc import sstruct +from fontTools.misc.textTools import safeEval +from fontTools.misc.lazyTools import LazyDict +from fontTools.ttLib import OPTIMIZE_FONT_SPEED +from fontTools.ttLib.tables.TupleVariation import TupleVariation +from . import DefaultTable +import array +import itertools +import logging +import struct +import sys +import fontTools.ttLib.tables.TupleVariation as tv + +log = logging.getLogger(__name__) + +# https://www.microsoft.com/typography/otspec/gvar.htm +# https://www.microsoft.com/typography/otspec/otvarcommonformats.htm +# +# Apple's documentation of 'gvar': +# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6gvar.html +# +# FreeType2 source code for parsing 'gvar': +# http://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/src/truetype/ttgxvar.c + +GVAR_HEADER_FORMAT_HEAD = """ + > # big endian + version: H + reserved: H + axisCount: H + sharedTupleCount: H + offsetToSharedTuples: I +""" +# In between the HEAD and TAIL lies the glyphCount, which is +# of different size: 2 bytes for gvar, and 3 bytes for GVAR. +GVAR_HEADER_FORMAT_TAIL = """ + > # big endian + flags: H + offsetToGlyphVariationData: I +""" + +GVAR_HEADER_SIZE_HEAD = sstruct.calcsize(GVAR_HEADER_FORMAT_HEAD) +GVAR_HEADER_SIZE_TAIL = sstruct.calcsize(GVAR_HEADER_FORMAT_TAIL) + + +class table__g_v_a_r(DefaultTable.DefaultTable): + """Glyph Variations table + + The ``gvar`` table provides the per-glyph variation data that + describe how glyph outlines in the ``glyf`` table change across + the variation space that is defined for the font in the ``fvar`` + table. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/gvar + """ + + dependencies = ["fvar", "glyf"] + gid_size = 2 + + def __init__(self, tag=None): + DefaultTable.DefaultTable.__init__(self, tag) + self.version, self.reserved = 1, 0 + self.variations = {} + + def compile(self, ttFont): + axisTags = [axis.axisTag for axis in ttFont["fvar"].axes] + sharedTuples = tv.compileSharedTuples( + axisTags, itertools.chain(*self.variations.values()) + ) + sharedTupleIndices = {coord: i for i, coord in enumerate(sharedTuples)} + sharedTupleSize = sum([len(c) for c in sharedTuples]) + compiledGlyphs = self.compileGlyphs_(ttFont, axisTags, sharedTupleIndices) + offset = 0 + offsets = [] + for glyph in compiledGlyphs: + offsets.append(offset) + offset += len(glyph) + offsets.append(offset) + compiledOffsets, tableFormat = self.compileOffsets_(offsets) + + GVAR_HEADER_SIZE = GVAR_HEADER_SIZE_HEAD + self.gid_size + GVAR_HEADER_SIZE_TAIL + header = {} + header["version"] = self.version + header["reserved"] = self.reserved + header["axisCount"] = len(axisTags) + header["sharedTupleCount"] = len(sharedTuples) + header["offsetToSharedTuples"] = GVAR_HEADER_SIZE + len(compiledOffsets) + header["flags"] = tableFormat + header["offsetToGlyphVariationData"] = ( + header["offsetToSharedTuples"] + sharedTupleSize + ) + + result = [ + sstruct.pack(GVAR_HEADER_FORMAT_HEAD, header), + len(compiledGlyphs).to_bytes(self.gid_size, "big"), + sstruct.pack(GVAR_HEADER_FORMAT_TAIL, header), + ] + + result.append(compiledOffsets) + result.extend(sharedTuples) + result.extend(compiledGlyphs) + return b"".join(result) + + def compileGlyphs_(self, ttFont, axisTags, sharedCoordIndices): + optimizeSpeed = ttFont.cfg[OPTIMIZE_FONT_SPEED] + result = [] + glyf = ttFont["glyf"] + for glyphName in ttFont.getGlyphOrder(): + variations = self.variations.get(glyphName, []) + if not variations: + result.append(b"") + continue + pointCountUnused = 0 # pointCount is actually unused by compileGlyph + result.append( + compileGlyph_( + self.gid_size, + variations, + pointCountUnused, + axisTags, + sharedCoordIndices, + optimizeSize=not optimizeSpeed, + ) + ) + return result + + def decompile(self, data, ttFont): + axisTags = [axis.axisTag for axis in ttFont["fvar"].axes] + glyphs = ttFont.getGlyphOrder() + + # Parse the header + GVAR_HEADER_SIZE = GVAR_HEADER_SIZE_HEAD + self.gid_size + GVAR_HEADER_SIZE_TAIL + sstruct.unpack(GVAR_HEADER_FORMAT_HEAD, data[:GVAR_HEADER_SIZE_HEAD], self) + self.glyphCount = int.from_bytes( + data[GVAR_HEADER_SIZE_HEAD : GVAR_HEADER_SIZE_HEAD + self.gid_size], "big" + ) + sstruct.unpack( + GVAR_HEADER_FORMAT_TAIL, + data[GVAR_HEADER_SIZE_HEAD + self.gid_size : GVAR_HEADER_SIZE], + self, + ) + + assert len(glyphs) == self.glyphCount, (len(glyphs), self.glyphCount) + assert len(axisTags) == self.axisCount, ( + len(axisTags), + self.axisCount, + axisTags, + ) + sharedCoords = tv.decompileSharedTuples( + axisTags, self.sharedTupleCount, data, self.offsetToSharedTuples + ) + variations = {} + offsetToData = self.offsetToGlyphVariationData + glyf = ttFont["glyf"] + + def get_read_item(): + reverseGlyphMap = ttFont.getReverseGlyphMap() + tableFormat = self.flags & 1 + + def read_item(glyphName): + gid = reverseGlyphMap[glyphName] + offsetSize = 2 if tableFormat == 0 else 4 + startOffset = GVAR_HEADER_SIZE + offsetSize * gid + endOffset = startOffset + offsetSize * 2 + offsets = table__g_v_a_r.decompileOffsets_( + data[startOffset:endOffset], + tableFormat=tableFormat, + glyphCount=1, + ) + gvarData = data[offsetToData + offsets[0] : offsetToData + offsets[1]] + if not gvarData: + return [] + glyph = glyf[glyphName] + numPointsInGlyph = self.getNumPoints_(glyph) + return decompileGlyph_( + self.gid_size, numPointsInGlyph, sharedCoords, axisTags, gvarData + ) + + return read_item + + read_item = get_read_item() + l = LazyDict({glyphs[gid]: read_item for gid in range(self.glyphCount)}) + + self.variations = l + + if ttFont.lazy is False: # Be lazy for None and True + self.ensureDecompiled() + + def ensureDecompiled(self, recurse=False): + # The recurse argument is unused, but part of the signature of + # ensureDecompiled across the library. + # Use a zero-length deque to consume the lazy dict + deque(self.variations.values(), maxlen=0) + + @staticmethod + def decompileOffsets_(data, tableFormat, glyphCount): + if tableFormat == 0: + # Short format: array of UInt16 + offsets = array.array("H") + offsetsSize = (glyphCount + 1) * 2 + else: + # Long format: array of UInt32 + offsets = array.array("I") + offsetsSize = (glyphCount + 1) * 4 + offsets.frombytes(data[0:offsetsSize]) + if sys.byteorder != "big": + offsets.byteswap() + + # In the short format, offsets need to be multiplied by 2. + # This is not documented in Apple's TrueType specification, + # but can be inferred from the FreeType implementation, and + # we could verify it with two sample GX fonts. + if tableFormat == 0: + offsets = [off * 2 for off in offsets] + + return offsets + + @staticmethod + def compileOffsets_(offsets): + """Packs a list of offsets into a 'gvar' offset table. + + Returns a pair (bytestring, tableFormat). Bytestring is the + packed offset table. Format indicates whether the table + uses short (tableFormat=0) or long (tableFormat=1) integers. + The returned tableFormat should get packed into the flags field + of the 'gvar' header. + """ + assert len(offsets) >= 2 + for i in range(1, len(offsets)): + assert offsets[i - 1] <= offsets[i] + if max(offsets) <= 0xFFFF * 2: + packed = array.array("H", [n >> 1 for n in offsets]) + tableFormat = 0 + else: + packed = array.array("I", offsets) + tableFormat = 1 + if sys.byteorder != "big": + packed.byteswap() + return (packed.tobytes(), tableFormat) + + def toXML(self, writer, ttFont): + writer.simpletag("version", value=self.version) + writer.newline() + writer.simpletag("reserved", value=self.reserved) + writer.newline() + axisTags = [axis.axisTag for axis in ttFont["fvar"].axes] + for glyphName in ttFont.getGlyphNames(): + variations = self.variations.get(glyphName) + if not variations: + continue + writer.begintag("glyphVariations", glyph=glyphName) + writer.newline() + for gvar in variations: + gvar.toXML(writer, axisTags) + writer.endtag("glyphVariations") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "version": + self.version = safeEval(attrs["value"]) + elif name == "reserved": + self.reserved = safeEval(attrs["value"]) + elif name == "glyphVariations": + if not hasattr(self, "variations"): + self.variations = {} + glyphName = attrs["glyph"] + glyph = ttFont["glyf"][glyphName] + numPointsInGlyph = self.getNumPoints_(glyph) + glyphVariations = [] + for element in content: + if isinstance(element, tuple): + name, attrs, content = element + if name == "tuple": + gvar = TupleVariation({}, [None] * numPointsInGlyph) + glyphVariations.append(gvar) + for tupleElement in content: + if isinstance(tupleElement, tuple): + tupleName, tupleAttrs, tupleContent = tupleElement + gvar.fromXML(tupleName, tupleAttrs, tupleContent) + self.variations[glyphName] = glyphVariations + + @staticmethod + def getNumPoints_(glyph): + NUM_PHANTOM_POINTS = 4 + + if glyph.isComposite(): + return len(glyph.components) + NUM_PHANTOM_POINTS + else: + # Empty glyphs (eg. space, nonmarkingreturn) have no "coordinates" attribute. + return len(getattr(glyph, "coordinates", [])) + NUM_PHANTOM_POINTS + + +def compileGlyph_( + dataOffsetSize, + variations, + pointCount, + axisTags, + sharedCoordIndices, + *, + optimizeSize=True, +): + assert dataOffsetSize in (2, 3) + tupleVariationCount, tuples, data = tv.compileTupleVariationStore( + variations, pointCount, axisTags, sharedCoordIndices, optimizeSize=optimizeSize + ) + if tupleVariationCount == 0: + return b"" + + offsetToData = 2 + dataOffsetSize + len(tuples) + + result = [ + tupleVariationCount.to_bytes(2, "big"), + offsetToData.to_bytes(dataOffsetSize, "big"), + tuples, + data, + ] + if (offsetToData + len(data)) % 2 != 0: + result.append(b"\0") # padding + return b"".join(result) + + +def decompileGlyph_(dataOffsetSize, pointCount, sharedTuples, axisTags, data): + assert dataOffsetSize in (2, 3) + if len(data) < 2 + dataOffsetSize: + return [] + + tupleVariationCount = int.from_bytes(data[:2], "big") + offsetToData = int.from_bytes(data[2 : 2 + dataOffsetSize], "big") + + dataPos = offsetToData + return tv.decompileTupleVariationStore( + "gvar", + axisTags, + tupleVariationCount, + pointCount, + sharedTuples, + data, + 2 + dataOffsetSize, + offsetToData, + ) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_h_d_m_x.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_h_d_m_x.py new file mode 100644 index 0000000000000000000000000000000000000000..07c4566a98dcd36e9b3e2cdc9513793f902d1dd9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_h_d_m_x.py @@ -0,0 +1,127 @@ +from fontTools.misc import sstruct +from fontTools.misc.textTools import bytechr, byteord, strjoin +from . import DefaultTable +import array +from collections.abc import Mapping + +hdmxHeaderFormat = """ + > # big endian! + version: H + numRecords: H + recordSize: l +""" + + +class _GlyphnamedList(Mapping): + def __init__(self, reverseGlyphOrder, data): + self._array = data + self._map = dict(reverseGlyphOrder) + + def __getitem__(self, k): + return self._array[self._map[k]] + + def __len__(self): + return len(self._map) + + def __iter__(self): + return iter(self._map) + + def keys(self): + return self._map.keys() + + +class table__h_d_m_x(DefaultTable.DefaultTable): + """Horizontal Device Metrics table + + The ``hdmx`` table is an optional table that stores advance widths for + glyph outlines at specified pixel sizes. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/hdmx + """ + + def decompile(self, data, ttFont): + numGlyphs = ttFont["maxp"].numGlyphs + glyphOrder = ttFont.getGlyphOrder() + dummy, data = sstruct.unpack2(hdmxHeaderFormat, data, self) + self.hdmx = {} + for i in range(self.numRecords): + ppem = byteord(data[0]) + maxSize = byteord(data[1]) + widths = _GlyphnamedList( + ttFont.getReverseGlyphMap(), array.array("B", data[2 : 2 + numGlyphs]) + ) + self.hdmx[ppem] = widths + data = data[self.recordSize :] + assert len(data) == 0, "too much hdmx data" + + def compile(self, ttFont): + self.version = 0 + numGlyphs = ttFont["maxp"].numGlyphs + glyphOrder = ttFont.getGlyphOrder() + self.recordSize = 4 * ((2 + numGlyphs + 3) // 4) + pad = (self.recordSize - 2 - numGlyphs) * b"\0" + self.numRecords = len(self.hdmx) + data = sstruct.pack(hdmxHeaderFormat, self) + items = sorted(self.hdmx.items()) + for ppem, widths in items: + data = data + bytechr(ppem) + bytechr(max(widths.values())) + for glyphName in glyphOrder: + width = widths[glyphName] + data = data + bytechr(width) + data = data + pad + return data + + def toXML(self, writer, ttFont): + writer.begintag("hdmxData") + writer.newline() + ppems = sorted(self.hdmx.keys()) + records = [] + format = "" + for ppem in ppems: + widths = self.hdmx[ppem] + records.append(widths) + format = format + "%4d" + glyphNames = ttFont.getGlyphOrder()[:] + glyphNames.sort() + maxNameLen = max(map(len, glyphNames)) + format = "%" + repr(maxNameLen) + "s:" + format + " ;" + writer.write(format % (("ppem",) + tuple(ppems))) + writer.newline() + writer.newline() + for glyphName in glyphNames: + row = [] + for ppem in ppems: + widths = self.hdmx[ppem] + row.append(widths[glyphName]) + if ";" in glyphName: + glyphName = "\\x3b".join(glyphName.split(";")) + writer.write(format % ((glyphName,) + tuple(row))) + writer.newline() + writer.endtag("hdmxData") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name != "hdmxData": + return + content = strjoin(content) + lines = content.split(";") + topRow = lines[0].split() + assert topRow[0] == "ppem:", "illegal hdmx format" + ppems = list(map(int, topRow[1:])) + self.hdmx = hdmx = {} + for ppem in ppems: + hdmx[ppem] = {} + lines = (line.split() for line in lines[1:]) + for line in lines: + if not line: + continue + assert line[0][-1] == ":", "illegal hdmx format" + glyphName = line[0][:-1] + if "\\" in glyphName: + from fontTools.misc.textTools import safeEval + + glyphName = safeEval('"""' + glyphName + '"""') + line = list(map(int, line[1:])) + assert len(line) == len(ppems), "illegal hdmx format" + for i, ppem in enumerate(ppems): + hdmx[ppem][glyphName] = line[i] diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_h_e_a_d.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_h_e_a_d.py new file mode 100644 index 0000000000000000000000000000000000000000..dcadf68a275ce25748a50a3d257d50d849cb24fc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_h_e_a_d.py @@ -0,0 +1,130 @@ +from fontTools.misc import sstruct +from fontTools.misc.fixedTools import floatToFixedToStr, strToFixedToFloat +from fontTools.misc.textTools import safeEval, num2binary, binary2num +from fontTools.misc.timeTools import ( + timestampFromString, + timestampToString, + timestampNow, +) +from fontTools.misc.timeTools import epoch_diff as mac_epoch_diff # For backward compat +from fontTools.misc.arrayTools import intRect, unionRect +from . import DefaultTable +import logging + + +log = logging.getLogger(__name__) + +headFormat = """ + > # big endian + tableVersion: 16.16F + fontRevision: 16.16F + checkSumAdjustment: I + magicNumber: I + flags: H + unitsPerEm: H + created: Q + modified: Q + xMin: h + yMin: h + xMax: h + yMax: h + macStyle: H + lowestRecPPEM: H + fontDirectionHint: h + indexToLocFormat: h + glyphDataFormat: h +""" + + +class table__h_e_a_d(DefaultTable.DefaultTable): + """Font Header table + + The ``head`` table contains a variety of font-wide information. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/head + """ + + dependencies = ["maxp", "loca", "CFF ", "CFF2"] + + def decompile(self, data, ttFont): + dummy, rest = sstruct.unpack2(headFormat, data, self) + if rest: + # this is quite illegal, but there seem to be fonts out there that do this + log.warning("extra bytes at the end of 'head' table") + assert rest == b"\0\0" + + # For timestamp fields, ignore the top four bytes. Some fonts have + # bogus values there. Since till 2038 those bytes only can be zero, + # ignore them. + # + # https://github.com/fonttools/fonttools/issues/99#issuecomment-66776810 + for stamp in "created", "modified": + value = getattr(self, stamp) + if value > 0xFFFFFFFF: + log.warning("'%s' timestamp out of range; ignoring top bytes", stamp) + value &= 0xFFFFFFFF + setattr(self, stamp, value) + if value < 0x7C259DC0: # January 1, 1970 00:00:00 + log.warning( + "'%s' timestamp seems very low; regarding as unix timestamp", stamp + ) + value += 0x7C259DC0 + setattr(self, stamp, value) + + def compile(self, ttFont): + if ttFont.recalcBBoxes: + # For TT-flavored fonts, xMin, yMin, xMax and yMax are set in table__m_a_x_p.recalc(). + if "CFF " in ttFont: + topDict = ttFont["CFF "].cff.topDictIndex[0] + self.xMin, self.yMin, self.xMax, self.yMax = intRect(topDict.FontBBox) + elif "CFF2" in ttFont: + topDict = ttFont["CFF2"].cff.topDictIndex[0] + charStrings = topDict.CharStrings + fontBBox = None + for charString in charStrings.values(): + bounds = charString.calcBounds(charStrings) + if bounds is not None: + if fontBBox is not None: + fontBBox = unionRect(fontBBox, bounds) + else: + fontBBox = bounds + if fontBBox is not None: + self.xMin, self.yMin, self.xMax, self.yMax = intRect(fontBBox) + if ttFont.recalcTimestamp: + self.modified = timestampNow() + data = sstruct.pack(headFormat, self) + return data + + def toXML(self, writer, ttFont): + writer.comment("Most of this table will be recalculated by the compiler") + writer.newline() + _, names, fixes = sstruct.getformat(headFormat) + for name in names: + value = getattr(self, name) + if name in fixes: + value = floatToFixedToStr(value, precisionBits=fixes[name]) + elif name in ("created", "modified"): + value = timestampToString(value) + elif name in ("magicNumber", "checkSumAdjustment"): + if value < 0: + value = value + 0x100000000 + value = hex(value) + if value[-1:] == "L": + value = value[:-1] + elif name in ("macStyle", "flags"): + value = num2binary(value, 16) + writer.simpletag(name, value=value) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + value = attrs["value"] + fixes = sstruct.getformat(headFormat)[2] + if name in fixes: + value = strToFixedToFloat(value, precisionBits=fixes[name]) + elif name in ("created", "modified"): + value = timestampFromString(value) + elif name in ("macStyle", "flags"): + value = binary2num(value) + else: + value = safeEval(value) + setattr(self, name, value) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_h_h_e_a.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_h_h_e_a.py new file mode 100644 index 0000000000000000000000000000000000000000..1f051e499ceb223e9260da5b7bb76ad47ae174dd --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_h_h_e_a.py @@ -0,0 +1,147 @@ +from fontTools.misc import sstruct +from fontTools.misc.textTools import safeEval +from fontTools.misc.fixedTools import ( + ensureVersionIsLong as fi2ve, + versionToFixed as ve2fi, +) +from . import DefaultTable +import math + + +hheaFormat = """ + > # big endian + tableVersion: L + ascent: h + descent: h + lineGap: h + advanceWidthMax: H + minLeftSideBearing: h + minRightSideBearing: h + xMaxExtent: h + caretSlopeRise: h + caretSlopeRun: h + caretOffset: h + reserved0: h + reserved1: h + reserved2: h + reserved3: h + metricDataFormat: h + numberOfHMetrics: H +""" + + +class table__h_h_e_a(DefaultTable.DefaultTable): + """Horizontal Header table + + The ``hhea`` table contains information needed during horizontal + text layout. + + .. note:: + This converter class is kept in sync with the :class:`._v_h_e_a.table__v_h_e_a` + table constructor. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/hhea + """ + + # Note: Keep in sync with table__v_h_e_a + + dependencies = ["hmtx", "glyf", "CFF ", "CFF2"] + + # OpenType spec renamed these, add aliases for compatibility + @property + def ascender(self): + return self.ascent + + @ascender.setter + def ascender(self, value): + self.ascent = value + + @property + def descender(self): + return self.descent + + @descender.setter + def descender(self, value): + self.descent = value + + def decompile(self, data, ttFont): + sstruct.unpack(hheaFormat, data, self) + + def compile(self, ttFont): + if ttFont.recalcBBoxes and ( + ttFont.isLoaded("glyf") + or ttFont.isLoaded("CFF ") + or ttFont.isLoaded("CFF2") + ): + self.recalc(ttFont) + self.tableVersion = fi2ve(self.tableVersion) + return sstruct.pack(hheaFormat, self) + + def recalc(self, ttFont): + if "hmtx" not in ttFont: + return + + hmtxTable = ttFont["hmtx"] + self.advanceWidthMax = max(adv for adv, _ in hmtxTable.metrics.values()) + + boundsWidthDict = {} + if "glyf" in ttFont: + glyfTable = ttFont["glyf"] + for name in ttFont.getGlyphOrder(): + g = glyfTable[name] + if g.numberOfContours == 0: + continue + if g.numberOfContours < 0 and not hasattr(g, "xMax"): + # Composite glyph without extents set. + # Calculate those. + g.recalcBounds(glyfTable) + boundsWidthDict[name] = g.xMax - g.xMin + elif "CFF " in ttFont or "CFF2" in ttFont: + if "CFF " in ttFont: + topDict = ttFont["CFF "].cff.topDictIndex[0] + else: + topDict = ttFont["CFF2"].cff.topDictIndex[0] + charStrings = topDict.CharStrings + for name in ttFont.getGlyphOrder(): + cs = charStrings[name] + bounds = cs.calcBounds(charStrings) + if bounds is not None: + boundsWidthDict[name] = int( + math.ceil(bounds[2]) - math.floor(bounds[0]) + ) + + if boundsWidthDict: + minLeftSideBearing = float("inf") + minRightSideBearing = float("inf") + xMaxExtent = -float("inf") + for name, boundsWidth in boundsWidthDict.items(): + advanceWidth, lsb = hmtxTable[name] + rsb = advanceWidth - lsb - boundsWidth + extent = lsb + boundsWidth + minLeftSideBearing = min(minLeftSideBearing, lsb) + minRightSideBearing = min(minRightSideBearing, rsb) + xMaxExtent = max(xMaxExtent, extent) + self.minLeftSideBearing = minLeftSideBearing + self.minRightSideBearing = minRightSideBearing + self.xMaxExtent = xMaxExtent + + else: # No glyph has outlines. + self.minLeftSideBearing = 0 + self.minRightSideBearing = 0 + self.xMaxExtent = 0 + + def toXML(self, writer, ttFont): + formatstring, names, fixes = sstruct.getformat(hheaFormat) + for name in names: + value = getattr(self, name) + if name == "tableVersion": + value = fi2ve(value) + value = "0x%08x" % value + writer.simpletag(name, value=value) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "tableVersion": + setattr(self, name, ve2fi(attrs["value"])) + return + setattr(self, name, safeEval(attrs["value"])) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_h_m_t_x.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_h_m_t_x.py new file mode 100644 index 0000000000000000000000000000000000000000..0dc5077588b2bfd8892832256801af7cc83d83c0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_h_m_t_x.py @@ -0,0 +1,164 @@ +from fontTools.misc.roundTools import otRound +from fontTools import ttLib +from fontTools.misc.textTools import safeEval +from . import DefaultTable +import sys +import struct +import array +import logging + + +log = logging.getLogger(__name__) + + +class table__h_m_t_x(DefaultTable.DefaultTable): + """Horizontal Metrics table + + The ``hmtx`` table contains per-glyph metrics for the glyphs in a + ``glyf``, ``CFF ``, or ``CFF2`` table, as needed for horizontal text + layout. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/hmtx + """ + + headerTag = "hhea" + advanceName = "width" + sideBearingName = "lsb" + numberOfMetricsName = "numberOfHMetrics" + longMetricFormat = "Hh" + + def decompile(self, data, ttFont): + numGlyphs = ttFont["maxp"].numGlyphs + headerTable = ttFont.get(self.headerTag) + if headerTable is not None: + numberOfMetrics = int(getattr(headerTable, self.numberOfMetricsName)) + else: + numberOfMetrics = numGlyphs + if numberOfMetrics > numGlyphs: + log.warning( + "The %s.%s exceeds the maxp.numGlyphs" + % (self.headerTag, self.numberOfMetricsName) + ) + numberOfMetrics = numGlyphs + numberOfSideBearings = numGlyphs - numberOfMetrics + tableSize = 4 * numberOfMetrics + 2 * numberOfSideBearings + if len(data) < tableSize: + raise ttLib.TTLibError( + f"not enough '{self.tableTag}' table data: " + f"expected {tableSize} bytes, got {len(data)}" + ) + # Note: advanceWidth is unsigned, but some font editors might + # read/write as signed. We can't be sure whether it was a mistake + # or not, so we read as unsigned but also issue a warning... + metricsFmt = ">" + self.longMetricFormat * numberOfMetrics + metrics = struct.unpack(metricsFmt, data[: 4 * numberOfMetrics]) + data = data[4 * numberOfMetrics :] + sideBearings = array.array("h", data[: 2 * numberOfSideBearings]) + data = data[2 * numberOfSideBearings :] + + if sys.byteorder != "big": + sideBearings.byteswap() + if data: + log.warning("too much '%s' table data" % self.tableTag) + self.metrics = {} + glyphOrder = ttFont.getGlyphOrder() + for i in range(numberOfMetrics): + glyphName = glyphOrder[i] + advanceWidth, lsb = metrics[i * 2 : i * 2 + 2] + if advanceWidth > 32767: + log.warning( + "Glyph %r has a huge advance %s (%d); is it intentional or " + "an (invalid) negative value?", + glyphName, + self.advanceName, + advanceWidth, + ) + self.metrics[glyphName] = (advanceWidth, lsb) + lastAdvance = metrics[-2] + for i in range(numberOfSideBearings): + glyphName = glyphOrder[i + numberOfMetrics] + self.metrics[glyphName] = (lastAdvance, sideBearings[i]) + + def compile(self, ttFont): + metrics = [] + hasNegativeAdvances = False + for glyphName in ttFont.getGlyphOrder(): + advanceWidth, sideBearing = self.metrics[glyphName] + if advanceWidth < 0: + log.error( + "Glyph %r has negative advance %s" % (glyphName, self.advanceName) + ) + hasNegativeAdvances = True + metrics.append([advanceWidth, sideBearing]) + + headerTable = ttFont.get(self.headerTag) + if headerTable is not None: + lastAdvance = metrics[-1][0] + lastIndex = len(metrics) + while metrics[lastIndex - 2][0] == lastAdvance: + lastIndex -= 1 + if lastIndex <= 1: + # all advances are equal + lastIndex = 1 + break + additionalMetrics = metrics[lastIndex:] + additionalMetrics = [otRound(sb) for _, sb in additionalMetrics] + metrics = metrics[:lastIndex] + numberOfMetrics = len(metrics) + setattr(headerTable, self.numberOfMetricsName, numberOfMetrics) + else: + # no hhea/vhea, can't store numberOfMetrics; assume == numGlyphs + numberOfMetrics = ttFont["maxp"].numGlyphs + additionalMetrics = [] + + allMetrics = [] + for advance, sb in metrics: + allMetrics.extend([otRound(advance), otRound(sb)]) + metricsFmt = ">" + self.longMetricFormat * numberOfMetrics + try: + data = struct.pack(metricsFmt, *allMetrics) + except struct.error as e: + if "out of range" in str(e) and hasNegativeAdvances: + raise ttLib.TTLibError( + "'%s' table can't contain negative advance %ss" + % (self.tableTag, self.advanceName) + ) + else: + raise + additionalMetrics = array.array("h", additionalMetrics) + if sys.byteorder != "big": + additionalMetrics.byteswap() + data = data + additionalMetrics.tobytes() + return data + + def toXML(self, writer, ttFont): + names = sorted(self.metrics.keys()) + for glyphName in names: + advance, sb = self.metrics[glyphName] + writer.simpletag( + "mtx", + [ + ("name", glyphName), + (self.advanceName, advance), + (self.sideBearingName, sb), + ], + ) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if not hasattr(self, "metrics"): + self.metrics = {} + if name == "mtx": + self.metrics[attrs["name"]] = ( + safeEval(attrs[self.advanceName]), + safeEval(attrs[self.sideBearingName]), + ) + + def __delitem__(self, glyphName): + del self.metrics[glyphName] + + def __getitem__(self, glyphName): + return self.metrics[glyphName] + + def __setitem__(self, glyphName, advance_sb_pair): + self.metrics[glyphName] = tuple(advance_sb_pair) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_k_e_r_n.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_k_e_r_n.py new file mode 100644 index 0000000000000000000000000000000000000000..cdbaebedc63db51ecfb06601c9673f08f74a445b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_k_e_r_n.py @@ -0,0 +1,289 @@ +from fontTools.ttLib import getSearchRange +from fontTools.misc.textTools import safeEval, readHex +from fontTools.misc.fixedTools import fixedToFloat as fi2fl, floatToFixed as fl2fi +from . import DefaultTable +import struct +import sys +import array +import logging + + +log = logging.getLogger(__name__) + + +class table__k_e_r_n(DefaultTable.DefaultTable): + """Kerning table + + The ``kern`` table contains values that contextually adjust the inter-glyph + spacing for the glyphs in a ``glyf`` table. + + Note that similar contextual spacing adjustments can also be stored + in the "kern" feature of a ``GPOS`` table. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/kern + """ + + def getkern(self, format): + for subtable in self.kernTables: + if subtable.format == format: + return subtable + return None # not found + + def decompile(self, data, ttFont): + version, nTables = struct.unpack(">HH", data[:4]) + apple = False + if (len(data) >= 8) and (version == 1): + # AAT Apple's "new" format. Hm. + version, nTables = struct.unpack(">LL", data[:8]) + self.version = fi2fl(version, 16) + data = data[8:] + apple = True + else: + self.version = version + data = data[4:] + self.kernTables = [] + for i in range(nTables): + if self.version == 1.0: + # Apple + length, coverage, subtableFormat = struct.unpack(">LBB", data[:6]) + else: + # in OpenType spec the "version" field refers to the common + # subtable header; the actual subtable format is stored in + # the 8-15 mask bits of "coverage" field. + # This "version" is always 0 so we ignore it here + _, length, subtableFormat, coverage = struct.unpack(">HHBB", data[:6]) + if nTables == 1 and subtableFormat == 0: + # The "length" value is ignored since some fonts + # (like OpenSans and Calibri) have a subtable larger than + # its value. + (nPairs,) = struct.unpack(">H", data[6:8]) + calculated_length = (nPairs * 6) + 14 + if length != calculated_length: + log.warning( + "'kern' subtable longer than defined: " + "%d bytes instead of %d bytes" % (calculated_length, length) + ) + length = calculated_length + if subtableFormat not in kern_classes: + subtable = KernTable_format_unkown(subtableFormat) + else: + subtable = kern_classes[subtableFormat](apple) + subtable.decompile(data[:length], ttFont) + self.kernTables.append(subtable) + data = data[length:] + + def compile(self, ttFont): + if hasattr(self, "kernTables"): + nTables = len(self.kernTables) + else: + nTables = 0 + if self.version == 1.0: + # AAT Apple's "new" format. + data = struct.pack(">LL", fl2fi(self.version, 16), nTables) + else: + data = struct.pack(">HH", self.version, nTables) + if hasattr(self, "kernTables"): + for subtable in self.kernTables: + data = data + subtable.compile(ttFont) + return data + + def toXML(self, writer, ttFont): + writer.simpletag("version", value=self.version) + writer.newline() + for subtable in self.kernTables: + subtable.toXML(writer, ttFont) + + def fromXML(self, name, attrs, content, ttFont): + if name == "version": + self.version = safeEval(attrs["value"]) + return + if name != "kernsubtable": + return + if not hasattr(self, "kernTables"): + self.kernTables = [] + format = safeEval(attrs["format"]) + if format not in kern_classes: + subtable = KernTable_format_unkown(format) + else: + apple = self.version == 1.0 + subtable = kern_classes[format](apple) + self.kernTables.append(subtable) + subtable.fromXML(name, attrs, content, ttFont) + + +class KernTable_format_0(object): + # 'version' is kept for backward compatibility + version = format = 0 + + def __init__(self, apple=False): + self.apple = apple + + def decompile(self, data, ttFont): + if not self.apple: + version, length, subtableFormat, coverage = struct.unpack(">HHBB", data[:6]) + if version != 0: + from fontTools.ttLib import TTLibError + + raise TTLibError("unsupported kern subtable version: %d" % version) + tupleIndex = None + # Should we also assert length == len(data)? + data = data[6:] + else: + length, coverage, subtableFormat, tupleIndex = struct.unpack( + ">LBBH", data[:8] + ) + data = data[8:] + assert self.format == subtableFormat, "unsupported format" + self.coverage = coverage + self.tupleIndex = tupleIndex + + self.kernTable = kernTable = {} + + nPairs, searchRange, entrySelector, rangeShift = struct.unpack( + ">HHHH", data[:8] + ) + data = data[8:] + + datas = array.array("H", data[: 6 * nPairs]) + if sys.byteorder != "big": + datas.byteswap() + it = iter(datas) + glyphOrder = ttFont.getGlyphOrder() + for k in range(nPairs): + left, right, value = next(it), next(it), next(it) + if value >= 32768: + value -= 65536 + try: + kernTable[(glyphOrder[left], glyphOrder[right])] = value + except IndexError: + # Slower, but will not throw an IndexError on an invalid + # glyph id. + kernTable[(ttFont.getGlyphName(left), ttFont.getGlyphName(right))] = ( + value + ) + if len(data) > 6 * nPairs + 4: # Ignore up to 4 bytes excess + log.warning( + "excess data in 'kern' subtable: %d bytes", len(data) - 6 * nPairs + ) + + def compile(self, ttFont): + nPairs = min(len(self.kernTable), 0xFFFF) + searchRange, entrySelector, rangeShift = getSearchRange(nPairs, 6) + searchRange &= 0xFFFF + entrySelector = min(entrySelector, 0xFFFF) + rangeShift = min(rangeShift, 0xFFFF) + data = struct.pack(">HHHH", nPairs, searchRange, entrySelector, rangeShift) + + # yeehee! (I mean, turn names into indices) + try: + reverseOrder = ttFont.getReverseGlyphMap() + kernTable = sorted( + (reverseOrder[left], reverseOrder[right], value) + for ((left, right), value) in self.kernTable.items() + ) + except KeyError: + # Slower, but will not throw KeyError on invalid glyph id. + getGlyphID = ttFont.getGlyphID + kernTable = sorted( + (getGlyphID(left), getGlyphID(right), value) + for ((left, right), value) in self.kernTable.items() + ) + + for left, right, value in kernTable: + data = data + struct.pack(">HHh", left, right, value) + + if not self.apple: + version = 0 + length = len(data) + 6 + if length >= 0x10000: + log.warning( + '"kern" subtable overflow, ' + "truncating length value while preserving pairs." + ) + length &= 0xFFFF + header = struct.pack(">HHBB", version, length, self.format, self.coverage) + else: + if self.tupleIndex is None: + # sensible default when compiling a TTX from an old fonttools + # or when inserting a Windows-style format 0 subtable into an + # Apple version=1.0 kern table + log.warning("'tupleIndex' is None; default to 0") + self.tupleIndex = 0 + length = len(data) + 8 + header = struct.pack( + ">LBBH", length, self.coverage, self.format, self.tupleIndex + ) + return header + data + + def toXML(self, writer, ttFont): + attrs = dict(coverage=self.coverage, format=self.format) + if self.apple: + if self.tupleIndex is None: + log.warning("'tupleIndex' is None; default to 0") + attrs["tupleIndex"] = 0 + else: + attrs["tupleIndex"] = self.tupleIndex + writer.begintag("kernsubtable", **attrs) + writer.newline() + items = sorted(self.kernTable.items()) + for (left, right), value in items: + writer.simpletag("pair", [("l", left), ("r", right), ("v", value)]) + writer.newline() + writer.endtag("kernsubtable") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + self.coverage = safeEval(attrs["coverage"]) + subtableFormat = safeEval(attrs["format"]) + if self.apple: + if "tupleIndex" in attrs: + self.tupleIndex = safeEval(attrs["tupleIndex"]) + else: + # previous fontTools versions didn't export tupleIndex + log.warning("Apple kern subtable is missing 'tupleIndex' attribute") + self.tupleIndex = None + else: + self.tupleIndex = None + assert subtableFormat == self.format, "unsupported format" + if not hasattr(self, "kernTable"): + self.kernTable = {} + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + self.kernTable[(attrs["l"], attrs["r"])] = safeEval(attrs["v"]) + + def __getitem__(self, pair): + return self.kernTable[pair] + + def __setitem__(self, pair, value): + self.kernTable[pair] = value + + def __delitem__(self, pair): + del self.kernTable[pair] + + +class KernTable_format_unkown(object): + def __init__(self, format): + self.format = format + + def decompile(self, data, ttFont): + self.data = data + + def compile(self, ttFont): + return self.data + + def toXML(self, writer, ttFont): + writer.begintag("kernsubtable", format=self.format) + writer.newline() + writer.comment("unknown 'kern' subtable format") + writer.newline() + writer.dumphex(self.data) + writer.endtag("kernsubtable") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + self.decompile(readHex(content), ttFont) + + +kern_classes = {0: KernTable_format_0} diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_l_c_a_r.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_l_c_a_r.py new file mode 100644 index 0000000000000000000000000000000000000000..bbb32d23d9d636361117e068fb7846d319f1b52c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_l_c_a_r.py @@ -0,0 +1,13 @@ +from .otBase import BaseTTXConverter + + +class table__l_c_a_r(BaseTTXConverter): + """Ligature Caret table + + The AAT ``lcar`` table stores division points within ligatures, which applications + can use to position carets properly between the logical parts of the ligature. + + See also https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6lcar.html + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_l_o_c_a.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_l_o_c_a.py new file mode 100644 index 0000000000000000000000000000000000000000..f0b12fe57ee7ba2aafa1ea4d5aa503e14134b9af --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_l_o_c_a.py @@ -0,0 +1,70 @@ +from . import DefaultTable +import sys +import array +import logging + + +log = logging.getLogger(__name__) + + +class table__l_o_c_a(DefaultTable.DefaultTable): + """Index to Location table + + The ``loca`` table stores the offsets in the ``glyf`` table that correspond + to the descriptions of each glyph. The glyphs are references by Glyph ID. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/loca + """ + + dependencies = ["glyf"] + + def decompile(self, data, ttFont): + longFormat = ttFont["head"].indexToLocFormat + if longFormat: + format = "I" + else: + format = "H" + locations = array.array(format) + locations.frombytes(data) + if sys.byteorder != "big": + locations.byteswap() + if not longFormat: + locations = array.array("I", (2 * l for l in locations)) + if len(locations) < (ttFont["maxp"].numGlyphs + 1): + log.warning( + "corrupt 'loca' table, or wrong numGlyphs in 'maxp': %d %d", + len(locations) - 1, + ttFont["maxp"].numGlyphs, + ) + self.locations = locations + + def compile(self, ttFont): + try: + max_location = max(self.locations) + except AttributeError: + self.set([]) + max_location = 0 + if max_location < 0x20000 and all(l % 2 == 0 for l in self.locations): + locations = array.array("H") + for location in self.locations: + locations.append(location // 2) + ttFont["head"].indexToLocFormat = 0 + else: + locations = array.array("I", self.locations) + ttFont["head"].indexToLocFormat = 1 + if sys.byteorder != "big": + locations.byteswap() + return locations.tobytes() + + def set(self, locations): + self.locations = array.array("I", locations) + + def toXML(self, writer, ttFont): + writer.comment("The 'loca' table will be calculated by the compiler") + writer.newline() + + def __getitem__(self, index): + return self.locations[index] + + def __len__(self): + return len(self.locations) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_l_t_a_g.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_l_t_a_g.py new file mode 100644 index 0000000000000000000000000000000000000000..fc47cd648bc7b6be6b4ca3011c5125cc2e1d897e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_l_t_a_g.py @@ -0,0 +1,72 @@ +from fontTools.misc.textTools import bytesjoin, tobytes, safeEval +from . import DefaultTable +import struct + +# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6ltag.html + + +class table__l_t_a_g(DefaultTable.DefaultTable): + """Language Tag table + + The AAT ``ltag`` table contains mappings between the numeric codes used + in the language field of the ``name`` table and IETF language tags. + + See also https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6ltag.html + """ + + def __init__(self, tag=None): + DefaultTable.DefaultTable.__init__(self, tag) + self.version, self.flags = 1, 0 + self.tags = [] + + def addTag(self, tag): + """Add 'tag' to the list of langauge tags if not already there. + + Returns the integer index of 'tag' in the list of all tags. + """ + try: + return self.tags.index(tag) + except ValueError: + self.tags.append(tag) + return len(self.tags) - 1 + + def decompile(self, data, ttFont): + self.version, self.flags, numTags = struct.unpack(">LLL", data[:12]) + assert self.version == 1 + self.tags = [] + for i in range(numTags): + pos = 12 + i * 4 + offset, length = struct.unpack(">HH", data[pos : pos + 4]) + tag = data[offset : offset + length].decode("ascii") + self.tags.append(tag) + + def compile(self, ttFont): + dataList = [struct.pack(">LLL", self.version, self.flags, len(self.tags))] + stringPool = "" + for tag in self.tags: + offset = stringPool.find(tag) + if offset < 0: + offset = len(stringPool) + stringPool = stringPool + tag + offset = offset + 12 + len(self.tags) * 4 + dataList.append(struct.pack(">HH", offset, len(tag))) + dataList.append(tobytes(stringPool)) + return bytesjoin(dataList) + + def toXML(self, writer, ttFont): + writer.simpletag("version", value=self.version) + writer.newline() + writer.simpletag("flags", value=self.flags) + writer.newline() + for tag in self.tags: + writer.simpletag("LanguageTag", tag=tag) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if not hasattr(self, "tags"): + self.tags = [] + if name == "LanguageTag": + self.tags.append(attrs["tag"]) + elif "value" in attrs: + value = safeEval(attrs["value"]) + setattr(self, name, value) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_m_a_x_p.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_m_a_x_p.py new file mode 100644 index 0000000000000000000000000000000000000000..c1576a578f22c375ad4c5c4534b38162329aadde --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_m_a_x_p.py @@ -0,0 +1,147 @@ +from fontTools.misc import sstruct +from fontTools.misc.textTools import safeEval +from . import DefaultTable + +maxpFormat_0_5 = """ + > # big endian + tableVersion: i + numGlyphs: H +""" + +maxpFormat_1_0_add = """ + > # big endian + maxPoints: H + maxContours: H + maxCompositePoints: H + maxCompositeContours: H + maxZones: H + maxTwilightPoints: H + maxStorage: H + maxFunctionDefs: H + maxInstructionDefs: H + maxStackElements: H + maxSizeOfInstructions: H + maxComponentElements: H + maxComponentDepth: H +""" + + +class table__m_a_x_p(DefaultTable.DefaultTable): + """Maximum Profile table + + The ``maxp`` table contains the memory requirements for the data in + the font. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/maxp + """ + + dependencies = ["glyf"] + + def decompile(self, data, ttFont): + dummy, data = sstruct.unpack2(maxpFormat_0_5, data, self) + self.numGlyphs = int(self.numGlyphs) + if self.tableVersion != 0x00005000: + dummy, data = sstruct.unpack2(maxpFormat_1_0_add, data, self) + assert len(data) == 0 + + def compile(self, ttFont): + if "glyf" in ttFont: + if ttFont.isLoaded("glyf") and ttFont.recalcBBoxes: + self.recalc(ttFont) + else: + pass # CFF + self.numGlyphs = len(ttFont.getGlyphOrder()) + if self.tableVersion != 0x00005000: + self.tableVersion = 0x00010000 + data = sstruct.pack(maxpFormat_0_5, self) + if self.tableVersion == 0x00010000: + data = data + sstruct.pack(maxpFormat_1_0_add, self) + return data + + def recalc(self, ttFont): + """Recalculate the font bounding box, and most other maxp values except + for the TT instructions values. Also recalculate the value of bit 1 + of the flags field and the font bounding box of the 'head' table. + """ + glyfTable = ttFont["glyf"] + hmtxTable = ttFont["hmtx"] + headTable = ttFont["head"] + self.numGlyphs = len(glyfTable) + INFINITY = 100000 + xMin = +INFINITY + yMin = +INFINITY + xMax = -INFINITY + yMax = -INFINITY + maxPoints = 0 + maxContours = 0 + maxCompositePoints = 0 + maxCompositeContours = 0 + maxComponentElements = 0 + maxComponentDepth = 0 + allXMinIsLsb = 1 + for glyphName in ttFont.getGlyphOrder(): + g = glyfTable[glyphName] + if g.numberOfContours: + if hmtxTable[glyphName][1] != g.xMin: + allXMinIsLsb = 0 + xMin = min(xMin, g.xMin) + yMin = min(yMin, g.yMin) + xMax = max(xMax, g.xMax) + yMax = max(yMax, g.yMax) + if g.numberOfContours > 0: + nPoints, nContours = g.getMaxpValues() + maxPoints = max(maxPoints, nPoints) + maxContours = max(maxContours, nContours) + elif g.isComposite(): + nPoints, nContours, componentDepth = g.getCompositeMaxpValues( + glyfTable + ) + maxCompositePoints = max(maxCompositePoints, nPoints) + maxCompositeContours = max(maxCompositeContours, nContours) + maxComponentElements = max(maxComponentElements, len(g.components)) + maxComponentDepth = max(maxComponentDepth, componentDepth) + if xMin == +INFINITY: + headTable.xMin = 0 + headTable.yMin = 0 + headTable.xMax = 0 + headTable.yMax = 0 + else: + headTable.xMin = xMin + headTable.yMin = yMin + headTable.xMax = xMax + headTable.yMax = yMax + self.maxPoints = maxPoints + self.maxContours = maxContours + self.maxCompositePoints = maxCompositePoints + self.maxCompositeContours = maxCompositeContours + self.maxComponentElements = maxComponentElements + self.maxComponentDepth = maxComponentDepth + if allXMinIsLsb: + headTable.flags = headTable.flags | 0x2 + else: + headTable.flags = headTable.flags & ~0x2 + + def testrepr(self): + items = sorted(self.__dict__.items()) + print(". . . . . . . . .") + for combo in items: + print(" %s: %s" % combo) + print(". . . . . . . . .") + + def toXML(self, writer, ttFont): + if self.tableVersion != 0x00005000: + writer.comment("Most of this table will be recalculated by the compiler") + writer.newline() + formatstring, names, fixes = sstruct.getformat(maxpFormat_0_5) + if self.tableVersion != 0x00005000: + formatstring, names_1_0, fixes = sstruct.getformat(maxpFormat_1_0_add) + names = {**names, **names_1_0} + for name in names: + value = getattr(self, name) + if name == "tableVersion": + value = hex(value) + writer.simpletag(name, value=value) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + setattr(self, name, safeEval(attrs["value"])) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_m_e_t_a.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_m_e_t_a.py new file mode 100644 index 0000000000000000000000000000000000000000..c5cea1b993e8e15968065f9a50b27784fcf4eb8c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_m_e_t_a.py @@ -0,0 +1,112 @@ +from fontTools.misc import sstruct +from fontTools.misc.textTools import bytesjoin, strjoin, readHex +from fontTools.ttLib import TTLibError +from . import DefaultTable + +# Apple's documentation of 'meta': +# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6meta.html + +META_HEADER_FORMAT = """ + > # big endian + version: L + flags: L + dataOffset: L + numDataMaps: L +""" + + +DATA_MAP_FORMAT = """ + > # big endian + tag: 4s + dataOffset: L + dataLength: L +""" + + +class table__m_e_t_a(DefaultTable.DefaultTable): + """Metadata table + + The ``meta`` table contains various metadata values for the font. Each + category of metadata in the table is identified by a four-character tag. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/meta + """ + + def __init__(self, tag=None): + DefaultTable.DefaultTable.__init__(self, tag) + self.data = {} + + def decompile(self, data, ttFont): + headerSize = sstruct.calcsize(META_HEADER_FORMAT) + header = sstruct.unpack(META_HEADER_FORMAT, data[0:headerSize]) + if header["version"] != 1: + raise TTLibError("unsupported 'meta' version %d" % header["version"]) + dataMapSize = sstruct.calcsize(DATA_MAP_FORMAT) + for i in range(header["numDataMaps"]): + dataMapOffset = headerSize + i * dataMapSize + dataMap = sstruct.unpack( + DATA_MAP_FORMAT, data[dataMapOffset : dataMapOffset + dataMapSize] + ) + tag = dataMap["tag"] + offset = dataMap["dataOffset"] + self.data[tag] = data[offset : offset + dataMap["dataLength"]] + if tag in ["dlng", "slng"]: + self.data[tag] = self.data[tag].decode("utf-8") + + def compile(self, ttFont): + keys = sorted(self.data.keys()) + headerSize = sstruct.calcsize(META_HEADER_FORMAT) + dataOffset = headerSize + len(keys) * sstruct.calcsize(DATA_MAP_FORMAT) + header = sstruct.pack( + META_HEADER_FORMAT, + { + "version": 1, + "flags": 0, + "dataOffset": dataOffset, + "numDataMaps": len(keys), + }, + ) + dataMaps = [] + dataBlocks = [] + for tag in keys: + if tag in ["dlng", "slng"]: + data = self.data[tag].encode("utf-8") + else: + data = self.data[tag] + dataMaps.append( + sstruct.pack( + DATA_MAP_FORMAT, + {"tag": tag, "dataOffset": dataOffset, "dataLength": len(data)}, + ) + ) + dataBlocks.append(data) + dataOffset += len(data) + return bytesjoin([header] + dataMaps + dataBlocks) + + def toXML(self, writer, ttFont): + for tag in sorted(self.data.keys()): + if tag in ["dlng", "slng"]: + writer.begintag("text", tag=tag) + writer.newline() + writer.write(self.data[tag]) + writer.newline() + writer.endtag("text") + writer.newline() + else: + writer.begintag("hexdata", tag=tag) + writer.newline() + data = self.data[tag] + if min(data) >= 0x20 and max(data) <= 0x7E: + writer.comment("ascii: " + data.decode("ascii")) + writer.newline() + writer.dumphex(data) + writer.endtag("hexdata") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "hexdata": + self.data[attrs["tag"]] = readHex(content) + elif name == "text" and attrs["tag"] in ["dlng", "slng"]: + self.data[attrs["tag"]] = strjoin(content).strip() + else: + raise TTLibError("can't handle '%s' element" % name) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_m_o_r_t.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_m_o_r_t.py new file mode 100644 index 0000000000000000000000000000000000000000..5e5fa77ce73fff4906d92610afd9914eb2b61a3c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_m_o_r_t.py @@ -0,0 +1,14 @@ +from .otBase import BaseTTXConverter + + +# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6mort.html +class table__m_o_r_t(BaseTTXConverter): + """The AAT ``mort`` table contains glyph transformations used for script shaping and + for various other optional smart features. + + Note: ``mort`` has been deprecated in favor of the newer ``morx`` table. + + See also https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6mort.html + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_m_o_r_x.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_m_o_r_x.py new file mode 100644 index 0000000000000000000000000000000000000000..dfb3abcc5e35e426bbd670417c429dd4b4ce0962 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_m_o_r_x.py @@ -0,0 +1,15 @@ +from .otBase import BaseTTXConverter + + +# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html +class table__m_o_r_x(BaseTTXConverter): + """The AAT ``morx`` table contains glyph transformations used for script shaping and + for various other optional smart features, akin to ``GSUB`` and ``GPOS`` features + in OpenType Layout. + + Note: ``morx`` is a replacement for the now deprecated ``mort`` table. + + See also https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_n_a_m_e.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_n_a_m_e.py new file mode 100644 index 0000000000000000000000000000000000000000..b5913639bcf1823bbde584d1f2bdbe56a56b88d9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_n_a_m_e.py @@ -0,0 +1,1242 @@ +# -*- coding: utf-8 -*- +from __future__ import annotations + +from fontTools.misc import sstruct +from fontTools.misc.textTools import ( + bytechr, + byteord, + bytesjoin, + strjoin, + tobytes, + tostr, + safeEval, +) +from fontTools.misc.encodingTools import getEncoding +from fontTools.ttLib import newTable +from fontTools.ttLib.ttVisitor import TTVisitor +from fontTools import ttLib +import fontTools.ttLib.tables.otTables as otTables +from fontTools.ttLib.tables import C_P_A_L_ +from . import DefaultTable +import struct +import logging + + +log = logging.getLogger(__name__) + +nameRecordFormat = """ + > # big endian + platformID: H + platEncID: H + langID: H + nameID: H + length: H + offset: H +""" + +nameRecordSize = sstruct.calcsize(nameRecordFormat) + + +class table__n_a_m_e(DefaultTable.DefaultTable): + """Naming table + + The ``name`` table is used to store a variety of strings that can be + associated with user-facing font information. Records in the ``name`` + table can be tagged with language tags to support multilingual naming + and can support platform-specific character-encoding variants. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/name + """ + + dependencies = ["ltag"] + + def __init__(self, tag=None): + super().__init__(tag) + self.names = [] + + def decompile(self, data, ttFont): + format, n, stringOffset = struct.unpack(b">HHH", data[:6]) + expectedStringOffset = 6 + n * nameRecordSize + if stringOffset != expectedStringOffset: + log.error( + "'name' table stringOffset incorrect. Expected: %s; Actual: %s", + expectedStringOffset, + stringOffset, + ) + stringData = data[stringOffset:] + data = data[6:] + self.names: list[NameRecord] = [] + for i in range(n): + if len(data) < 12: + log.error("skipping malformed name record #%d", i) + continue + name, data = sstruct.unpack2(nameRecordFormat, data, NameRecord()) + name.string = stringData[name.offset : name.offset + name.length] + if name.offset + name.length > len(stringData): + log.error("skipping malformed name record #%d", i) + continue + assert len(name.string) == name.length + # if (name.platEncID, name.platformID) in ((0, 0), (1, 3)): + # if len(name.string) % 2: + # print "2-byte string doesn't have even length!" + # print name.__dict__ + del name.offset, name.length + self.names.append(name) + + def compile(self, ttFont): + names = self.names + names.sort() # sort according to the spec; see NameRecord.__lt__() + stringData = b"" + format = 0 + n = len(names) + stringOffset = 6 + n * sstruct.calcsize(nameRecordFormat) + data = struct.pack(b">HHH", format, n, stringOffset) + lastoffset = 0 + done = {} # remember the data so we can reuse the "pointers" + for name in names: + string = name.toBytes() + if string in done: + name.offset, name.length = done[string] + else: + name.offset, name.length = done[string] = len(stringData), len(string) + stringData = bytesjoin([stringData, string]) + data = data + sstruct.pack(nameRecordFormat, name) + return data + stringData + + def toXML(self, writer, ttFont): + for name in self.names: + name.toXML(writer, ttFont) + + def fromXML(self, name, attrs, content, ttFont): + if name != "namerecord": + return # ignore unknown tags + name = NameRecord() + self.names.append(name) + name.fromXML(name, attrs, content, ttFont) + + def getName( + self, nameID: int, platformID: int, platEncID: int, langID: int | None = None + ) -> "NameRecord | None": + for namerecord in self.names: + if ( + namerecord.nameID == nameID + and namerecord.platformID == platformID + and namerecord.platEncID == platEncID + ): + if langID is None or namerecord.langID == langID: + return namerecord + return None # not found + + def getDebugName(self, nameID: int) -> str | None: + englishName: str | None = None + someName: str | None = None + for name in self.names: + if name.nameID != nameID: + continue + try: + unistr = name.toUnicode() + except UnicodeDecodeError: + continue + + someName = unistr + if (name.platformID, name.langID) in ((1, 0), (3, 0x409)): + englishName = unistr + break + if englishName: + return englishName + elif someName: + return someName + else: + return None + + def getFirstDebugName(self, nameIDs): + for nameID in nameIDs: + name = self.getDebugName(nameID) + if name is not None: + return name + return None + + def getBestFamilyName(self): + # 21 = WWS Family Name + # 16 = Typographic Family Name + # 1 = Family Name + return self.getFirstDebugName((21, 16, 1)) + + def getBestSubFamilyName(self): + # 22 = WWS SubFamily Name + # 17 = Typographic SubFamily Name + # 2 = SubFamily Name + return self.getFirstDebugName((22, 17, 2)) + + def getBestFullName(self): + # 4 = Full Name + # 6 = PostScript Name + for nameIDs in ((21, 22), (16, 17), (1, 2), (4,), (6,)): + if len(nameIDs) == 2: + name_fam = self.getDebugName(nameIDs[0]) + name_subfam = self.getDebugName(nameIDs[1]) + if None in [name_fam, name_subfam]: + continue # if any is None, skip + name = f"{name_fam} {name_subfam}" + if name_subfam.lower() == "regular": + name = f"{name_fam}" + return name + else: + name = self.getDebugName(nameIDs[0]) + if name is not None: + return name + return None + + def setName(self, string, nameID, platformID, platEncID, langID): + """Set the 'string' for the name record identified by 'nameID', 'platformID', + 'platEncID' and 'langID'. If a record with that nameID doesn't exist, create it + and append to the name table. + + 'string' can be of type `str` (`unicode` in PY2) or `bytes`. In the latter case, + it is assumed to be already encoded with the correct plaform-specific encoding + identified by the (platformID, platEncID, langID) triplet. A warning is issued + to prevent unexpected results. + """ + if not isinstance(string, str): + if isinstance(string, bytes): + log.warning( + "name string is bytes, ensure it's correctly encoded: %r", string + ) + else: + raise TypeError( + "expected unicode or bytes, found %s: %r" + % (type(string).__name__, string) + ) + namerecord = self.getName(nameID, platformID, platEncID, langID) + if namerecord: + namerecord.string = string + else: + self.names.append(makeName(string, nameID, platformID, platEncID, langID)) + + def removeNames(self, nameID=None, platformID=None, platEncID=None, langID=None): + """Remove any name records identified by the given combination of 'nameID', + 'platformID', 'platEncID' and 'langID'. + """ + args = { + argName: argValue + for argName, argValue in ( + ("nameID", nameID), + ("platformID", platformID), + ("platEncID", platEncID), + ("langID", langID), + ) + if argValue is not None + } + if not args: + # no arguments, nothing to do + return + self.names = [ + rec + for rec in self.names + if any( + argValue != getattr(rec, argName) for argName, argValue in args.items() + ) + ] + + @staticmethod + def removeUnusedNames(ttFont): + """Remove any name records which are not in NameID range 0-255 and not utilized + within the font itself.""" + visitor = NameRecordVisitor() + visitor.visit(ttFont) + toDelete = set() + for record in ttFont["name"].names: + # Name IDs 26 to 255, inclusive, are reserved for future standard names. + # https://learn.microsoft.com/en-us/typography/opentype/spec/name#name-ids + if record.nameID < 256: + continue + if record.nameID not in visitor.seen: + toDelete.add(record.nameID) + + for nameID in toDelete: + ttFont["name"].removeNames(nameID) + return toDelete + + def _findUnusedNameID(self, minNameID=256): + """Finds an unused name id. + + The nameID is assigned in the range between 'minNameID' and 32767 (inclusive), + following the last nameID in the name table. + """ + names = self.names + nameID = 1 + max([n.nameID for n in names] + [minNameID - 1]) + if nameID > 32767: + raise ValueError("nameID must be less than 32768") + return nameID + + def findMultilingualName( + self, names, windows=True, mac=True, minNameID=0, ttFont=None + ): + """Return the name ID of an existing multilingual name that + matches the 'names' dictionary, or None if not found. + + 'names' is a dictionary with the name in multiple languages, + such as {'en': 'Pale', 'de': 'Blaß', 'de-CH': 'Blass'}. + The keys can be arbitrary IETF BCP 47 language codes; + the values are Unicode strings. + + If 'windows' is True, the returned name ID is guaranteed + exist for all requested languages for platformID=3 and + platEncID=1. + If 'mac' is True, the returned name ID is guaranteed to exist + for all requested languages for platformID=1 and platEncID=0. + + The returned name ID will not be less than the 'minNameID' + argument. + """ + # Gather the set of requested + # (string, platformID, platEncID, langID) + # tuples + reqNameSet = set() + for lang, name in sorted(names.items()): + if windows: + windowsName = _makeWindowsName(name, None, lang) + if windowsName is not None: + reqNameSet.add( + ( + windowsName.string, + windowsName.platformID, + windowsName.platEncID, + windowsName.langID, + ) + ) + if mac: + macName = _makeMacName(name, None, lang, ttFont) + if macName is not None: + reqNameSet.add( + ( + macName.string, + macName.platformID, + macName.platEncID, + macName.langID, + ) + ) + + # Collect matching name IDs + matchingNames = dict() + for name in self.names: + try: + key = (name.toUnicode(), name.platformID, name.platEncID, name.langID) + except UnicodeDecodeError: + continue + if key in reqNameSet and name.nameID >= minNameID: + nameSet = matchingNames.setdefault(name.nameID, set()) + nameSet.add(key) + + # Return the first name ID that defines all requested strings + for nameID, nameSet in sorted(matchingNames.items()): + if nameSet == reqNameSet: + return nameID + + return None # not found + + def addMultilingualName( + self, names, ttFont=None, nameID=None, windows=True, mac=True, minNameID=0 + ): + """Add a multilingual name, returning its name ID + + 'names' is a dictionary with the name in multiple languages, + such as {'en': 'Pale', 'de': 'Blaß', 'de-CH': 'Blass'}. + The keys can be arbitrary IETF BCP 47 language codes; + the values are Unicode strings. + + 'ttFont' is the TTFont to which the names are added, or None. + If present, the font's 'ltag' table can get populated + to store exotic language codes, which allows encoding + names that otherwise cannot get encoded at all. + + 'nameID' is the name ID to be used, or None to let the library + find an existing set of name records that match, or pick an + unused name ID. + + If 'windows' is True, a platformID=3 name record will be added. + If 'mac' is True, a platformID=1 name record will be added. + + If the 'nameID' argument is None, the created nameID will not + be less than the 'minNameID' argument. + """ + if nameID is None: + # Reuse nameID if possible + nameID = self.findMultilingualName( + names, windows=windows, mac=mac, minNameID=minNameID, ttFont=ttFont + ) + if nameID is not None: + return nameID + nameID = self._findUnusedNameID() + # TODO: Should minimize BCP 47 language codes. + # https://github.com/fonttools/fonttools/issues/930 + for lang, name in sorted(names.items()): + if windows: + windowsName = _makeWindowsName(name, nameID, lang) + if windowsName is not None: + self.names.append(windowsName) + else: + # We cannot not make a Windows name: make sure we add a + # Mac name as a fallback. This can happen for exotic + # BCP47 language tags that have no Windows language code. + mac = True + if mac: + macName = _makeMacName(name, nameID, lang, ttFont) + if macName is not None: + self.names.append(macName) + return nameID + + def addName(self, string, platforms=((1, 0, 0), (3, 1, 0x409)), minNameID=255): + """Add a new name record containing 'string' for each (platformID, platEncID, + langID) tuple specified in the 'platforms' list. + + The nameID is assigned in the range between 'minNameID'+1 and 32767 (inclusive), + following the last nameID in the name table. + If no 'platforms' are specified, two English name records are added, one for the + Macintosh (platformID=0), and one for the Windows platform (3). + + The 'string' must be a Unicode string, so it can be encoded with different, + platform-specific encodings. + + Return the new nameID. + """ + assert ( + len(platforms) > 0 + ), "'platforms' must contain at least one (platformID, platEncID, langID) tuple" + if not isinstance(string, str): + raise TypeError( + "expected str, found %s: %r" % (type(string).__name__, string) + ) + nameID = self._findUnusedNameID(minNameID + 1) + for platformID, platEncID, langID in platforms: + self.names.append(makeName(string, nameID, platformID, platEncID, langID)) + return nameID + + +def makeName(string, nameID, platformID, platEncID, langID): + name = NameRecord() + name.string, name.nameID, name.platformID, name.platEncID, name.langID = ( + string, + nameID, + platformID, + platEncID, + langID, + ) + return name + + +def _makeWindowsName(name, nameID, language): + """Create a NameRecord for the Microsoft Windows platform + + 'language' is an arbitrary IETF BCP 47 language identifier such + as 'en', 'de-CH', 'de-AT-1901', or 'fa-Latn'. If Microsoft Windows + does not support the desired language, the result will be None. + Future versions of fonttools might return a NameRecord for the + OpenType 'name' table format 1, but this is not implemented yet. + """ + langID = _WINDOWS_LANGUAGE_CODES.get(language.lower()) + if langID is not None: + return makeName(name, nameID, 3, 1, langID) + else: + log.warning( + "cannot add Windows name in language %s " + "because fonttools does not yet support " + "name table format 1" % language + ) + return None + + +def _makeMacName(name, nameID, language, font=None): + """Create a NameRecord for Apple platforms + + 'language' is an arbitrary IETF BCP 47 language identifier such + as 'en', 'de-CH', 'de-AT-1901', or 'fa-Latn'. When possible, we + create a Macintosh NameRecord that is understood by old applications + (platform ID 1 and an old-style Macintosh language enum). If this + is not possible, we create a Unicode NameRecord (platform ID 0) + whose language points to the font’s 'ltag' table. The latter + can encode any string in any language, but legacy applications + might not recognize the format (in which case they will ignore + those names). + + 'font' should be the TTFont for which you want to create a name. + If 'font' is None, we only return NameRecords for legacy Macintosh; + in that case, the result will be None for names that need to + be encoded with an 'ltag' table. + + See the section “The language identifier” in Apple’s specification: + https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html + """ + macLang = _MAC_LANGUAGE_CODES.get(language.lower()) + macScript = _MAC_LANGUAGE_TO_SCRIPT.get(macLang) + if macLang is not None and macScript is not None: + encoding = getEncoding(1, macScript, macLang, default="ascii") + # Check if we can actually encode this name. If we can't, + # for example because we have no support for the legacy + # encoding, or because the name string contains Unicode + # characters that the legacy encoding cannot represent, + # we fall back to encoding the name in Unicode and put + # the language tag into the ltag table. + try: + _ = tobytes(name, encoding, errors="strict") + return makeName(name, nameID, 1, macScript, macLang) + except UnicodeEncodeError: + pass + if font is not None: + ltag = font.tables.get("ltag") + if ltag is None: + ltag = font["ltag"] = newTable("ltag") + # 0 = Unicode; 4 = “Unicode 2.0 or later semantics (non-BMP characters allowed)” + # “The preferred platform-specific code for Unicode would be 3 or 4.” + # https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html + return makeName(name, nameID, 0, 4, ltag.addTag(language)) + else: + log.warning( + "cannot store language %s into 'ltag' table " + "without having access to the TTFont object" % language + ) + return None + + +class NameRecord(object): + def getEncoding(self, default="ascii"): + """Returns the Python encoding name for this name entry based on its platformID, + platEncID, and langID. If encoding for these values is not known, by default + 'ascii' is returned. That can be overriden by passing a value to the default + argument. + """ + return getEncoding(self.platformID, self.platEncID, self.langID, default) + + def encodingIsUnicodeCompatible(self): + return self.getEncoding(None) in ["utf_16_be", "ucs2be", "ascii", "latin1"] + + def __str__(self): + return self.toStr(errors="backslashreplace") + + def isUnicode(self): + return self.platformID == 0 or ( + self.platformID == 3 and self.platEncID in [0, 1, 10] + ) + + def toUnicode(self, errors: str = "strict") -> str: + """ + If self.string is a Unicode string, return it; otherwise try decoding the + bytes in self.string to a Unicode string using the encoding of this + entry as returned by self.getEncoding(); Note that self.getEncoding() + returns 'ascii' if the encoding is unknown to the library. + + Certain heuristics are performed to recover data from bytes that are + ill-formed in the chosen encoding, or that otherwise look misencoded + (mostly around bad UTF-16BE encoded bytes, or bytes that look like UTF-16BE + but marked otherwise). If the bytes are ill-formed and the heuristics fail, + the error is handled according to the errors parameter to this function, which is + passed to the underlying decode() function; by default it throws a + UnicodeDecodeError exception. + + Note: The mentioned heuristics mean that roundtripping a font to XML and back + to binary might recover some misencoded data whereas just loading the font + and saving it back will not change them. + """ + + def isascii(b: int) -> bool: + return (b >= 0x20 and b <= 0x7E) or b in [0x09, 0x0A, 0x0D] + + encoding = self.getEncoding() + string = self.string + + if ( + isinstance(string, bytes) + and encoding == "utf_16_be" + and len(string) % 2 == 1 + ): + # Recover badly encoded UTF-16 strings that have an odd number of bytes: + # - If the last byte is zero, drop it. Otherwise, + # - If all the odd bytes are zero and all the even bytes are ASCII, + # prepend one zero byte. Otherwise, + # - If first byte is zero and all other bytes are ASCII, insert zero + # bytes between consecutive ASCII bytes. + # + # (Yes, I've seen all of these in the wild... sigh) + if byteord(string[-1]) == 0: + string = string[:-1] + elif all( + byteord(b) == 0 if i % 2 else isascii(byteord(b)) + for i, b in enumerate(string) + ): + string = b"\0" + string + elif byteord(string[0]) == 0 and all( + isascii(byteord(b)) for b in string[1:] + ): + string = bytesjoin(b"\0" + bytechr(byteord(b)) for b in string[1:]) + + string = tostr(string, encoding=encoding, errors=errors) + + # If decoded strings still looks like UTF-16BE, it suggests a double-encoding. + # Fix it up. + if all( + ord(c) == 0 if i % 2 == 0 else isascii(ord(c)) for i, c in enumerate(string) + ): + # If string claims to be Mac encoding, but looks like UTF-16BE with ASCII text, + # narrow it down. + string = "".join(c for c in string[1::2]) + + return string + + def toBytes(self, errors="strict"): + """If self.string is a bytes object, return it; otherwise try encoding + the Unicode string in self.string to bytes using the encoding of this + entry as returned by self.getEncoding(); Note that self.getEncoding() + returns 'ascii' if the encoding is unknown to the library. + + If the Unicode string cannot be encoded to bytes in the chosen encoding, + the error is handled according to the errors parameter to this function, + which is passed to the underlying encode() function; by default it throws a + UnicodeEncodeError exception. + """ + return tobytes(self.string, encoding=self.getEncoding(), errors=errors) + + toStr = toUnicode + + def toXML(self, writer, ttFont): + try: + unistr = self.toUnicode() + except UnicodeDecodeError: + unistr = None + attrs = [ + ("nameID", self.nameID), + ("platformID", self.platformID), + ("platEncID", self.platEncID), + ("langID", hex(self.langID)), + ] + + if unistr is None or not self.encodingIsUnicodeCompatible(): + attrs.append(("unicode", unistr is not None)) + + writer.begintag("namerecord", attrs) + writer.newline() + if unistr is not None: + writer.write(unistr) + else: + writer.write8bit(self.string) + writer.newline() + writer.endtag("namerecord") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + self.nameID = safeEval(attrs["nameID"]) + self.platformID = safeEval(attrs["platformID"]) + self.platEncID = safeEval(attrs["platEncID"]) + self.langID = safeEval(attrs["langID"]) + s = strjoin(content).strip() + encoding = self.getEncoding() + if self.encodingIsUnicodeCompatible() or safeEval( + attrs.get("unicode", "False") + ): + self.string = s.encode(encoding) + else: + # This is the inverse of write8bit... + self.string = s.encode("latin1") + + def __lt__(self, other): + if type(self) != type(other): + return NotImplemented + + try: + selfTuple = ( + self.platformID, + self.platEncID, + self.langID, + self.nameID, + ) + otherTuple = ( + other.platformID, + other.platEncID, + other.langID, + other.nameID, + ) + except AttributeError: + # This can only happen for + # 1) an object that is not a NameRecord, or + # 2) an unlikely incomplete NameRecord object which has not been + # fully populated + return NotImplemented + + try: + # Include the actual NameRecord string in the comparison tuples + selfTuple = selfTuple + (self.toBytes(),) + otherTuple = otherTuple + (other.toBytes(),) + except UnicodeEncodeError as e: + # toBytes caused an encoding error in either of the two, so content + # to sorting based on IDs only + log.error("NameRecord sorting failed to encode: %s" % e) + + # Implemented so that list.sort() sorts according to the spec by using + # the order of the tuple items and their comparison + return selfTuple < otherTuple + + def __repr__(self): + return "<NameRecord NameID=%d; PlatformID=%d; LanguageID=%d>" % ( + self.nameID, + self.platformID, + self.langID, + ) + + +# Windows language ID → IETF BCP-47 language tag +# +# While Microsoft indicates a region/country for all its language +# IDs, we follow Unicode practice by omitting “most likely subtags” +# as per Unicode CLDR. For example, English is simply “en” and not +# “en-Latn” because according to Unicode, the default script +# for English is Latin. +# +# http://www.unicode.org/cldr/charts/latest/supplemental/likely_subtags.html +# http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry +_WINDOWS_LANGUAGES = { + 0x0436: "af", + 0x041C: "sq", + 0x0484: "gsw", + 0x045E: "am", + 0x1401: "ar-DZ", + 0x3C01: "ar-BH", + 0x0C01: "ar", + 0x0801: "ar-IQ", + 0x2C01: "ar-JO", + 0x3401: "ar-KW", + 0x3001: "ar-LB", + 0x1001: "ar-LY", + 0x1801: "ary", + 0x2001: "ar-OM", + 0x4001: "ar-QA", + 0x0401: "ar-SA", + 0x2801: "ar-SY", + 0x1C01: "aeb", + 0x3801: "ar-AE", + 0x2401: "ar-YE", + 0x042B: "hy", + 0x044D: "as", + 0x082C: "az-Cyrl", + 0x042C: "az", + 0x046D: "ba", + 0x042D: "eu", + 0x0423: "be", + 0x0845: "bn", + 0x0445: "bn-IN", + 0x201A: "bs-Cyrl", + 0x141A: "bs", + 0x047E: "br", + 0x0402: "bg", + 0x0403: "ca", + 0x0C04: "zh-HK", + 0x1404: "zh-MO", + 0x0804: "zh", + 0x1004: "zh-SG", + 0x0404: "zh-TW", + 0x0483: "co", + 0x041A: "hr", + 0x101A: "hr-BA", + 0x0405: "cs", + 0x0406: "da", + 0x048C: "prs", + 0x0465: "dv", + 0x0813: "nl-BE", + 0x0413: "nl", + 0x0C09: "en-AU", + 0x2809: "en-BZ", + 0x1009: "en-CA", + 0x2409: "en-029", + 0x4009: "en-IN", + 0x1809: "en-IE", + 0x2009: "en-JM", + 0x4409: "en-MY", + 0x1409: "en-NZ", + 0x3409: "en-PH", + 0x4809: "en-SG", + 0x1C09: "en-ZA", + 0x2C09: "en-TT", + 0x0809: "en-GB", + 0x0409: "en", + 0x3009: "en-ZW", + 0x0425: "et", + 0x0438: "fo", + 0x0464: "fil", + 0x040B: "fi", + 0x080C: "fr-BE", + 0x0C0C: "fr-CA", + 0x040C: "fr", + 0x140C: "fr-LU", + 0x180C: "fr-MC", + 0x100C: "fr-CH", + 0x0462: "fy", + 0x0456: "gl", + 0x0437: "ka", + 0x0C07: "de-AT", + 0x0407: "de", + 0x1407: "de-LI", + 0x1007: "de-LU", + 0x0807: "de-CH", + 0x0408: "el", + 0x046F: "kl", + 0x0447: "gu", + 0x0468: "ha", + 0x040D: "he", + 0x0439: "hi", + 0x040E: "hu", + 0x040F: "is", + 0x0470: "ig", + 0x0421: "id", + 0x045D: "iu", + 0x085D: "iu-Latn", + 0x083C: "ga", + 0x0434: "xh", + 0x0435: "zu", + 0x0410: "it", + 0x0810: "it-CH", + 0x0411: "ja", + 0x044B: "kn", + 0x043F: "kk", + 0x0453: "km", + 0x0486: "quc", + 0x0487: "rw", + 0x0441: "sw", + 0x0457: "kok", + 0x0412: "ko", + 0x0440: "ky", + 0x0454: "lo", + 0x0426: "lv", + 0x0427: "lt", + 0x082E: "dsb", + 0x046E: "lb", + 0x042F: "mk", + 0x083E: "ms-BN", + 0x043E: "ms", + 0x044C: "ml", + 0x043A: "mt", + 0x0481: "mi", + 0x047A: "arn", + 0x044E: "mr", + 0x047C: "moh", + 0x0450: "mn", + 0x0850: "mn-CN", + 0x0461: "ne", + 0x0414: "nb", + 0x0814: "nn", + 0x0482: "oc", + 0x0448: "or", + 0x0463: "ps", + 0x0415: "pl", + 0x0416: "pt", + 0x0816: "pt-PT", + 0x0446: "pa", + 0x046B: "qu-BO", + 0x086B: "qu-EC", + 0x0C6B: "qu", + 0x0418: "ro", + 0x0417: "rm", + 0x0419: "ru", + 0x243B: "smn", + 0x103B: "smj-NO", + 0x143B: "smj", + 0x0C3B: "se-FI", + 0x043B: "se", + 0x083B: "se-SE", + 0x203B: "sms", + 0x183B: "sma-NO", + 0x1C3B: "sms", + 0x044F: "sa", + 0x1C1A: "sr-Cyrl-BA", + 0x0C1A: "sr", + 0x181A: "sr-Latn-BA", + 0x081A: "sr-Latn", + 0x046C: "nso", + 0x0432: "tn", + 0x045B: "si", + 0x041B: "sk", + 0x0424: "sl", + 0x2C0A: "es-AR", + 0x400A: "es-BO", + 0x340A: "es-CL", + 0x240A: "es-CO", + 0x140A: "es-CR", + 0x1C0A: "es-DO", + 0x300A: "es-EC", + 0x440A: "es-SV", + 0x100A: "es-GT", + 0x480A: "es-HN", + 0x080A: "es-MX", + 0x4C0A: "es-NI", + 0x180A: "es-PA", + 0x3C0A: "es-PY", + 0x280A: "es-PE", + 0x500A: "es-PR", + # Microsoft has defined two different language codes for + # “Spanish with modern sorting” and “Spanish with traditional + # sorting”. This makes sense for collation APIs, and it would be + # possible to express this in BCP 47 language tags via Unicode + # extensions (eg., “es-u-co-trad” is “Spanish with traditional + # sorting”). However, for storing names in fonts, this distinction + # does not make sense, so we use “es” in both cases. + 0x0C0A: "es", + 0x040A: "es", + 0x540A: "es-US", + 0x380A: "es-UY", + 0x200A: "es-VE", + 0x081D: "sv-FI", + 0x041D: "sv", + 0x045A: "syr", + 0x0428: "tg", + 0x085F: "tzm", + 0x0449: "ta", + 0x0444: "tt", + 0x044A: "te", + 0x041E: "th", + 0x0451: "bo", + 0x041F: "tr", + 0x0442: "tk", + 0x0480: "ug", + 0x0422: "uk", + 0x042E: "hsb", + 0x0420: "ur", + 0x0843: "uz-Cyrl", + 0x0443: "uz", + 0x042A: "vi", + 0x0452: "cy", + 0x0488: "wo", + 0x0485: "sah", + 0x0478: "ii", + 0x046A: "yo", +} + + +_MAC_LANGUAGES = { + 0: "en", + 1: "fr", + 2: "de", + 3: "it", + 4: "nl", + 5: "sv", + 6: "es", + 7: "da", + 8: "pt", + 9: "no", + 10: "he", + 11: "ja", + 12: "ar", + 13: "fi", + 14: "el", + 15: "is", + 16: "mt", + 17: "tr", + 18: "hr", + 19: "zh-Hant", + 20: "ur", + 21: "hi", + 22: "th", + 23: "ko", + 24: "lt", + 25: "pl", + 26: "hu", + 27: "es", + 28: "lv", + 29: "se", + 30: "fo", + 31: "fa", + 32: "ru", + 33: "zh", + 34: "nl-BE", + 35: "ga", + 36: "sq", + 37: "ro", + 38: "cz", + 39: "sk", + 40: "sl", + 41: "yi", + 42: "sr", + 43: "mk", + 44: "bg", + 45: "uk", + 46: "be", + 47: "uz", + 48: "kk", + 49: "az-Cyrl", + 50: "az-Arab", + 51: "hy", + 52: "ka", + 53: "mo", + 54: "ky", + 55: "tg", + 56: "tk", + 57: "mn-CN", + 58: "mn", + 59: "ps", + 60: "ks", + 61: "ku", + 62: "sd", + 63: "bo", + 64: "ne", + 65: "sa", + 66: "mr", + 67: "bn", + 68: "as", + 69: "gu", + 70: "pa", + 71: "or", + 72: "ml", + 73: "kn", + 74: "ta", + 75: "te", + 76: "si", + 77: "my", + 78: "km", + 79: "lo", + 80: "vi", + 81: "id", + 82: "tl", + 83: "ms", + 84: "ms-Arab", + 85: "am", + 86: "ti", + 87: "om", + 88: "so", + 89: "sw", + 90: "rw", + 91: "rn", + 92: "ny", + 93: "mg", + 94: "eo", + 128: "cy", + 129: "eu", + 130: "ca", + 131: "la", + 132: "qu", + 133: "gn", + 134: "ay", + 135: "tt", + 136: "ug", + 137: "dz", + 138: "jv", + 139: "su", + 140: "gl", + 141: "af", + 142: "br", + 143: "iu", + 144: "gd", + 145: "gv", + 146: "ga", + 147: "to", + 148: "el-polyton", + 149: "kl", + 150: "az", + 151: "nn", +} + + +_WINDOWS_LANGUAGE_CODES = { + lang.lower(): code for code, lang in _WINDOWS_LANGUAGES.items() +} +_MAC_LANGUAGE_CODES = {lang.lower(): code for code, lang in _MAC_LANGUAGES.items()} + + +# MacOS language ID → MacOS script ID +# +# Note that the script ID is not sufficient to determine what encoding +# to use in TrueType files. For some languages, MacOS used a modification +# of a mainstream script. For example, an Icelandic name would be stored +# with smRoman in the TrueType naming table, but the actual encoding +# is a special Icelandic version of the normal Macintosh Roman encoding. +# As another example, Inuktitut uses an 8-bit encoding for Canadian Aboriginal +# Syllables but MacOS had run out of available script codes, so this was +# done as a (pretty radical) “modification” of Ethiopic. +# +# http://unicode.org/Public/MAPPINGS/VENDORS/APPLE/Readme.txt +_MAC_LANGUAGE_TO_SCRIPT = { + 0: 0, # langEnglish → smRoman + 1: 0, # langFrench → smRoman + 2: 0, # langGerman → smRoman + 3: 0, # langItalian → smRoman + 4: 0, # langDutch → smRoman + 5: 0, # langSwedish → smRoman + 6: 0, # langSpanish → smRoman + 7: 0, # langDanish → smRoman + 8: 0, # langPortuguese → smRoman + 9: 0, # langNorwegian → smRoman + 10: 5, # langHebrew → smHebrew + 11: 1, # langJapanese → smJapanese + 12: 4, # langArabic → smArabic + 13: 0, # langFinnish → smRoman + 14: 6, # langGreek → smGreek + 15: 0, # langIcelandic → smRoman (modified) + 16: 0, # langMaltese → smRoman + 17: 0, # langTurkish → smRoman (modified) + 18: 0, # langCroatian → smRoman (modified) + 19: 2, # langTradChinese → smTradChinese + 20: 4, # langUrdu → smArabic + 21: 9, # langHindi → smDevanagari + 22: 21, # langThai → smThai + 23: 3, # langKorean → smKorean + 24: 29, # langLithuanian → smCentralEuroRoman + 25: 29, # langPolish → smCentralEuroRoman + 26: 29, # langHungarian → smCentralEuroRoman + 27: 29, # langEstonian → smCentralEuroRoman + 28: 29, # langLatvian → smCentralEuroRoman + 29: 0, # langSami → smRoman + 30: 0, # langFaroese → smRoman (modified) + 31: 4, # langFarsi → smArabic (modified) + 32: 7, # langRussian → smCyrillic + 33: 25, # langSimpChinese → smSimpChinese + 34: 0, # langFlemish → smRoman + 35: 0, # langIrishGaelic → smRoman (modified) + 36: 0, # langAlbanian → smRoman + 37: 0, # langRomanian → smRoman (modified) + 38: 29, # langCzech → smCentralEuroRoman + 39: 29, # langSlovak → smCentralEuroRoman + 40: 0, # langSlovenian → smRoman (modified) + 41: 5, # langYiddish → smHebrew + 42: 7, # langSerbian → smCyrillic + 43: 7, # langMacedonian → smCyrillic + 44: 7, # langBulgarian → smCyrillic + 45: 7, # langUkrainian → smCyrillic (modified) + 46: 7, # langByelorussian → smCyrillic + 47: 7, # langUzbek → smCyrillic + 48: 7, # langKazakh → smCyrillic + 49: 7, # langAzerbaijani → smCyrillic + 50: 4, # langAzerbaijanAr → smArabic + 51: 24, # langArmenian → smArmenian + 52: 23, # langGeorgian → smGeorgian + 53: 7, # langMoldavian → smCyrillic + 54: 7, # langKirghiz → smCyrillic + 55: 7, # langTajiki → smCyrillic + 56: 7, # langTurkmen → smCyrillic + 57: 27, # langMongolian → smMongolian + 58: 7, # langMongolianCyr → smCyrillic + 59: 4, # langPashto → smArabic + 60: 4, # langKurdish → smArabic + 61: 4, # langKashmiri → smArabic + 62: 4, # langSindhi → smArabic + 63: 26, # langTibetan → smTibetan + 64: 9, # langNepali → smDevanagari + 65: 9, # langSanskrit → smDevanagari + 66: 9, # langMarathi → smDevanagari + 67: 13, # langBengali → smBengali + 68: 13, # langAssamese → smBengali + 69: 11, # langGujarati → smGujarati + 70: 10, # langPunjabi → smGurmukhi + 71: 12, # langOriya → smOriya + 72: 17, # langMalayalam → smMalayalam + 73: 16, # langKannada → smKannada + 74: 14, # langTamil → smTamil + 75: 15, # langTelugu → smTelugu + 76: 18, # langSinhalese → smSinhalese + 77: 19, # langBurmese → smBurmese + 78: 20, # langKhmer → smKhmer + 79: 22, # langLao → smLao + 80: 30, # langVietnamese → smVietnamese + 81: 0, # langIndonesian → smRoman + 82: 0, # langTagalog → smRoman + 83: 0, # langMalayRoman → smRoman + 84: 4, # langMalayArabic → smArabic + 85: 28, # langAmharic → smEthiopic + 86: 28, # langTigrinya → smEthiopic + 87: 28, # langOromo → smEthiopic + 88: 0, # langSomali → smRoman + 89: 0, # langSwahili → smRoman + 90: 0, # langKinyarwanda → smRoman + 91: 0, # langRundi → smRoman + 92: 0, # langNyanja → smRoman + 93: 0, # langMalagasy → smRoman + 94: 0, # langEsperanto → smRoman + 128: 0, # langWelsh → smRoman (modified) + 129: 0, # langBasque → smRoman + 130: 0, # langCatalan → smRoman + 131: 0, # langLatin → smRoman + 132: 0, # langQuechua → smRoman + 133: 0, # langGuarani → smRoman + 134: 0, # langAymara → smRoman + 135: 7, # langTatar → smCyrillic + 136: 4, # langUighur → smArabic + 137: 26, # langDzongkha → smTibetan + 138: 0, # langJavaneseRom → smRoman + 139: 0, # langSundaneseRom → smRoman + 140: 0, # langGalician → smRoman + 141: 0, # langAfrikaans → smRoman + 142: 0, # langBreton → smRoman (modified) + 143: 28, # langInuktitut → smEthiopic (modified) + 144: 0, # langScottishGaelic → smRoman (modified) + 145: 0, # langManxGaelic → smRoman (modified) + 146: 0, # langIrishGaelicScript → smRoman (modified) + 147: 0, # langTongan → smRoman + 148: 6, # langGreekAncient → smRoman + 149: 0, # langGreenlandic → smRoman + 150: 0, # langAzerbaijanRoman → smRoman + 151: 0, # langNynorsk → smRoman +} + + +class NameRecordVisitor(TTVisitor): + # Font tables that have NameIDs we need to collect. + TABLES = ("GSUB", "GPOS", "fvar", "CPAL", "STAT") + + def __init__(self): + self.seen = set() + + +@NameRecordVisitor.register_attrs( + ( + (otTables.FeatureParamsSize, ("SubfamilyNameID",)), + (otTables.FeatureParamsStylisticSet, ("UINameID",)), + (otTables.STAT, ("ElidedFallbackNameID",)), + (otTables.AxisRecord, ("AxisNameID",)), + (otTables.AxisValue, ("ValueNameID",)), + (otTables.FeatureName, ("FeatureNameID",)), + (otTables.Setting, ("SettingNameID",)), + ) +) +def visit(visitor, obj, attr, value): + visitor.seen.add(value) + + +@NameRecordVisitor.register(otTables.FeatureParamsCharacterVariants) +def visit(visitor, obj): + for attr in ("FeatUILabelNameID", "FeatUITooltipTextNameID", "SampleTextNameID"): + value = getattr(obj, attr) + visitor.seen.add(value) + # also include the sequence of UI strings for individual variants, if any + if obj.FirstParamUILabelNameID == 0 or obj.NumNamedParameters == 0: + return + visitor.seen.update( + range( + obj.FirstParamUILabelNameID, + obj.FirstParamUILabelNameID + obj.NumNamedParameters, + ) + ) + + +@NameRecordVisitor.register(ttLib.getTableClass("fvar")) +def visit(visitor, obj): + for inst in obj.instances: + if inst.postscriptNameID != 0xFFFF: + visitor.seen.add(inst.postscriptNameID) + visitor.seen.add(inst.subfamilyNameID) + + for axis in obj.axes: + visitor.seen.add(axis.axisNameID) + + +@NameRecordVisitor.register(ttLib.getTableClass("CPAL")) +def visit(visitor, obj): + if obj.version == 1: + visitor.seen.update(obj.paletteLabels) + visitor.seen.update(obj.paletteEntryLabels) + + +@NameRecordVisitor.register(ttLib.TTFont) +def visit(visitor, font, *args, **kwargs): + if hasattr(visitor, "font"): + return False + + visitor.font = font + for tag in visitor.TABLES: + if tag in font: + visitor.visit(font[tag], *args, **kwargs) + del visitor.font + return False diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_o_p_b_d.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_o_p_b_d.py new file mode 100644 index 0000000000000000000000000000000000000000..b4c5f568290e20563992de91c7a0f5e6928652bf --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_o_p_b_d.py @@ -0,0 +1,14 @@ +from .otBase import BaseTTXConverter + + +# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6opbd.html +class table__o_p_b_d(BaseTTXConverter): + """Optical Bounds table + + The AAT ``opbd`` table contains optical boundary points for glyphs, which + applications can use for the visual alignment of lines of text. + + See also https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6opbd.html + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_p_o_s_t.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_p_o_s_t.py new file mode 100644 index 0000000000000000000000000000000000000000..1564c89347b4b7934b978c8f4ae383851b6d18d5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_p_o_s_t.py @@ -0,0 +1,319 @@ +from fontTools import ttLib +from fontTools.ttLib.standardGlyphOrder import standardGlyphOrder +from fontTools.misc import sstruct +from fontTools.misc.textTools import bytechr, byteord, tobytes, tostr, safeEval, readHex +from . import DefaultTable +import sys +import struct +import array +import logging + +log = logging.getLogger(__name__) + +postFormat = """ + > + formatType: 16.16F + italicAngle: 16.16F # italic angle in degrees + underlinePosition: h + underlineThickness: h + isFixedPitch: L + minMemType42: L # minimum memory if TrueType font is downloaded + maxMemType42: L # maximum memory if TrueType font is downloaded + minMemType1: L # minimum memory if Type1 font is downloaded + maxMemType1: L # maximum memory if Type1 font is downloaded +""" + +postFormatSize = sstruct.calcsize(postFormat) + + +class table__p_o_s_t(DefaultTable.DefaultTable): + """PostScript table + + The ``post`` table contains information needed to use the font on + PostScript printers, including the PostScript names of glyphs and + data that was stored in the ``FontInfo`` dictionary for Type 1 fonts. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/post + """ + + def decompile(self, data, ttFont): + sstruct.unpack(postFormat, data[:postFormatSize], self) + data = data[postFormatSize:] + if self.formatType == 1.0: + self.decode_format_1_0(data, ttFont) + elif self.formatType == 2.0: + self.decode_format_2_0(data, ttFont) + elif self.formatType == 3.0: + self.decode_format_3_0(data, ttFont) + elif self.formatType == 4.0: + self.decode_format_4_0(data, ttFont) + else: + # supported format + raise ttLib.TTLibError( + "'post' table format %f not supported" % self.formatType + ) + + def compile(self, ttFont): + data = sstruct.pack(postFormat, self) + if self.formatType == 1.0: + pass # we're done + elif self.formatType == 2.0: + data = data + self.encode_format_2_0(ttFont) + elif self.formatType == 3.0: + pass # we're done + elif self.formatType == 4.0: + data = data + self.encode_format_4_0(ttFont) + else: + # supported format + raise ttLib.TTLibError( + "'post' table format %f not supported" % self.formatType + ) + return data + + def getGlyphOrder(self): + """This function will get called by a ttLib.TTFont instance. + Do not call this function yourself, use TTFont().getGlyphOrder() + or its relatives instead! + """ + if not hasattr(self, "glyphOrder"): + raise ttLib.TTLibError("illegal use of getGlyphOrder()") + glyphOrder = self.glyphOrder + del self.glyphOrder + return glyphOrder + + def decode_format_1_0(self, data, ttFont): + self.glyphOrder = standardGlyphOrder[: ttFont["maxp"].numGlyphs] + + def decode_format_2_0(self, data, ttFont): + (numGlyphs,) = struct.unpack(">H", data[:2]) + numGlyphs = int(numGlyphs) + if numGlyphs > ttFont["maxp"].numGlyphs: + # Assume the numGlyphs field is bogus, so sync with maxp. + # I've seen this in one font, and if the assumption is + # wrong elsewhere, well, so be it: it's hard enough to + # work around _one_ non-conforming post format... + numGlyphs = ttFont["maxp"].numGlyphs + data = data[2:] + indices = array.array("H") + indices.frombytes(data[: 2 * numGlyphs]) + if sys.byteorder != "big": + indices.byteswap() + data = data[2 * numGlyphs :] + maxIndex = max(indices) + self.extraNames = extraNames = unpackPStrings(data, maxIndex - 257) + self.glyphOrder = glyphOrder = [""] * int(ttFont["maxp"].numGlyphs) + for glyphID in range(numGlyphs): + index = indices[glyphID] + if index > 257: + try: + name = extraNames[index - 258] + except IndexError: + name = "" + else: + # fetch names from standard list + name = standardGlyphOrder[index] + glyphOrder[glyphID] = name + self.build_psNameMapping(ttFont) + + def build_psNameMapping(self, ttFont): + mapping = {} + allNames = {} + glyphOrderNames = set(self.glyphOrder) + for i in range(ttFont["maxp"].numGlyphs): + glyphName = psName = self.glyphOrder[i] + if glyphName == "": + glyphName = "glyph%.5d" % i + + if glyphName in allNames: + # make up a new glyphName that's unique + n = allNames[glyphName] + # check if the glyph name exists in the glyph order + while f"{glyphName}.{n}" in glyphOrderNames: + n += 1 + allNames[glyphName] = n + 1 + glyphName = f"{glyphName}.{n}" + + allNames[glyphName] = 1 + if glyphName != psName: + self.glyphOrder[i] = glyphName + mapping[glyphName] = psName + + self.mapping = mapping + + def decode_format_3_0(self, data, ttFont): + # Setting self.glyphOrder to None will cause the TTFont object + # try and construct glyph names from a Unicode cmap table. + self.glyphOrder = None + + def decode_format_4_0(self, data, ttFont): + from fontTools import agl + + numGlyphs = ttFont["maxp"].numGlyphs + indices = array.array("H") + indices.frombytes(data) + if sys.byteorder != "big": + indices.byteswap() + # In some older fonts, the size of the post table doesn't match + # the number of glyphs. Sometimes it's bigger, sometimes smaller. + self.glyphOrder = glyphOrder = [""] * int(numGlyphs) + for i in range(min(len(indices), numGlyphs)): + if indices[i] == 0xFFFF: + self.glyphOrder[i] = "" + elif indices[i] in agl.UV2AGL: + self.glyphOrder[i] = agl.UV2AGL[indices[i]] + else: + self.glyphOrder[i] = "uni%04X" % indices[i] + self.build_psNameMapping(ttFont) + + def encode_format_2_0(self, ttFont): + numGlyphs = ttFont["maxp"].numGlyphs + glyphOrder = ttFont.getGlyphOrder() + assert len(glyphOrder) == numGlyphs + indices = array.array("H") + extraDict = {} + extraNames = self.extraNames = [ + n for n in self.extraNames if n not in standardGlyphOrder + ] + for i, name in enumerate(extraNames): + extraDict[name] = i + for glyphName in glyphOrder: + if glyphName in self.mapping: + psName = self.mapping[glyphName] + else: + psName = glyphName + if psName in extraDict: + index = 258 + extraDict[psName] + elif psName in standardGlyphOrder: + index = standardGlyphOrder.index(psName) + else: + index = 258 + len(extraNames) + extraDict[psName] = len(extraNames) + extraNames.append(psName) + indices.append(index) + if sys.byteorder != "big": + indices.byteswap() + return ( + struct.pack(">H", numGlyphs) + indices.tobytes() + packPStrings(extraNames) + ) + + def encode_format_4_0(self, ttFont): + from fontTools import agl + + numGlyphs = ttFont["maxp"].numGlyphs + glyphOrder = ttFont.getGlyphOrder() + assert len(glyphOrder) == numGlyphs + indices = array.array("H") + for glyphID in glyphOrder: + glyphID = glyphID.split("#")[0] + if glyphID in agl.AGL2UV: + indices.append(agl.AGL2UV[glyphID]) + elif len(glyphID) == 7 and glyphID[:3] == "uni": + indices.append(int(glyphID[3:], 16)) + else: + indices.append(0xFFFF) + if sys.byteorder != "big": + indices.byteswap() + return indices.tobytes() + + def toXML(self, writer, ttFont): + formatstring, names, fixes = sstruct.getformat(postFormat) + for name in names: + value = getattr(self, name) + writer.simpletag(name, value=value) + writer.newline() + if hasattr(self, "mapping"): + writer.begintag("psNames") + writer.newline() + writer.comment( + "This file uses unique glyph names based on the information\n" + "found in the 'post' table. Since these names might not be unique,\n" + "we have to invent artificial names in case of clashes. In order to\n" + "be able to retain the original information, we need a name to\n" + "ps name mapping for those cases where they differ. That's what\n" + "you see below.\n" + ) + writer.newline() + items = sorted(self.mapping.items()) + for name, psName in items: + writer.simpletag("psName", name=name, psName=psName) + writer.newline() + writer.endtag("psNames") + writer.newline() + if hasattr(self, "extraNames"): + writer.begintag("extraNames") + writer.newline() + writer.comment( + "following are the name that are not taken from the standard Mac glyph order" + ) + writer.newline() + for name in self.extraNames: + writer.simpletag("psName", name=name) + writer.newline() + writer.endtag("extraNames") + writer.newline() + if hasattr(self, "data"): + writer.begintag("hexdata") + writer.newline() + writer.dumphex(self.data) + writer.endtag("hexdata") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name not in ("psNames", "extraNames", "hexdata"): + setattr(self, name, safeEval(attrs["value"])) + elif name == "psNames": + self.mapping = {} + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name == "psName": + self.mapping[attrs["name"]] = attrs["psName"] + elif name == "extraNames": + self.extraNames = [] + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + if name == "psName": + self.extraNames.append(attrs["name"]) + else: + self.data = readHex(content) + + +def unpackPStrings(data, n): + # extract n Pascal strings from data. + # if there is not enough data, use "" + + strings = [] + index = 0 + dataLen = len(data) + + for _ in range(n): + if dataLen <= index: + length = 0 + else: + length = byteord(data[index]) + index += 1 + + if dataLen <= index + length - 1: + name = "" + else: + name = tostr(data[index : index + length], encoding="latin1") + strings.append(name) + index += length + + if index < dataLen: + log.warning("%d extra bytes in post.stringData array", dataLen - index) + + elif dataLen < index: + log.warning("not enough data in post.stringData array") + + return strings + + +def packPStrings(strings): + data = b"" + for s in strings: + data = data + bytechr(len(s)) + tobytes(s, encoding="latin1") + return data diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_p_r_e_p.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_p_r_e_p.py new file mode 100644 index 0000000000000000000000000000000000000000..cf4a5dd24f27ab08082cf9976bc2f5a9e1a967a5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_p_r_e_p.py @@ -0,0 +1,16 @@ +from fontTools import ttLib + +superclass = ttLib.getTableClass("fpgm") + + +class table__p_r_e_p(superclass): + """Control Value Program table + + The ``prep`` table contains TrueType instructions that can makee font-wide + alterations to the Control Value Table. It may potentially be executed + before any glyph is processed. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/prep + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_p_r_o_p.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_p_r_o_p.py new file mode 100644 index 0000000000000000000000000000000000000000..1d7de8098de797268cd14607939e78e0c5c7bf5a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_p_r_o_p.py @@ -0,0 +1,12 @@ +from .otBase import BaseTTXConverter + + +# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6prop.html +class table__p_r_o_p(BaseTTXConverter): + """The AAT ``prop`` table can store a variety of per-glyph properties, such as + Unicode directionality or whether glyphs are non-spacing marks. + + See also https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6prop.html + """ + + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_s_b_i_x.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_s_b_i_x.py new file mode 100644 index 0000000000000000000000000000000000000000..a282ea9a60d1a1e5f58747db6079d7c493504295 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_s_b_i_x.py @@ -0,0 +1,129 @@ +from fontTools.misc import sstruct +from fontTools.misc.textTools import safeEval, num2binary, binary2num +from . import DefaultTable +from .sbixStrike import Strike + + +sbixHeaderFormat = """ + > + version: H # Version number (set to 1) + flags: H # The only two bits used in the flags field are bits 0 + # and 1. For historical reasons, bit 0 must always be 1. + # Bit 1 is a sbixDrawOutlines flag and is interpreted as + # follows: + # 0: Draw only 'sbix' bitmaps + # 1: Draw both 'sbix' bitmaps and outlines, in that + # order + numStrikes: L # Number of bitmap strikes to follow +""" +sbixHeaderFormatSize = sstruct.calcsize(sbixHeaderFormat) + + +sbixStrikeOffsetFormat = """ + > + strikeOffset: L # Offset from begining of table to data for the + # individual strike +""" +sbixStrikeOffsetFormatSize = sstruct.calcsize(sbixStrikeOffsetFormat) + + +class table__s_b_i_x(DefaultTable.DefaultTable): + """Standard Bitmap Graphics table + + The ``sbix`` table stores bitmap image data in standard graphics formats + like JPEG, PNG, or TIFF. The glyphs for which the ``sbix`` table provides + data are indexed by Glyph ID. For each such glyph, the ``sbix`` table can + hold different data for different sizes, called "strikes." + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/sbix + """ + + def __init__(self, tag=None): + DefaultTable.DefaultTable.__init__(self, tag) + self.version = 1 + self.flags = 1 + self.numStrikes = 0 + self.strikes = {} + self.strikeOffsets = [] + + def decompile(self, data, ttFont): + # read table header + sstruct.unpack(sbixHeaderFormat, data[:sbixHeaderFormatSize], self) + # collect offsets to individual strikes in self.strikeOffsets + for i in range(self.numStrikes): + current_offset = sbixHeaderFormatSize + i * sbixStrikeOffsetFormatSize + offset_entry = sbixStrikeOffset() + sstruct.unpack( + sbixStrikeOffsetFormat, + data[current_offset : current_offset + sbixStrikeOffsetFormatSize], + offset_entry, + ) + self.strikeOffsets.append(offset_entry.strikeOffset) + + # decompile Strikes + for i in range(self.numStrikes - 1, -1, -1): + current_strike = Strike(rawdata=data[self.strikeOffsets[i] :]) + data = data[: self.strikeOffsets[i]] + current_strike.decompile(ttFont) + # print " Strike length: %xh" % len(bitmapSetData) + # print "Number of Glyph entries:", len(current_strike.glyphs) + if current_strike.ppem in self.strikes: + from fontTools import ttLib + + raise ttLib.TTLibError("Pixel 'ppem' must be unique for each Strike") + self.strikes[current_strike.ppem] = current_strike + + # after the glyph data records have been extracted, we don't need the offsets anymore + del self.strikeOffsets + del self.numStrikes + + def compile(self, ttFont): + sbixData = b"" + self.numStrikes = len(self.strikes) + sbixHeader = sstruct.pack(sbixHeaderFormat, self) + + # calculate offset to start of first strike + setOffset = sbixHeaderFormatSize + sbixStrikeOffsetFormatSize * self.numStrikes + + for si in sorted(self.strikes.keys()): + current_strike = self.strikes[si] + current_strike.compile(ttFont) + # append offset to this strike to table header + current_strike.strikeOffset = setOffset + sbixHeader += sstruct.pack(sbixStrikeOffsetFormat, current_strike) + setOffset += len(current_strike.data) + sbixData += current_strike.data + + return sbixHeader + sbixData + + def toXML(self, xmlWriter, ttFont): + xmlWriter.simpletag("version", value=self.version) + xmlWriter.newline() + xmlWriter.simpletag("flags", value=num2binary(self.flags, 16)) + xmlWriter.newline() + for i in sorted(self.strikes.keys()): + self.strikes[i].toXML(xmlWriter, ttFont) + + def fromXML(self, name, attrs, content, ttFont): + if name == "version": + setattr(self, name, safeEval(attrs["value"])) + elif name == "flags": + setattr(self, name, binary2num(attrs["value"])) + elif name == "strike": + current_strike = Strike() + for element in content: + if isinstance(element, tuple): + name, attrs, content = element + current_strike.fromXML(name, attrs, content, ttFont) + self.strikes[current_strike.ppem] = current_strike + else: + from fontTools import ttLib + + raise ttLib.TTLibError("can't handle '%s' element" % name) + + +# Helper classes + + +class sbixStrikeOffset(object): + pass diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_t_r_a_k.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_t_r_a_k.py new file mode 100644 index 0000000000000000000000000000000000000000..b0e8e19e08a87514a252b96a6836a442646e484c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_t_r_a_k.py @@ -0,0 +1,332 @@ +from fontTools.misc import sstruct +from fontTools.misc.fixedTools import ( + fixedToFloat as fi2fl, + floatToFixed as fl2fi, + floatToFixedToStr as fl2str, + strToFixedToFloat as str2fl, +) +from fontTools.misc.textTools import bytesjoin, safeEval +from fontTools.ttLib import TTLibError +from . import DefaultTable +import struct +from collections.abc import MutableMapping + + +# Apple's documentation of 'trak': +# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6trak.html + +TRAK_HEADER_FORMAT = """ + > # big endian + version: 16.16F + format: H + horizOffset: H + vertOffset: H + reserved: H +""" + +TRAK_HEADER_FORMAT_SIZE = sstruct.calcsize(TRAK_HEADER_FORMAT) + + +TRACK_DATA_FORMAT = """ + > # big endian + nTracks: H + nSizes: H + sizeTableOffset: L +""" + +TRACK_DATA_FORMAT_SIZE = sstruct.calcsize(TRACK_DATA_FORMAT) + + +TRACK_TABLE_ENTRY_FORMAT = """ + > # big endian + track: 16.16F + nameIndex: H + offset: H +""" + +TRACK_TABLE_ENTRY_FORMAT_SIZE = sstruct.calcsize(TRACK_TABLE_ENTRY_FORMAT) + + +# size values are actually '16.16F' fixed-point values, but here I do the +# fixedToFloat conversion manually instead of relying on sstruct +SIZE_VALUE_FORMAT = ">l" +SIZE_VALUE_FORMAT_SIZE = struct.calcsize(SIZE_VALUE_FORMAT) + +# per-Size values are in 'FUnits', i.e. 16-bit signed integers +PER_SIZE_VALUE_FORMAT = ">h" +PER_SIZE_VALUE_FORMAT_SIZE = struct.calcsize(PER_SIZE_VALUE_FORMAT) + + +class table__t_r_a_k(DefaultTable.DefaultTable): + """The AAT ``trak`` table can store per-size adjustments to each glyph's + sidebearings to make when tracking is enabled, which applications can + use to provide more visually balanced line spacing. + + See also https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6trak.html + """ + + dependencies = ["name"] + + def compile(self, ttFont): + dataList = [] + offset = TRAK_HEADER_FORMAT_SIZE + for direction in ("horiz", "vert"): + trackData = getattr(self, direction + "Data", TrackData()) + offsetName = direction + "Offset" + # set offset to 0 if None or empty + if not trackData: + setattr(self, offsetName, 0) + continue + # TrackData table format must be longword aligned + alignedOffset = (offset + 3) & ~3 + padding, offset = b"\x00" * (alignedOffset - offset), alignedOffset + setattr(self, offsetName, offset) + + data = trackData.compile(offset) + offset += len(data) + dataList.append(padding + data) + + self.reserved = 0 + tableData = bytesjoin([sstruct.pack(TRAK_HEADER_FORMAT, self)] + dataList) + return tableData + + def decompile(self, data, ttFont): + sstruct.unpack(TRAK_HEADER_FORMAT, data[:TRAK_HEADER_FORMAT_SIZE], self) + for direction in ("horiz", "vert"): + trackData = TrackData() + offset = getattr(self, direction + "Offset") + if offset != 0: + trackData.decompile(data, offset) + setattr(self, direction + "Data", trackData) + + def toXML(self, writer, ttFont): + writer.simpletag("version", value=self.version) + writer.newline() + writer.simpletag("format", value=self.format) + writer.newline() + for direction in ("horiz", "vert"): + dataName = direction + "Data" + writer.begintag(dataName) + writer.newline() + trackData = getattr(self, dataName, TrackData()) + trackData.toXML(writer, ttFont) + writer.endtag(dataName) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "version": + self.version = safeEval(attrs["value"]) + elif name == "format": + self.format = safeEval(attrs["value"]) + elif name in ("horizData", "vertData"): + trackData = TrackData() + setattr(self, name, trackData) + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content_ = element + trackData.fromXML(name, attrs, content_, ttFont) + + +class TrackData(MutableMapping): + def __init__(self, initialdata={}): + self._map = dict(initialdata) + + def compile(self, offset): + nTracks = len(self) + sizes = self.sizes() + nSizes = len(sizes) + + # offset to the start of the size subtable + offset += TRACK_DATA_FORMAT_SIZE + TRACK_TABLE_ENTRY_FORMAT_SIZE * nTracks + trackDataHeader = sstruct.pack( + TRACK_DATA_FORMAT, + {"nTracks": nTracks, "nSizes": nSizes, "sizeTableOffset": offset}, + ) + + entryDataList = [] + perSizeDataList = [] + # offset to per-size tracking values + offset += SIZE_VALUE_FORMAT_SIZE * nSizes + # sort track table entries by track value + for track, entry in sorted(self.items()): + assert entry.nameIndex is not None + entry.track = track + entry.offset = offset + entryDataList += [sstruct.pack(TRACK_TABLE_ENTRY_FORMAT, entry)] + # sort per-size values by size + for size, value in sorted(entry.items()): + perSizeDataList += [struct.pack(PER_SIZE_VALUE_FORMAT, value)] + offset += PER_SIZE_VALUE_FORMAT_SIZE * nSizes + # sort size values + sizeDataList = [ + struct.pack(SIZE_VALUE_FORMAT, fl2fi(sv, 16)) for sv in sorted(sizes) + ] + + data = bytesjoin( + [trackDataHeader] + entryDataList + sizeDataList + perSizeDataList + ) + return data + + def decompile(self, data, offset): + # initial offset is from the start of trak table to the current TrackData + trackDataHeader = data[offset : offset + TRACK_DATA_FORMAT_SIZE] + if len(trackDataHeader) != TRACK_DATA_FORMAT_SIZE: + raise TTLibError("not enough data to decompile TrackData header") + sstruct.unpack(TRACK_DATA_FORMAT, trackDataHeader, self) + offset += TRACK_DATA_FORMAT_SIZE + + nSizes = self.nSizes + sizeTableOffset = self.sizeTableOffset + sizeTable = [] + for i in range(nSizes): + sizeValueData = data[ + sizeTableOffset : sizeTableOffset + SIZE_VALUE_FORMAT_SIZE + ] + if len(sizeValueData) < SIZE_VALUE_FORMAT_SIZE: + raise TTLibError("not enough data to decompile TrackData size subtable") + (sizeValue,) = struct.unpack(SIZE_VALUE_FORMAT, sizeValueData) + sizeTable.append(fi2fl(sizeValue, 16)) + sizeTableOffset += SIZE_VALUE_FORMAT_SIZE + + for i in range(self.nTracks): + entry = TrackTableEntry() + entryData = data[offset : offset + TRACK_TABLE_ENTRY_FORMAT_SIZE] + if len(entryData) < TRACK_TABLE_ENTRY_FORMAT_SIZE: + raise TTLibError("not enough data to decompile TrackTableEntry record") + sstruct.unpack(TRACK_TABLE_ENTRY_FORMAT, entryData, entry) + perSizeOffset = entry.offset + for j in range(nSizes): + size = sizeTable[j] + perSizeValueData = data[ + perSizeOffset : perSizeOffset + PER_SIZE_VALUE_FORMAT_SIZE + ] + if len(perSizeValueData) < PER_SIZE_VALUE_FORMAT_SIZE: + raise TTLibError( + "not enough data to decompile per-size track values" + ) + (perSizeValue,) = struct.unpack(PER_SIZE_VALUE_FORMAT, perSizeValueData) + entry[size] = perSizeValue + perSizeOffset += PER_SIZE_VALUE_FORMAT_SIZE + self[entry.track] = entry + offset += TRACK_TABLE_ENTRY_FORMAT_SIZE + + def toXML(self, writer, ttFont): + nTracks = len(self) + nSizes = len(self.sizes()) + writer.comment("nTracks=%d, nSizes=%d" % (nTracks, nSizes)) + writer.newline() + for track, entry in sorted(self.items()): + assert entry.nameIndex is not None + entry.track = track + entry.toXML(writer, ttFont) + + def fromXML(self, name, attrs, content, ttFont): + if name != "trackEntry": + return + entry = TrackTableEntry() + entry.fromXML(name, attrs, content, ttFont) + self[entry.track] = entry + + def sizes(self): + if not self: + return frozenset() + tracks = list(self.tracks()) + sizes = self[tracks.pop(0)].sizes() + for track in tracks: + entrySizes = self[track].sizes() + if sizes != entrySizes: + raise TTLibError( + "'trak' table entries must specify the same sizes: " + "%s != %s" % (sorted(sizes), sorted(entrySizes)) + ) + return frozenset(sizes) + + def __getitem__(self, track): + return self._map[track] + + def __delitem__(self, track): + del self._map[track] + + def __setitem__(self, track, entry): + self._map[track] = entry + + def __len__(self): + return len(self._map) + + def __iter__(self): + return iter(self._map) + + def keys(self): + return self._map.keys() + + tracks = keys + + def __repr__(self): + return "TrackData({})".format(self._map if self else "") + + +class TrackTableEntry(MutableMapping): + def __init__(self, values={}, nameIndex=None): + self.nameIndex = nameIndex + self._map = dict(values) + + def toXML(self, writer, ttFont): + name = ttFont["name"].getDebugName(self.nameIndex) + writer.begintag( + "trackEntry", + (("value", fl2str(self.track, 16)), ("nameIndex", self.nameIndex)), + ) + writer.newline() + if name: + writer.comment(name) + writer.newline() + for size, perSizeValue in sorted(self.items()): + writer.simpletag("track", size=fl2str(size, 16), value=perSizeValue) + writer.newline() + writer.endtag("trackEntry") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + self.track = str2fl(attrs["value"], 16) + self.nameIndex = safeEval(attrs["nameIndex"]) + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, _ = element + if name != "track": + continue + size = str2fl(attrs["size"], 16) + self[size] = safeEval(attrs["value"]) + + def __getitem__(self, size): + return self._map[size] + + def __delitem__(self, size): + del self._map[size] + + def __setitem__(self, size, value): + self._map[size] = value + + def __len__(self): + return len(self._map) + + def __iter__(self): + return iter(self._map) + + def keys(self): + return self._map.keys() + + sizes = keys + + def __repr__(self): + return "TrackTableEntry({}, nameIndex={})".format(self._map, self.nameIndex) + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return self.nameIndex == other.nameIndex and dict(self) == dict(other) + + def __ne__(self, other): + result = self.__eq__(other) + return result if result is NotImplemented else not result diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_v_h_e_a.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_v_h_e_a.py new file mode 100644 index 0000000000000000000000000000000000000000..9c6fa3aefe2e91c042948b4d21a7df3e8087a17c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_v_h_e_a.py @@ -0,0 +1,139 @@ +from fontTools.misc import sstruct +from fontTools.misc.textTools import safeEval +from fontTools.misc.fixedTools import ( + ensureVersionIsLong as fi2ve, + versionToFixed as ve2fi, +) +from . import DefaultTable +import math + + +vheaFormat = """ + > # big endian + tableVersion: L + ascent: h + descent: h + lineGap: h + advanceHeightMax: H + minTopSideBearing: h + minBottomSideBearing: h + yMaxExtent: h + caretSlopeRise: h + caretSlopeRun: h + caretOffset: h + reserved1: h + reserved2: h + reserved3: h + reserved4: h + metricDataFormat: h + numberOfVMetrics: H +""" + + +class table__v_h_e_a(DefaultTable.DefaultTable): + """Vertical Header table + + The ``vhea`` table contains information needed during vertical + text layout. + + .. note:: + This converter class is kept in sync with the :class:`._h_h_e_a.table__h_h_e_a` + table constructor. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/vhea + """ + + # Note: Keep in sync with table__h_h_e_a + + dependencies = ["vmtx", "glyf", "CFF ", "CFF2"] + + def decompile(self, data, ttFont): + sstruct.unpack(vheaFormat, data, self) + + def compile(self, ttFont): + if ttFont.recalcBBoxes and ( + ttFont.isLoaded("glyf") + or ttFont.isLoaded("CFF ") + or ttFont.isLoaded("CFF2") + ): + self.recalc(ttFont) + self.tableVersion = fi2ve(self.tableVersion) + return sstruct.pack(vheaFormat, self) + + def recalc(self, ttFont): + if "vmtx" not in ttFont: + return + + vmtxTable = ttFont["vmtx"] + self.advanceHeightMax = max(adv for adv, _ in vmtxTable.metrics.values()) + + boundsHeightDict = {} + if "glyf" in ttFont: + glyfTable = ttFont["glyf"] + for name in ttFont.getGlyphOrder(): + g = glyfTable[name] + if g.numberOfContours == 0: + continue + if g.numberOfContours < 0 and not hasattr(g, "yMax"): + # Composite glyph without extents set. + # Calculate those. + g.recalcBounds(glyfTable) + boundsHeightDict[name] = g.yMax - g.yMin + elif "CFF " in ttFont or "CFF2" in ttFont: + if "CFF " in ttFont: + topDict = ttFont["CFF "].cff.topDictIndex[0] + else: + topDict = ttFont["CFF2"].cff.topDictIndex[0] + charStrings = topDict.CharStrings + for name in ttFont.getGlyphOrder(): + cs = charStrings[name] + bounds = cs.calcBounds(charStrings) + if bounds is not None: + boundsHeightDict[name] = int( + math.ceil(bounds[3]) - math.floor(bounds[1]) + ) + + if boundsHeightDict: + minTopSideBearing = float("inf") + minBottomSideBearing = float("inf") + yMaxExtent = -float("inf") + for name, boundsHeight in boundsHeightDict.items(): + advanceHeight, tsb = vmtxTable[name] + bsb = advanceHeight - tsb - boundsHeight + extent = tsb + boundsHeight + minTopSideBearing = min(minTopSideBearing, tsb) + minBottomSideBearing = min(minBottomSideBearing, bsb) + yMaxExtent = max(yMaxExtent, extent) + self.minTopSideBearing = minTopSideBearing + self.minBottomSideBearing = minBottomSideBearing + self.yMaxExtent = yMaxExtent + + else: # No glyph has outlines. + self.minTopSideBearing = 0 + self.minBottomSideBearing = 0 + self.yMaxExtent = 0 + + def toXML(self, writer, ttFont): + formatstring, names, fixes = sstruct.getformat(vheaFormat) + for name in names: + value = getattr(self, name) + if name == "tableVersion": + value = fi2ve(value) + value = "0x%08x" % value + writer.simpletag(name, value=value) + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "tableVersion": + setattr(self, name, ve2fi(attrs["value"])) + return + setattr(self, name, safeEval(attrs["value"])) + + # reserved0 is caretOffset for legacy reasons + @property + def reserved0(self): + return self.caretOffset + + @reserved0.setter + def reserved0(self, value): + self.caretOffset = value diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_v_m_t_x.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_v_m_t_x.py new file mode 100644 index 0000000000000000000000000000000000000000..32662fc6a257e9bb3da60b259756d8f9f7fa7919 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/_v_m_t_x.py @@ -0,0 +1,19 @@ +from fontTools import ttLib + +superclass = ttLib.getTableClass("hmtx") + + +class table__v_m_t_x(superclass): + """Vertical Metrics table + + The ``vmtx`` table contains per-glyph metrics for the glyphs in a + ``glyf``, ``CFF ``, or ``CFF2`` table, as needed for vertical text + layout. + + See also https://learn.microsoft.com/en-us/typography/opentype/spec/vmtx + """ + + headerTag = "vhea" + advanceName = "height" + sideBearingName = "tsb" + numberOfMetricsName = "numberOfVMetrics" diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/asciiTable.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/asciiTable.py new file mode 100644 index 0000000000000000000000000000000000000000..6f81c526b372b268b253da47c337715e316ee4d4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/asciiTable.py @@ -0,0 +1,20 @@ +from fontTools.misc.textTools import strjoin, tobytes, tostr +from . import DefaultTable + + +class asciiTable(DefaultTable.DefaultTable): + def toXML(self, writer, ttFont): + data = tostr(self.data) + # removing null bytes. XXX needed?? + data = data.split("\0") + data = strjoin(data) + writer.begintag("source") + writer.newline() + writer.write_noindent(data) + writer.newline() + writer.endtag("source") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + lines = strjoin(content).split("\n") + self.data = tobytes("\n".join(lines[1:-1])) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/grUtils.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/grUtils.py new file mode 100644 index 0000000000000000000000000000000000000000..785684b1eb30a76ae598bfe46416d4556fc422a0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/grUtils.py @@ -0,0 +1,92 @@ +import struct, warnings + +try: + import lz4 +except ImportError: + lz4 = None +else: + import lz4.block + +# old scheme for VERSION < 0.9 otherwise use lz4.block + + +def decompress(data): + (compression,) = struct.unpack(">L", data[4:8]) + scheme = compression >> 27 + size = compression & 0x07FFFFFF + if scheme == 0: + pass + elif scheme == 1 and lz4: + res = lz4.block.decompress(struct.pack("<L", size) + data[8:]) + if len(res) != size: + warnings.warn("Table decompression failed.") + else: + data = res + else: + warnings.warn("Table is compressed with an unsupported compression scheme") + return (data, scheme) + + +def compress(scheme, data): + hdr = data[:4] + struct.pack(">L", (scheme << 27) + (len(data) & 0x07FFFFFF)) + if scheme == 0: + return data + elif scheme == 1 and lz4: + res = lz4.block.compress( + data, mode="high_compression", compression=16, store_size=False + ) + return hdr + res + else: + warnings.warn("Table failed to compress by unsupported compression scheme") + return data + + +def _entries(attrs, sameval): + ak = 0 + vals = [] + lastv = 0 + for k, v in attrs: + if len(vals) and (k != ak + 1 or (sameval and v != lastv)): + yield (ak - len(vals) + 1, len(vals), vals) + vals = [] + ak = k + vals.append(v) + lastv = v + yield (ak - len(vals) + 1, len(vals), vals) + + +def entries(attributes, sameval=False): + g = _entries(sorted(attributes.items(), key=lambda x: int(x[0])), sameval) + return g + + +def bininfo(num, size=1): + if num == 0: + return struct.pack(">4H", 0, 0, 0, 0) + srange = 1 + select = 0 + while srange <= num: + srange *= 2 + select += 1 + select -= 1 + srange //= 2 + srange *= size + shift = num * size - srange + return struct.pack(">4H", num, srange, select, shift) + + +def num2tag(n): + if n < 0x200000: + return str(n) + else: + return ( + struct.unpack("4s", struct.pack(">L", n))[0].replace(b"\000", b"").decode() + ) + + +def tag2num(n): + try: + return int(n) + except ValueError: + n = (n + " ")[:4] + return struct.unpack(">L", n.encode("ascii"))[0] diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/otBase.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/otBase.py new file mode 100644 index 0000000000000000000000000000000000000000..41557cfa4b41f2531fe4b930c29551e960d1d1ce --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/otBase.py @@ -0,0 +1,1458 @@ +from fontTools.config import OPTIONS +from fontTools.misc.textTools import Tag, bytesjoin +from .DefaultTable import DefaultTable +from enum import IntEnum +import sys +import array +import struct +import logging +from functools import lru_cache +from typing import Iterator, NamedTuple, Optional, Tuple + +log = logging.getLogger(__name__) + +have_uharfbuzz = False +try: + import uharfbuzz as hb + + have_uharfbuzz = True +except ImportError: + pass + +USE_HARFBUZZ_REPACKER = OPTIONS[f"{__name__}:USE_HARFBUZZ_REPACKER"] + + +class OverflowErrorRecord(object): + def __init__(self, overflowTuple): + self.tableType = overflowTuple[0] + self.LookupListIndex = overflowTuple[1] + self.SubTableIndex = overflowTuple[2] + self.itemName = overflowTuple[3] + self.itemIndex = overflowTuple[4] + + def __repr__(self): + return str( + ( + self.tableType, + "LookupIndex:", + self.LookupListIndex, + "SubTableIndex:", + self.SubTableIndex, + "ItemName:", + self.itemName, + "ItemIndex:", + self.itemIndex, + ) + ) + + +class OTLOffsetOverflowError(Exception): + def __init__(self, overflowErrorRecord): + self.value = overflowErrorRecord + + def __str__(self): + return repr(self.value) + + +class RepackerState(IntEnum): + # Repacking control flow is implemnted using a state machine. The state machine table: + # + # State | Packing Success | Packing Failed | Exception Raised | + # ------------+-----------------+----------------+------------------+ + # PURE_FT | Return result | PURE_FT | Return failure | + # HB_FT | Return result | HB_FT | FT_FALLBACK | + # FT_FALLBACK | HB_FT | FT_FALLBACK | Return failure | + + # Pack only with fontTools, don't allow sharing between extensions. + PURE_FT = 1 + + # Attempt to pack with harfbuzz (allowing sharing between extensions) + # use fontTools to attempt overflow resolution. + HB_FT = 2 + + # Fallback if HB/FT packing gets stuck. Pack only with fontTools, don't allow sharing between + # extensions. + FT_FALLBACK = 3 + + +class BaseTTXConverter(DefaultTable): + """Generic base class for TTX table converters. It functions as an + adapter between the TTX (ttLib actually) table model and the model + we use for OpenType tables, which is necessarily subtly different. + """ + + def decompile(self, data, font): + """Create an object from the binary data. Called automatically on access.""" + from . import otTables + + reader = OTTableReader(data, tableTag=self.tableTag) + tableClass = getattr(otTables, self.tableTag) + self.table = tableClass() + self.table.decompile(reader, font) + + def compile(self, font): + """Compiles the table into binary. Called automatically on save.""" + + # General outline: + # Create a top-level OTTableWriter for the GPOS/GSUB table. + # Call the compile method for the the table + # for each 'converter' record in the table converter list + # call converter's write method for each item in the value. + # - For simple items, the write method adds a string to the + # writer's self.items list. + # - For Struct/Table/Subtable items, it add first adds new writer to the + # to the writer's self.items, then calls the item's compile method. + # This creates a tree of writers, rooted at the GUSB/GPOS writer, with + # each writer representing a table, and the writer.items list containing + # the child data strings and writers. + # call the getAllData method + # call _doneWriting, which removes duplicates + # call _gatherTables. This traverses the tables, adding unique occurences to a flat list of tables + # Traverse the flat list of tables, calling getDataLength on each to update their position + # Traverse the flat list of tables again, calling getData each get the data in the table, now that + # pos's and offset are known. + + # If a lookup subtable overflows an offset, we have to start all over. + overflowRecord = None + # this is 3-state option: default (None) means automatically use hb.repack or + # silently fall back if it fails; True, use it and raise error if not possible + # or it errors out; False, don't use it, even if you can. + use_hb_repack = font.cfg[USE_HARFBUZZ_REPACKER] + if self.tableTag in ("GSUB", "GPOS"): + if use_hb_repack is False: + log.debug( + "hb.repack disabled, compiling '%s' with pure-python serializer", + self.tableTag, + ) + elif not have_uharfbuzz: + if use_hb_repack is True: + raise ImportError("No module named 'uharfbuzz'") + else: + assert use_hb_repack is None + log.debug( + "uharfbuzz not found, compiling '%s' with pure-python serializer", + self.tableTag, + ) + + if ( + use_hb_repack in (None, True) + and have_uharfbuzz + and self.tableTag in ("GSUB", "GPOS") + ): + state = RepackerState.HB_FT + else: + state = RepackerState.PURE_FT + + hb_first_error_logged = False + lastOverflowRecord = None + while True: + try: + writer = OTTableWriter(tableTag=self.tableTag) + self.table.compile(writer, font) + if state == RepackerState.HB_FT: + return self.tryPackingHarfbuzz(writer, hb_first_error_logged) + elif state == RepackerState.PURE_FT: + return self.tryPackingFontTools(writer) + elif state == RepackerState.FT_FALLBACK: + # Run packing with FontTools only, but don't return the result as it will + # not be optimally packed. Once a successful packing has been found, state is + # changed back to harfbuzz packing to produce the final, optimal, packing. + self.tryPackingFontTools(writer) + log.debug( + "Re-enabling sharing between extensions and switching back to " + "harfbuzz+fontTools packing." + ) + state = RepackerState.HB_FT + + except OTLOffsetOverflowError as e: + hb_first_error_logged = True + ok = self.tryResolveOverflow(font, e, lastOverflowRecord) + lastOverflowRecord = e.value + + if ok: + continue + + if state is RepackerState.HB_FT: + log.debug( + "Harfbuzz packing out of resolutions, disabling sharing between extensions and " + "switching to fontTools only packing." + ) + state = RepackerState.FT_FALLBACK + else: + raise + + def tryPackingHarfbuzz(self, writer, hb_first_error_logged): + try: + log.debug("serializing '%s' with hb.repack", self.tableTag) + return writer.getAllDataUsingHarfbuzz(self.tableTag) + except (ValueError, MemoryError, hb.RepackerError) as e: + # Only log hb repacker errors the first time they occur in + # the offset-overflow resolution loop, they are just noisy. + # Maybe we can revisit this if/when uharfbuzz actually gives + # us more info as to why hb.repack failed... + if not hb_first_error_logged: + error_msg = f"{type(e).__name__}" + if str(e) != "": + error_msg += f": {e}" + log.warning( + "hb.repack failed to serialize '%s', attempting fonttools resolutions " + "; the error message was: %s", + self.tableTag, + error_msg, + ) + hb_first_error_logged = True + return writer.getAllData(remove_duplicate=False) + + def tryPackingFontTools(self, writer): + return writer.getAllData() + + def tryResolveOverflow(self, font, e, lastOverflowRecord): + ok = 0 + if lastOverflowRecord == e.value: + # Oh well... + return ok + + overflowRecord = e.value + log.info("Attempting to fix OTLOffsetOverflowError %s", e) + + if overflowRecord.itemName is None: + from .otTables import fixLookupOverFlows + + ok = fixLookupOverFlows(font, overflowRecord) + else: + from .otTables import fixSubTableOverFlows + + ok = fixSubTableOverFlows(font, overflowRecord) + + if ok: + return ok + + # Try upgrading lookup to Extension and hope + # that cross-lookup sharing not happening would + # fix overflow... + from .otTables import fixLookupOverFlows + + return fixLookupOverFlows(font, overflowRecord) + + def toXML(self, writer, font): + self.table.toXML2(writer, font) + + def fromXML(self, name, attrs, content, font): + from . import otTables + + if not hasattr(self, "table"): + tableClass = getattr(otTables, self.tableTag) + self.table = tableClass() + self.table.fromXML(name, attrs, content, font) + self.table.populateDefaults() + + def ensureDecompiled(self, recurse=True): + self.table.ensureDecompiled(recurse=recurse) + + +# https://github.com/fonttools/fonttools/pull/2285#issuecomment-834652928 +assert len(struct.pack("i", 0)) == 4 +assert array.array("i").itemsize == 4, "Oops, file a bug against fonttools." + + +class OTTableReader(object): + """Helper class to retrieve data from an OpenType table.""" + + __slots__ = ("data", "offset", "pos", "localState", "tableTag") + + def __init__(self, data, localState=None, offset=0, tableTag=None): + self.data = data + self.offset = offset + self.pos = offset + self.localState = localState + self.tableTag = tableTag + + def advance(self, count): + self.pos += count + + def seek(self, pos): + self.pos = pos + + def copy(self): + other = self.__class__(self.data, self.localState, self.offset, self.tableTag) + other.pos = self.pos + return other + + def getSubReader(self, offset): + offset = self.offset + offset + return self.__class__(self.data, self.localState, offset, self.tableTag) + + def readValue(self, typecode, staticSize): + pos = self.pos + newpos = pos + staticSize + (value,) = struct.unpack(f">{typecode}", self.data[pos:newpos]) + self.pos = newpos + return value + + def readArray(self, typecode, staticSize, count): + pos = self.pos + newpos = pos + count * staticSize + value = array.array(typecode, self.data[pos:newpos]) + if sys.byteorder != "big": + value.byteswap() + self.pos = newpos + return value.tolist() + + def readInt8(self): + return self.readValue("b", staticSize=1) + + def readInt8Array(self, count): + return self.readArray("b", staticSize=1, count=count) + + def readShort(self): + return self.readValue("h", staticSize=2) + + def readShortArray(self, count): + return self.readArray("h", staticSize=2, count=count) + + def readLong(self): + return self.readValue("i", staticSize=4) + + def readLongArray(self, count): + return self.readArray("i", staticSize=4, count=count) + + def readUInt8(self): + return self.readValue("B", staticSize=1) + + def readUInt8Array(self, count): + return self.readArray("B", staticSize=1, count=count) + + def readUShort(self): + return self.readValue("H", staticSize=2) + + def readUShortArray(self, count): + return self.readArray("H", staticSize=2, count=count) + + def readULong(self): + return self.readValue("I", staticSize=4) + + def readULongArray(self, count): + return self.readArray("I", staticSize=4, count=count) + + def readUInt24(self): + pos = self.pos + newpos = pos + 3 + (value,) = struct.unpack(">l", b"\0" + self.data[pos:newpos]) + self.pos = newpos + return value + + def readUInt24Array(self, count): + return [self.readUInt24() for _ in range(count)] + + def readTag(self): + pos = self.pos + newpos = pos + 4 + value = Tag(self.data[pos:newpos]) + assert len(value) == 4, value + self.pos = newpos + return value + + def readData(self, count): + pos = self.pos + newpos = pos + count + value = self.data[pos:newpos] + self.pos = newpos + return value + + def __setitem__(self, name, value): + state = self.localState.copy() if self.localState else dict() + state[name] = value + self.localState = state + + def __getitem__(self, name): + return self.localState and self.localState[name] + + def __contains__(self, name): + return self.localState and name in self.localState + + +class OffsetToWriter(object): + def __init__(self, subWriter, offsetSize): + self.subWriter = subWriter + self.offsetSize = offsetSize + + def __eq__(self, other): + if type(self) != type(other): + return NotImplemented + return self.subWriter == other.subWriter and self.offsetSize == other.offsetSize + + def __hash__(self): + # only works after self._doneWriting() has been called + return hash((self.subWriter, self.offsetSize)) + + +class OTTableWriter(object): + """Helper class to gather and assemble data for OpenType tables.""" + + def __init__(self, localState=None, tableTag=None): + self.items = [] + self.pos = None + self.localState = localState + self.tableTag = tableTag + self.parent = None + self.name = "<none>" + + def __setitem__(self, name, value): + state = self.localState.copy() if self.localState else dict() + state[name] = value + self.localState = state + + def __getitem__(self, name): + return self.localState[name] + + def __delitem__(self, name): + del self.localState[name] + + # assembler interface + + def getDataLength(self): + """Return the length of this table in bytes, without subtables.""" + l = 0 + for item in self.items: + if hasattr(item, "getCountData"): + l += item.size + elif hasattr(item, "subWriter"): + l += item.offsetSize + else: + l = l + len(item) + return l + + def getData(self): + """Assemble the data for this writer/table, without subtables.""" + items = list(self.items) # make a shallow copy + pos = self.pos + numItems = len(items) + for i in range(numItems): + item = items[i] + + if hasattr(item, "subWriter"): + if item.offsetSize == 4: + items[i] = packULong(item.subWriter.pos - pos) + elif item.offsetSize == 2: + try: + items[i] = packUShort(item.subWriter.pos - pos) + except struct.error: + # provide data to fix overflow problem. + overflowErrorRecord = self.getOverflowErrorRecord( + item.subWriter + ) + + raise OTLOffsetOverflowError(overflowErrorRecord) + elif item.offsetSize == 3: + items[i] = packUInt24(item.subWriter.pos - pos) + else: + raise ValueError(item.offsetSize) + + return bytesjoin(items) + + def getDataForHarfbuzz(self): + """Assemble the data for this writer/table with all offset field set to 0""" + items = list(self.items) + packFuncs = {2: packUShort, 3: packUInt24, 4: packULong} + for i, item in enumerate(items): + if hasattr(item, "subWriter"): + # Offset value is not needed in harfbuzz repacker, so setting offset to 0 to avoid overflow here + if item.offsetSize in packFuncs: + items[i] = packFuncs[item.offsetSize](0) + else: + raise ValueError(item.offsetSize) + + return bytesjoin(items) + + def __hash__(self): + # only works after self._doneWriting() has been called + return hash(self.items) + + def __ne__(self, other): + result = self.__eq__(other) + return result if result is NotImplemented else not result + + def __eq__(self, other): + if type(self) != type(other): + return NotImplemented + return self.items == other.items + + def _doneWriting(self, internedTables, shareExtension=False): + # Convert CountData references to data string items + # collapse duplicate table references to a unique entry + # "tables" are OTTableWriter objects. + + # For Extension Lookup types, we can + # eliminate duplicates only within the tree under the Extension Lookup, + # as offsets may exceed 64K even between Extension LookupTable subtables. + isExtension = hasattr(self, "Extension") + + # Certain versions of Uniscribe reject the font if the GSUB/GPOS top-level + # arrays (ScriptList, FeatureList, LookupList) point to the same, possibly + # empty, array. So, we don't share those. + # See: https://github.com/fonttools/fonttools/issues/518 + dontShare = hasattr(self, "DontShare") + + if isExtension and not shareExtension: + internedTables = {} + + items = self.items + for i, item in enumerate(items): + if hasattr(item, "getCountData"): + items[i] = item.getCountData() + elif hasattr(item, "subWriter"): + item.subWriter._doneWriting( + internedTables, shareExtension=shareExtension + ) + # At this point, all subwriters are hashable based on their items. + # (See hash and comparison magic methods above.) So the ``setdefault`` + # call here will return the first writer object we've seen with + # equal content, or store it in the dictionary if it's not been + # seen yet. We therefore replace the subwriter object with an equivalent + # object, which deduplicates the tree. + if not dontShare: + items[i].subWriter = internedTables.setdefault( + item.subWriter, item.subWriter + ) + self.items = tuple(items) + + def _gatherTables(self, tables, extTables, done): + # Convert table references in self.items tree to a flat + # list of tables in depth-first traversal order. + # "tables" are OTTableWriter objects. + # We do the traversal in reverse order at each level, in order to + # resolve duplicate references to be the last reference in the list of tables. + # For extension lookups, duplicate references can be merged only within the + # writer tree under the extension lookup. + + done[id(self)] = True + + numItems = len(self.items) + iRange = list(range(numItems)) + iRange.reverse() + + isExtension = hasattr(self, "Extension") + + selfTables = tables + + if isExtension: + assert ( + extTables is not None + ), "Program or XML editing error. Extension subtables cannot contain extensions subtables" + tables, extTables, done = extTables, None, {} + + # add Coverage table if it is sorted last. + sortCoverageLast = False + if hasattr(self, "sortCoverageLast"): + # Find coverage table + for i in range(numItems): + item = self.items[i] + if ( + hasattr(item, "subWriter") + and getattr(item.subWriter, "name", None) == "Coverage" + ): + sortCoverageLast = True + break + if id(item.subWriter) not in done: + item.subWriter._gatherTables(tables, extTables, done) + else: + # We're a new parent of item + pass + + for i in iRange: + item = self.items[i] + if not hasattr(item, "subWriter"): + continue + + if ( + sortCoverageLast + and (i == 1) + and getattr(item.subWriter, "name", None) == "Coverage" + ): + # we've already 'gathered' it above + continue + + if id(item.subWriter) not in done: + item.subWriter._gatherTables(tables, extTables, done) + else: + # Item is already written out by other parent + pass + + selfTables.append(self) + + def _gatherGraphForHarfbuzz(self, tables, obj_list, done, objidx, virtual_edges): + real_links = [] + virtual_links = [] + item_idx = objidx + + # Merge virtual_links from parent + for idx in virtual_edges: + virtual_links.append((0, 0, idx)) + + sortCoverageLast = False + coverage_idx = 0 + if hasattr(self, "sortCoverageLast"): + # Find coverage table + for i, item in enumerate(self.items): + if getattr(item, "name", None) == "Coverage": + sortCoverageLast = True + if id(item) not in done: + coverage_idx = item_idx = item._gatherGraphForHarfbuzz( + tables, obj_list, done, item_idx, virtual_edges + ) + else: + coverage_idx = done[id(item)] + virtual_edges.append(coverage_idx) + break + + child_idx = 0 + offset_pos = 0 + for i, item in enumerate(self.items): + if hasattr(item, "subWriter"): + pos = offset_pos + elif hasattr(item, "getCountData"): + offset_pos += item.size + continue + else: + offset_pos = offset_pos + len(item) + continue + + if id(item.subWriter) not in done: + child_idx = item_idx = item.subWriter._gatherGraphForHarfbuzz( + tables, obj_list, done, item_idx, virtual_edges + ) + else: + child_idx = done[id(item.subWriter)] + + real_edge = (pos, item.offsetSize, child_idx) + real_links.append(real_edge) + offset_pos += item.offsetSize + + tables.append(self) + obj_list.append((real_links, virtual_links)) + item_idx += 1 + done[id(self)] = item_idx + if sortCoverageLast: + virtual_edges.pop() + + return item_idx + + def getAllDataUsingHarfbuzz(self, tableTag): + """The Whole table is represented as a Graph. + Assemble graph data and call Harfbuzz repacker to pack the table. + Harfbuzz repacker is faster and retain as much sub-table sharing as possible, see also: + https://github.com/harfbuzz/harfbuzz/blob/main/docs/repacker.md + The input format for hb.repack() method is explained here: + https://github.com/harfbuzz/uharfbuzz/blob/main/src/uharfbuzz/_harfbuzz.pyx#L1149 + """ + internedTables = {} + self._doneWriting(internedTables, shareExtension=True) + tables = [] + obj_list = [] + done = {} + objidx = 0 + virtual_edges = [] + self._gatherGraphForHarfbuzz(tables, obj_list, done, objidx, virtual_edges) + # Gather all data in two passes: the absolute positions of all + # subtable are needed before the actual data can be assembled. + pos = 0 + for table in tables: + table.pos = pos + pos = pos + table.getDataLength() + + data = [] + for table in tables: + tableData = table.getDataForHarfbuzz() + data.append(tableData) + + return hb.serialize_with_tag(str(tableTag), data, obj_list) + + def getAllData(self, remove_duplicate=True): + """Assemble all data, including all subtables.""" + if remove_duplicate: + internedTables = {} + self._doneWriting(internedTables) + tables = [] + extTables = [] + done = {} + self._gatherTables(tables, extTables, done) + tables.reverse() + extTables.reverse() + # Gather all data in two passes: the absolute positions of all + # subtable are needed before the actual data can be assembled. + pos = 0 + for table in tables: + table.pos = pos + pos = pos + table.getDataLength() + + for table in extTables: + table.pos = pos + pos = pos + table.getDataLength() + + data = [] + for table in tables: + tableData = table.getData() + data.append(tableData) + + for table in extTables: + tableData = table.getData() + data.append(tableData) + + return bytesjoin(data) + + # interface for gathering data, as used by table.compile() + + def getSubWriter(self): + subwriter = self.__class__(self.localState, self.tableTag) + subwriter.parent = ( + self # because some subtables have idential values, we discard + ) + # the duplicates under the getAllData method. Hence some + # subtable writers can have more than one parent writer. + # But we just care about first one right now. + return subwriter + + def writeValue(self, typecode, value): + self.items.append(struct.pack(f">{typecode}", value)) + + def writeArray(self, typecode, values): + a = array.array(typecode, values) + if sys.byteorder != "big": + a.byteswap() + self.items.append(a.tobytes()) + + def writeInt8(self, value): + assert -128 <= value < 128, value + self.items.append(struct.pack(">b", value)) + + def writeInt8Array(self, values): + self.writeArray("b", values) + + def writeShort(self, value): + assert -32768 <= value < 32768, value + self.items.append(struct.pack(">h", value)) + + def writeShortArray(self, values): + self.writeArray("h", values) + + def writeLong(self, value): + self.items.append(struct.pack(">i", value)) + + def writeLongArray(self, values): + self.writeArray("i", values) + + def writeUInt8(self, value): + assert 0 <= value < 256, value + self.items.append(struct.pack(">B", value)) + + def writeUInt8Array(self, values): + self.writeArray("B", values) + + def writeUShort(self, value): + assert 0 <= value < 0x10000, value + self.items.append(struct.pack(">H", value)) + + def writeUShortArray(self, values): + self.writeArray("H", values) + + def writeULong(self, value): + self.items.append(struct.pack(">I", value)) + + def writeULongArray(self, values): + self.writeArray("I", values) + + def writeUInt24(self, value): + assert 0 <= value < 0x1000000, value + b = struct.pack(">L", value) + self.items.append(b[1:]) + + def writeUInt24Array(self, values): + for value in values: + self.writeUInt24(value) + + def writeTag(self, tag): + tag = Tag(tag).tobytes() + assert len(tag) == 4, tag + self.items.append(tag) + + def writeSubTable(self, subWriter, offsetSize): + self.items.append(OffsetToWriter(subWriter, offsetSize)) + + def writeCountReference(self, table, name, size=2, value=None): + ref = CountReference(table, name, size=size, value=value) + self.items.append(ref) + return ref + + def writeStruct(self, format, values): + data = struct.pack(*(format,) + values) + self.items.append(data) + + def writeData(self, data): + self.items.append(data) + + def getOverflowErrorRecord(self, item): + LookupListIndex = SubTableIndex = itemName = itemIndex = None + if self.name == "LookupList": + LookupListIndex = item.repeatIndex + elif self.name == "Lookup": + LookupListIndex = self.repeatIndex + SubTableIndex = item.repeatIndex + else: + itemName = getattr(item, "name", "<none>") + if hasattr(item, "repeatIndex"): + itemIndex = item.repeatIndex + if self.name == "SubTable": + LookupListIndex = self.parent.repeatIndex + SubTableIndex = self.repeatIndex + elif self.name == "ExtSubTable": + LookupListIndex = self.parent.parent.repeatIndex + SubTableIndex = self.parent.repeatIndex + else: # who knows how far below the SubTable level we are! Climb back up to the nearest subtable. + itemName = ".".join([self.name, itemName]) + p1 = self.parent + while p1 and p1.name not in ["ExtSubTable", "SubTable"]: + itemName = ".".join([p1.name, itemName]) + p1 = p1.parent + if p1: + if p1.name == "ExtSubTable": + LookupListIndex = p1.parent.parent.repeatIndex + SubTableIndex = p1.parent.repeatIndex + else: + LookupListIndex = p1.parent.repeatIndex + SubTableIndex = p1.repeatIndex + + return OverflowErrorRecord( + (self.tableTag, LookupListIndex, SubTableIndex, itemName, itemIndex) + ) + + +class CountReference(object): + """A reference to a Count value, not a count of references.""" + + def __init__(self, table, name, size=None, value=None): + self.table = table + self.name = name + self.size = size + if value is not None: + self.setValue(value) + + def setValue(self, value): + table = self.table + name = self.name + if table[name] is None: + table[name] = value + else: + assert table[name] == value, (name, table[name], value) + + def getValue(self): + return self.table[self.name] + + def getCountData(self): + v = self.table[self.name] + if v is None: + v = 0 + return {1: packUInt8, 2: packUShort, 4: packULong}[self.size](v) + + +def packUInt8(value): + return struct.pack(">B", value) + + +def packUShort(value): + return struct.pack(">H", value) + + +def packULong(value): + assert 0 <= value < 0x100000000, value + return struct.pack(">I", value) + + +def packUInt24(value): + assert 0 <= value < 0x1000000, value + return struct.pack(">I", value)[1:] + + +class BaseTable(object): + """Generic base class for all OpenType (sub)tables.""" + + def __getattr__(self, attr): + reader = self.__dict__.get("reader") + if reader: + del self.reader + font = self.font + del self.font + self.decompile(reader, font) + return getattr(self, attr) + + raise AttributeError(attr) + + def ensureDecompiled(self, recurse=False): + reader = self.__dict__.get("reader") + if reader: + del self.reader + font = self.font + del self.font + self.decompile(reader, font) + if recurse: + for subtable in self.iterSubTables(): + subtable.value.ensureDecompiled(recurse) + + def __getstate__(self): + # before copying/pickling 'lazy' objects, make a shallow copy of OTTableReader + # https://github.com/fonttools/fonttools/issues/2965 + if "reader" in self.__dict__: + state = self.__dict__.copy() + state["reader"] = self.__dict__["reader"].copy() + return state + return self.__dict__ + + @classmethod + def getRecordSize(cls, reader): + totalSize = 0 + for conv in cls.converters: + size = conv.getRecordSize(reader) + if size is NotImplemented: + return NotImplemented + countValue = 1 + if conv.repeat: + if conv.repeat in reader: + countValue = reader[conv.repeat] + conv.aux + else: + return NotImplemented + totalSize += size * countValue + return totalSize + + def getConverters(self): + return self.converters + + def getConverterByName(self, name): + return self.convertersByName[name] + + def populateDefaults(self, propagator=None): + for conv in self.getConverters(): + if conv.repeat: + if not hasattr(self, conv.name): + setattr(self, conv.name, []) + countValue = len(getattr(self, conv.name)) - conv.aux + try: + count_conv = self.getConverterByName(conv.repeat) + setattr(self, conv.repeat, countValue) + except KeyError: + # conv.repeat is a propagated count + if propagator and conv.repeat in propagator: + propagator[conv.repeat].setValue(countValue) + else: + if conv.aux and not eval(conv.aux, None, self.__dict__): + continue + if hasattr(self, conv.name): + continue # Warn if it should NOT be present?! + if hasattr(conv, "writeNullOffset"): + setattr(self, conv.name, None) # Warn? + # elif not conv.isCount: + # # Warn? + # pass + if hasattr(conv, "DEFAULT"): + # OptionalValue converters (e.g. VarIndex) + setattr(self, conv.name, conv.DEFAULT) + + def decompile(self, reader, font): + self.readFormat(reader) + table = {} + self.__rawTable = table # for debugging + for conv in self.getConverters(): + if conv.name == "SubTable": + conv = conv.getConverter(reader.tableTag, table["LookupType"]) + if conv.name == "ExtSubTable": + conv = conv.getConverter(reader.tableTag, table["ExtensionLookupType"]) + if conv.name == "FeatureParams": + conv = conv.getConverter(reader["FeatureTag"]) + if conv.name == "SubStruct": + conv = conv.getConverter(reader.tableTag, table["MorphType"]) + try: + if conv.repeat: + if isinstance(conv.repeat, int): + countValue = conv.repeat + elif conv.repeat in table: + countValue = table[conv.repeat] + else: + # conv.repeat is a propagated count + countValue = reader[conv.repeat] + countValue += conv.aux + table[conv.name] = conv.readArray(reader, font, table, countValue) + else: + if conv.aux and not eval(conv.aux, None, table): + continue + table[conv.name] = conv.read(reader, font, table) + if conv.isPropagated: + reader[conv.name] = table[conv.name] + except Exception as e: + name = conv.name + e.args = e.args + (name,) + raise + + if hasattr(self, "postRead"): + self.postRead(table, font) + else: + self.__dict__.update(table) + + del self.__rawTable # succeeded, get rid of debugging info + + def compile(self, writer, font): + self.ensureDecompiled() + # TODO Following hack to be removed by rewriting how FormatSwitching tables + # are handled. + # https://github.com/fonttools/fonttools/pull/2238#issuecomment-805192631 + if hasattr(self, "preWrite"): + deleteFormat = not hasattr(self, "Format") + table = self.preWrite(font) + deleteFormat = deleteFormat and hasattr(self, "Format") + else: + deleteFormat = False + table = self.__dict__.copy() + + # some count references may have been initialized in a custom preWrite; we set + # these in the writer's state beforehand (instead of sequentially) so they will + # be propagated to all nested subtables even if the count appears in the current + # table only *after* the offset to the subtable that it is counting. + for conv in self.getConverters(): + if conv.isCount and conv.isPropagated: + value = table.get(conv.name) + if isinstance(value, CountReference): + writer[conv.name] = value + + if hasattr(self, "sortCoverageLast"): + writer.sortCoverageLast = 1 + + if hasattr(self, "DontShare"): + writer.DontShare = True + + if hasattr(self.__class__, "LookupType"): + writer["LookupType"].setValue(self.__class__.LookupType) + + self.writeFormat(writer) + for conv in self.getConverters(): + value = table.get( + conv.name + ) # TODO Handle defaults instead of defaulting to None! + if conv.repeat: + if value is None: + value = [] + countValue = len(value) - conv.aux + if isinstance(conv.repeat, int): + assert len(value) == conv.repeat, "expected %d values, got %d" % ( + conv.repeat, + len(value), + ) + elif conv.repeat in table: + CountReference(table, conv.repeat, value=countValue) + else: + # conv.repeat is a propagated count + writer[conv.repeat].setValue(countValue) + try: + conv.writeArray(writer, font, table, value) + except Exception as e: + e.args = e.args + (conv.name + "[]",) + raise + elif conv.isCount: + # Special-case Count values. + # Assumption: a Count field will *always* precede + # the actual array(s). + # We need a default value, as it may be set later by a nested + # table. We will later store it here. + # We add a reference: by the time the data is assembled + # the Count value will be filled in. + # We ignore the current count value since it will be recomputed, + # unless it's a CountReference that was already initialized in a custom preWrite. + if isinstance(value, CountReference): + ref = value + ref.size = conv.staticSize + writer.writeData(ref) + table[conv.name] = ref.getValue() + else: + ref = writer.writeCountReference(table, conv.name, conv.staticSize) + table[conv.name] = None + if conv.isPropagated: + writer[conv.name] = ref + elif conv.isLookupType: + # We make sure that subtables have the same lookup type, + # and that the type is the same as the one set on the + # Lookup object, if any is set. + if conv.name not in table: + table[conv.name] = None + ref = writer.writeCountReference( + table, conv.name, conv.staticSize, table[conv.name] + ) + writer["LookupType"] = ref + else: + if conv.aux and not eval(conv.aux, None, table): + continue + try: + conv.write(writer, font, table, value) + except Exception as e: + name = value.__class__.__name__ if value is not None else conv.name + e.args = e.args + (name,) + raise + if conv.isPropagated: + writer[conv.name] = value + + if deleteFormat: + del self.Format + + def readFormat(self, reader): + pass + + def writeFormat(self, writer): + pass + + def toXML(self, xmlWriter, font, attrs=None, name=None): + tableName = name if name else self.__class__.__name__ + if attrs is None: + attrs = [] + if hasattr(self, "Format"): + attrs = attrs + [("Format", self.Format)] + xmlWriter.begintag(tableName, attrs) + xmlWriter.newline() + self.toXML2(xmlWriter, font) + xmlWriter.endtag(tableName) + xmlWriter.newline() + + def toXML2(self, xmlWriter, font): + # Simpler variant of toXML, *only* for the top level tables (like GPOS, GSUB). + # This is because in TTX our parent writes our main tag, and in otBase.py we + # do it ourselves. I think I'm getting schizophrenic... + for conv in self.getConverters(): + if conv.repeat: + value = getattr(self, conv.name, []) + for i, item in enumerate(value): + conv.xmlWrite(xmlWriter, font, item, conv.name, [("index", i)]) + else: + if conv.aux and not eval(conv.aux, None, vars(self)): + continue + value = getattr( + self, conv.name, None + ) # TODO Handle defaults instead of defaulting to None! + conv.xmlWrite(xmlWriter, font, value, conv.name, []) + + def fromXML(self, name, attrs, content, font): + try: + conv = self.getConverterByName(name) + except KeyError: + raise # XXX on KeyError, raise nice error + value = conv.xmlRead(attrs, content, font) + # Some manually-written tables have a conv.repeat of "" + # to represent lists. Hence comparing to None here to + # allow those lists to be read correctly from XML. + if conv.repeat is not None: + seq = getattr(self, conv.name, None) + if seq is None: + seq = [] + setattr(self, conv.name, seq) + seq.append(value) + else: + setattr(self, conv.name, value) + + def __ne__(self, other): + result = self.__eq__(other) + return result if result is NotImplemented else not result + + def __eq__(self, other): + if type(self) != type(other): + return NotImplemented + + self.ensureDecompiled() + other.ensureDecompiled() + + return self.__dict__ == other.__dict__ + + class SubTableEntry(NamedTuple): + """See BaseTable.iterSubTables()""" + + name: str + value: "BaseTable" + index: Optional[int] = None # index into given array, None for single values + + def iterSubTables(self) -> Iterator[SubTableEntry]: + """Yield (name, value, index) namedtuples for all subtables of current table. + + A sub-table is an instance of BaseTable (or subclass thereof) that is a child + of self, the current parent table. + The tuples also contain the attribute name (str) of the of parent table to get + a subtable, and optionally, for lists of subtables (i.e. attributes associated + with a converter that has a 'repeat'), an index into the list containing the + given subtable value. + This method can be useful to traverse trees of otTables. + """ + for conv in self.getConverters(): + name = conv.name + value = getattr(self, name, None) + if value is None: + continue + if isinstance(value, BaseTable): + yield self.SubTableEntry(name, value) + elif isinstance(value, list): + yield from ( + self.SubTableEntry(name, v, index=i) + for i, v in enumerate(value) + if isinstance(v, BaseTable) + ) + + # instance (not @class)method for consistency with FormatSwitchingBaseTable + def getVariableAttrs(self): + return getVariableAttrs(self.__class__) + + +class FormatSwitchingBaseTable(BaseTable): + """Minor specialization of BaseTable, for tables that have multiple + formats, eg. CoverageFormat1 vs. CoverageFormat2.""" + + @classmethod + def getRecordSize(cls, reader): + return NotImplemented + + def getConverters(self): + try: + fmt = self.Format + except AttributeError: + # some FormatSwitchingBaseTables (e.g. Coverage) no longer have 'Format' + # attribute after fully decompiled, only gain one in preWrite before being + # recompiled. In the decompiled state, these hand-coded classes defined in + # otTables.py lose their format-specific nature and gain more high-level + # attributes that are not tied to converters. + return [] + return self.converters.get(self.Format, []) + + def getConverterByName(self, name): + return self.convertersByName[self.Format][name] + + def readFormat(self, reader): + self.Format = reader.readUShort() + + def writeFormat(self, writer): + writer.writeUShort(self.Format) + + def toXML(self, xmlWriter, font, attrs=None, name=None): + BaseTable.toXML(self, xmlWriter, font, attrs, name) + + def getVariableAttrs(self): + return getVariableAttrs(self.__class__, self.Format) + + +class UInt8FormatSwitchingBaseTable(FormatSwitchingBaseTable): + def readFormat(self, reader): + self.Format = reader.readUInt8() + + def writeFormat(self, writer): + writer.writeUInt8(self.Format) + + +formatSwitchingBaseTables = { + "uint16": FormatSwitchingBaseTable, + "uint8": UInt8FormatSwitchingBaseTable, +} + + +def getFormatSwitchingBaseTableClass(formatType): + try: + return formatSwitchingBaseTables[formatType] + except KeyError: + raise TypeError(f"Unsupported format type: {formatType!r}") + + +# memoize since these are parsed from otData.py, thus stay constant +@lru_cache() +def getVariableAttrs(cls: BaseTable, fmt: Optional[int] = None) -> Tuple[str]: + """Return sequence of variable table field names (can be empty). + + Attributes are deemed "variable" when their otData.py's description contain + 'VarIndexBase + {offset}', e.g. COLRv1 PaintVar* tables. + """ + if not issubclass(cls, BaseTable): + raise TypeError(cls) + if issubclass(cls, FormatSwitchingBaseTable): + if fmt is None: + raise TypeError(f"'fmt' is required for format-switching {cls.__name__}") + converters = cls.convertersByName[fmt] + else: + converters = cls.convertersByName + # assume if no 'VarIndexBase' field is present, table has no variable fields + if "VarIndexBase" not in converters: + return () + varAttrs = {} + for name, conv in converters.items(): + offset = conv.getVarIndexOffset() + if offset is not None: + varAttrs[name] = offset + return tuple(sorted(varAttrs, key=varAttrs.__getitem__)) + + +# +# Support for ValueRecords +# +# This data type is so different from all other OpenType data types that +# it requires quite a bit of code for itself. It even has special support +# in OTTableReader and OTTableWriter... +# + +valueRecordFormat = [ + # Mask Name isDevice signed + (0x0001, "XPlacement", 0, 1), + (0x0002, "YPlacement", 0, 1), + (0x0004, "XAdvance", 0, 1), + (0x0008, "YAdvance", 0, 1), + (0x0010, "XPlaDevice", 1, 0), + (0x0020, "YPlaDevice", 1, 0), + (0x0040, "XAdvDevice", 1, 0), + (0x0080, "YAdvDevice", 1, 0), + # reserved: + (0x0100, "Reserved1", 0, 0), + (0x0200, "Reserved2", 0, 0), + (0x0400, "Reserved3", 0, 0), + (0x0800, "Reserved4", 0, 0), + (0x1000, "Reserved5", 0, 0), + (0x2000, "Reserved6", 0, 0), + (0x4000, "Reserved7", 0, 0), + (0x8000, "Reserved8", 0, 0), +] + + +def _buildDict(): + d = {} + for mask, name, isDevice, signed in valueRecordFormat: + d[name] = mask, isDevice, signed + return d + + +valueRecordFormatDict = _buildDict() + + +class ValueRecordFactory(object): + """Given a format code, this object convert ValueRecords.""" + + def __init__(self, valueFormat): + format = [] + for mask, name, isDevice, signed in valueRecordFormat: + if valueFormat & mask: + format.append((name, isDevice, signed)) + self.format = format + + def __len__(self): + return len(self.format) + + def readValueRecord(self, reader, font): + format = self.format + if not format: + return None + valueRecord = ValueRecord() + for name, isDevice, signed in format: + if signed: + value = reader.readShort() + else: + value = reader.readUShort() + if isDevice: + if value: + from . import otTables + + subReader = reader.getSubReader(value) + value = getattr(otTables, name)() + value.decompile(subReader, font) + else: + value = None + setattr(valueRecord, name, value) + return valueRecord + + def writeValueRecord(self, writer, font, valueRecord): + for name, isDevice, signed in self.format: + value = getattr(valueRecord, name, 0) + if isDevice: + if value: + subWriter = writer.getSubWriter() + writer.writeSubTable(subWriter, offsetSize=2) + value.compile(subWriter, font) + else: + writer.writeUShort(0) + elif signed: + writer.writeShort(value) + else: + writer.writeUShort(value) + + +class ValueRecord(object): + # see ValueRecordFactory + + def __init__(self, valueFormat=None, src=None): + if valueFormat is not None: + for mask, name, isDevice, signed in valueRecordFormat: + if valueFormat & mask: + setattr(self, name, None if isDevice else 0) + if src is not None: + for key, val in src.__dict__.items(): + if not hasattr(self, key): + continue + setattr(self, key, val) + elif src is not None: + self.__dict__ = src.__dict__.copy() + + def getFormat(self): + format = 0 + for name in self.__dict__.keys(): + format = format | valueRecordFormatDict[name][0] + return format + + def getEffectiveFormat(self): + format = 0 + for name, value in self.__dict__.items(): + if value: + format = format | valueRecordFormatDict[name][0] + return format + + def toXML(self, xmlWriter, font, valueName, attrs=None): + if attrs is None: + simpleItems = [] + else: + simpleItems = list(attrs) + for mask, name, isDevice, format in valueRecordFormat[:4]: # "simple" values + if hasattr(self, name): + simpleItems.append((name, getattr(self, name))) + deviceItems = [] + for mask, name, isDevice, format in valueRecordFormat[4:8]: # device records + if hasattr(self, name): + device = getattr(self, name) + if device is not None: + deviceItems.append((name, device)) + if deviceItems: + xmlWriter.begintag(valueName, simpleItems) + xmlWriter.newline() + for name, deviceRecord in deviceItems: + if deviceRecord is not None: + deviceRecord.toXML(xmlWriter, font, name=name) + xmlWriter.endtag(valueName) + xmlWriter.newline() + else: + xmlWriter.simpletag(valueName, simpleItems) + xmlWriter.newline() + + def fromXML(self, name, attrs, content, font): + from . import otTables + + for k, v in attrs.items(): + setattr(self, k, int(v)) + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + value = getattr(otTables, name)() + for elem2 in content: + if not isinstance(elem2, tuple): + continue + name2, attrs2, content2 = elem2 + value.fromXML(name2, attrs2, content2, font) + setattr(self, name, value) + + def __ne__(self, other): + result = self.__eq__(other) + return result if result is NotImplemented else not result + + def __eq__(self, other): + if type(self) != type(other): + return NotImplemented + return self.__dict__ == other.__dict__ diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/otConverters.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/otConverters.py new file mode 100644 index 0000000000000000000000000000000000000000..75bfd7f6ca525b9167c1701f8e194aab29b2de8a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/otConverters.py @@ -0,0 +1,2068 @@ +from fontTools.misc.fixedTools import ( + fixedToFloat as fi2fl, + floatToFixed as fl2fi, + floatToFixedToStr as fl2str, + strToFixedToFloat as str2fl, + ensureVersionIsLong as fi2ve, + versionToFixed as ve2fi, +) +from fontTools.ttLib.tables.TupleVariation import TupleVariation +from fontTools.misc.roundTools import nearestMultipleShortestRepr, otRound +from fontTools.misc.textTools import bytesjoin, tobytes, tostr, pad, safeEval +from fontTools.misc.lazyTools import LazyList +from fontTools.ttLib import OPTIMIZE_FONT_SPEED, getSearchRange +from .otBase import ( + CountReference, + FormatSwitchingBaseTable, + OTTableReader, + OTTableWriter, + ValueRecordFactory, +) +from .otTables import ( + lookupTypes, + VarCompositeGlyph, + AATStateTable, + AATState, + AATAction, + ContextualMorphAction, + LigatureMorphAction, + InsertionMorphAction, + MorxSubtable, + ExtendMode as _ExtendMode, + CompositeMode as _CompositeMode, + NO_VARIATION_INDEX, +) +from itertools import zip_longest, accumulate +from functools import partial +from types import SimpleNamespace +import re +import struct +from typing import Optional +import logging + + +log = logging.getLogger(__name__) +istuple = lambda t: isinstance(t, tuple) + + +def buildConverters(tableSpec, tableNamespace): + """Given a table spec from otData.py, build a converter object for each + field of the table. This is called for each table in otData.py, and + the results are assigned to the corresponding class in otTables.py.""" + converters = [] + convertersByName = {} + for tp, name, repeat, aux, descr in tableSpec: + tableName = name + if name.startswith("ValueFormat"): + assert tp == "uint16" + converterClass = ValueFormat + elif name.endswith("Count") or name in ("StructLength", "MorphType"): + converterClass = { + "uint8": ComputedUInt8, + "uint16": ComputedUShort, + "uint32": ComputedULong, + }[tp] + elif name == "SubTable": + converterClass = SubTable + elif name == "ExtSubTable": + converterClass = ExtSubTable + elif name == "SubStruct": + converterClass = SubStruct + elif name == "FeatureParams": + converterClass = FeatureParams + elif name in ("CIDGlyphMapping", "GlyphCIDMapping"): + converterClass = StructWithLength + else: + if not tp in converterMapping and "(" not in tp: + tableName = tp + converterClass = Struct + else: + converterClass = eval(tp, tableNamespace, converterMapping) + + conv = converterClass(name, repeat, aux, description=descr) + + if conv.tableClass: + # A "template" such as OffsetTo(AType) knows the table class already + tableClass = conv.tableClass + elif tp in ("MortChain", "MortSubtable", "MorxChain"): + tableClass = tableNamespace.get(tp) + else: + tableClass = tableNamespace.get(tableName) + + if not conv.tableClass: + conv.tableClass = tableClass + + if name in ["SubTable", "ExtSubTable", "SubStruct"]: + conv.lookupTypes = tableNamespace["lookupTypes"] + # also create reverse mapping + for t in conv.lookupTypes.values(): + for cls in t.values(): + convertersByName[cls.__name__] = Table(name, repeat, aux, cls) + if name == "FeatureParams": + conv.featureParamTypes = tableNamespace["featureParamTypes"] + conv.defaultFeatureParams = tableNamespace["FeatureParams"] + for cls in conv.featureParamTypes.values(): + convertersByName[cls.__name__] = Table(name, repeat, aux, cls) + converters.append(conv) + assert name not in convertersByName, name + convertersByName[name] = conv + return converters, convertersByName + + +class BaseConverter(object): + """Base class for converter objects. Apart from the constructor, this + is an abstract class.""" + + def __init__(self, name, repeat, aux, tableClass=None, *, description=""): + self.name = name + self.repeat = repeat + self.aux = aux + if self.aux and not self.repeat: + self.aux = compile(self.aux, "<string>", "eval") + self.tableClass = tableClass + self.isCount = name.endswith("Count") or name in [ + "DesignAxisRecordSize", + "ValueRecordSize", + ] + self.isLookupType = name.endswith("LookupType") or name == "MorphType" + self.isPropagated = name in [ + "ClassCount", + "Class2Count", + "FeatureTag", + "SettingsCount", + "VarRegionCount", + "MappingCount", + "RegionAxisCount", + "DesignAxisCount", + "DesignAxisRecordSize", + "AxisValueCount", + "ValueRecordSize", + "AxisCount", + "BaseGlyphRecordCount", + "LayerRecordCount", + "AxisIndicesList", + ] + self.description = description + + def readArray(self, reader, font, tableDict, count): + """Read an array of values from the reader.""" + lazy = font.lazy and count > 8 + if lazy: + recordSize = self.getRecordSize(reader) + if recordSize is NotImplemented: + lazy = False + if not lazy: + l = [] + for i in range(count): + l.append(self.read(reader, font, tableDict)) + return l + else: + + def get_read_item(): + reader_copy = reader.copy() + pos = reader.pos + + def read_item(i): + reader_copy.seek(pos + i * recordSize) + return self.read(reader_copy, font, {}) + + return read_item + + read_item = get_read_item() + l = LazyList(read_item for i in range(count)) + reader.advance(count * recordSize) + + return l + + def getRecordSize(self, reader): + if hasattr(self, "staticSize"): + return self.staticSize + return NotImplemented + + def read(self, reader, font, tableDict): + """Read a value from the reader.""" + raise NotImplementedError(self) + + def writeArray(self, writer, font, tableDict, values): + try: + for i, value in enumerate(values): + self.write(writer, font, tableDict, value, i) + except Exception as e: + e.args = e.args + (i,) + raise + + def write(self, writer, font, tableDict, value, repeatIndex=None): + """Write a value to the writer.""" + raise NotImplementedError(self) + + def xmlRead(self, attrs, content, font): + """Read a value from XML.""" + raise NotImplementedError(self) + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + """Write a value to XML.""" + raise NotImplementedError(self) + + varIndexBasePlusOffsetRE = re.compile(r"VarIndexBase\s*\+\s*(\d+)") + + def getVarIndexOffset(self) -> Optional[int]: + """If description has `VarIndexBase + {offset}`, return the offset else None.""" + m = self.varIndexBasePlusOffsetRE.search(self.description) + if not m: + return None + return int(m.group(1)) + + +class SimpleValue(BaseConverter): + @staticmethod + def toString(value): + return value + + @staticmethod + def fromString(value): + return value + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + xmlWriter.simpletag(name, attrs + [("value", self.toString(value))]) + xmlWriter.newline() + + def xmlRead(self, attrs, content, font): + return self.fromString(attrs["value"]) + + +class OptionalValue(SimpleValue): + DEFAULT = None + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + if value != self.DEFAULT: + attrs.append(("value", self.toString(value))) + xmlWriter.simpletag(name, attrs) + xmlWriter.newline() + + def xmlRead(self, attrs, content, font): + if "value" in attrs: + return self.fromString(attrs["value"]) + return self.DEFAULT + + +class IntValue(SimpleValue): + @staticmethod + def fromString(value): + return int(value, 0) + + +class Long(IntValue): + staticSize = 4 + + def read(self, reader, font, tableDict): + return reader.readLong() + + def readArray(self, reader, font, tableDict, count): + return reader.readLongArray(count) + + def write(self, writer, font, tableDict, value, repeatIndex=None): + writer.writeLong(value) + + def writeArray(self, writer, font, tableDict, values): + writer.writeLongArray(values) + + +class ULong(IntValue): + staticSize = 4 + + def read(self, reader, font, tableDict): + return reader.readULong() + + def readArray(self, reader, font, tableDict, count): + return reader.readULongArray(count) + + def write(self, writer, font, tableDict, value, repeatIndex=None): + writer.writeULong(value) + + def writeArray(self, writer, font, tableDict, values): + writer.writeULongArray(values) + + +class Flags32(ULong): + @staticmethod + def toString(value): + return "0x%08X" % value + + +class VarIndex(OptionalValue, ULong): + DEFAULT = NO_VARIATION_INDEX + + +class Short(IntValue): + staticSize = 2 + + def read(self, reader, font, tableDict): + return reader.readShort() + + def readArray(self, reader, font, tableDict, count): + return reader.readShortArray(count) + + def write(self, writer, font, tableDict, value, repeatIndex=None): + writer.writeShort(value) + + def writeArray(self, writer, font, tableDict, values): + writer.writeShortArray(values) + + +class UShort(IntValue): + staticSize = 2 + + def read(self, reader, font, tableDict): + return reader.readUShort() + + def readArray(self, reader, font, tableDict, count): + return reader.readUShortArray(count) + + def write(self, writer, font, tableDict, value, repeatIndex=None): + writer.writeUShort(value) + + def writeArray(self, writer, font, tableDict, values): + writer.writeUShortArray(values) + + +class Int8(IntValue): + staticSize = 1 + + def read(self, reader, font, tableDict): + return reader.readInt8() + + def readArray(self, reader, font, tableDict, count): + return reader.readInt8Array(count) + + def write(self, writer, font, tableDict, value, repeatIndex=None): + writer.writeInt8(value) + + def writeArray(self, writer, font, tableDict, values): + writer.writeInt8Array(values) + + +class UInt8(IntValue): + staticSize = 1 + + def read(self, reader, font, tableDict): + return reader.readUInt8() + + def readArray(self, reader, font, tableDict, count): + return reader.readUInt8Array(count) + + def write(self, writer, font, tableDict, value, repeatIndex=None): + writer.writeUInt8(value) + + def writeArray(self, writer, font, tableDict, values): + writer.writeUInt8Array(values) + + +class UInt24(IntValue): + staticSize = 3 + + def read(self, reader, font, tableDict): + return reader.readUInt24() + + def write(self, writer, font, tableDict, value, repeatIndex=None): + writer.writeUInt24(value) + + +class ComputedInt(IntValue): + def xmlWrite(self, xmlWriter, font, value, name, attrs): + if value is not None: + xmlWriter.comment("%s=%s" % (name, value)) + xmlWriter.newline() + + +class ComputedUInt8(ComputedInt, UInt8): + pass + + +class ComputedUShort(ComputedInt, UShort): + pass + + +class ComputedULong(ComputedInt, ULong): + pass + + +class Tag(SimpleValue): + staticSize = 4 + + def read(self, reader, font, tableDict): + return reader.readTag() + + def write(self, writer, font, tableDict, value, repeatIndex=None): + writer.writeTag(value) + + +class GlyphID(SimpleValue): + staticSize = 2 + typecode = "H" + + def readArray(self, reader, font, tableDict, count): + return font.getGlyphNameMany( + reader.readArray(self.typecode, self.staticSize, count) + ) + + def read(self, reader, font, tableDict): + return font.getGlyphName(reader.readValue(self.typecode, self.staticSize)) + + def writeArray(self, writer, font, tableDict, values): + writer.writeArray(self.typecode, font.getGlyphIDMany(values)) + + def write(self, writer, font, tableDict, value, repeatIndex=None): + writer.writeValue(self.typecode, font.getGlyphID(value)) + + +class GlyphID32(GlyphID): + staticSize = 4 + typecode = "L" + + +class NameID(UShort): + def xmlWrite(self, xmlWriter, font, value, name, attrs): + xmlWriter.simpletag(name, attrs + [("value", value)]) + if font and value: + nameTable = font.get("name") + if nameTable: + name = nameTable.getDebugName(value) + xmlWriter.write(" ") + if name: + xmlWriter.comment(name) + else: + xmlWriter.comment("missing from name table") + log.warning("name id %d missing from name table" % value) + xmlWriter.newline() + + +class STATFlags(UShort): + def xmlWrite(self, xmlWriter, font, value, name, attrs): + xmlWriter.simpletag(name, attrs + [("value", value)]) + flags = [] + if value & 0x01: + flags.append("OlderSiblingFontAttribute") + if value & 0x02: + flags.append("ElidableAxisValueName") + if flags: + xmlWriter.write(" ") + xmlWriter.comment(" ".join(flags)) + xmlWriter.newline() + + +class FloatValue(SimpleValue): + @staticmethod + def fromString(value): + return float(value) + + +class DeciPoints(FloatValue): + staticSize = 2 + + def read(self, reader, font, tableDict): + return reader.readUShort() / 10 + + def write(self, writer, font, tableDict, value, repeatIndex=None): + writer.writeUShort(round(value * 10)) + + +class BaseFixedValue(FloatValue): + staticSize = NotImplemented + precisionBits = NotImplemented + readerMethod = NotImplemented + writerMethod = NotImplemented + + def read(self, reader, font, tableDict): + return self.fromInt(getattr(reader, self.readerMethod)()) + + def write(self, writer, font, tableDict, value, repeatIndex=None): + getattr(writer, self.writerMethod)(self.toInt(value)) + + @classmethod + def fromInt(cls, value): + return fi2fl(value, cls.precisionBits) + + @classmethod + def toInt(cls, value): + return fl2fi(value, cls.precisionBits) + + @classmethod + def fromString(cls, value): + return str2fl(value, cls.precisionBits) + + @classmethod + def toString(cls, value): + return fl2str(value, cls.precisionBits) + + +class Fixed(BaseFixedValue): + staticSize = 4 + precisionBits = 16 + readerMethod = "readLong" + writerMethod = "writeLong" + + +class F2Dot14(BaseFixedValue): + staticSize = 2 + precisionBits = 14 + readerMethod = "readShort" + writerMethod = "writeShort" + + +class Angle(F2Dot14): + # angles are specified in degrees, and encoded as F2Dot14 fractions of half + # circle: e.g. 1.0 => 180, -0.5 => -90, -2.0 => -360, etc. + bias = 0.0 + factor = 1.0 / (1 << 14) * 180 # 0.010986328125 + + @classmethod + def fromInt(cls, value): + return (super().fromInt(value) + cls.bias) * 180 + + @classmethod + def toInt(cls, value): + return super().toInt((value / 180) - cls.bias) + + @classmethod + def fromString(cls, value): + # quantize to nearest multiples of minimum fixed-precision angle + return otRound(float(value) / cls.factor) * cls.factor + + @classmethod + def toString(cls, value): + return nearestMultipleShortestRepr(value, cls.factor) + + +class BiasedAngle(Angle): + # A bias of 1.0 is used in the representation of start and end angles + # of COLRv1 PaintSweepGradients to allow for encoding +360deg + bias = 1.0 + + +class Version(SimpleValue): + staticSize = 4 + + def read(self, reader, font, tableDict): + value = reader.readLong() + return value + + def write(self, writer, font, tableDict, value, repeatIndex=None): + value = fi2ve(value) + writer.writeLong(value) + + @staticmethod + def fromString(value): + return ve2fi(value) + + @staticmethod + def toString(value): + return "0x%08x" % value + + @staticmethod + def fromFloat(v): + return fl2fi(v, 16) + + +class Char64(SimpleValue): + """An ASCII string with up to 64 characters. + + Unused character positions are filled with 0x00 bytes. + Used in Apple AAT fonts in the `gcid` table. + """ + + staticSize = 64 + + def read(self, reader, font, tableDict): + data = reader.readData(self.staticSize) + zeroPos = data.find(b"\0") + if zeroPos >= 0: + data = data[:zeroPos] + s = tostr(data, encoding="ascii", errors="replace") + if s != tostr(data, encoding="ascii", errors="ignore"): + log.warning('replaced non-ASCII characters in "%s"' % s) + return s + + def write(self, writer, font, tableDict, value, repeatIndex=None): + data = tobytes(value, encoding="ascii", errors="replace") + if data != tobytes(value, encoding="ascii", errors="ignore"): + log.warning('replacing non-ASCII characters in "%s"' % value) + if len(data) > self.staticSize: + log.warning( + 'truncating overlong "%s" to %d bytes' % (value, self.staticSize) + ) + data = (data + b"\0" * self.staticSize)[: self.staticSize] + writer.writeData(data) + + +class Struct(BaseConverter): + def getRecordSize(self, reader): + return self.tableClass and self.tableClass.getRecordSize(reader) + + def read(self, reader, font, tableDict): + table = self.tableClass() + table.decompile(reader, font) + return table + + def write(self, writer, font, tableDict, value, repeatIndex=None): + value.compile(writer, font) + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + if value is None: + if attrs: + # If there are attributes (probably index), then + # don't drop this even if it's NULL. It will mess + # up the array indices of the containing element. + xmlWriter.simpletag(name, attrs + [("empty", 1)]) + xmlWriter.newline() + else: + pass # NULL table, ignore + else: + value.toXML(xmlWriter, font, attrs, name=name) + + def xmlRead(self, attrs, content, font): + if "empty" in attrs and safeEval(attrs["empty"]): + return None + table = self.tableClass() + Format = attrs.get("Format") + if Format is not None: + table.Format = int(Format) + + noPostRead = not hasattr(table, "postRead") + if noPostRead: + # TODO Cache table.hasPropagated. + cleanPropagation = False + for conv in table.getConverters(): + if conv.isPropagated: + cleanPropagation = True + if not hasattr(font, "_propagator"): + font._propagator = {} + propagator = font._propagator + assert conv.name not in propagator, (conv.name, propagator) + setattr(table, conv.name, None) + propagator[conv.name] = CountReference(table.__dict__, conv.name) + + for element in content: + if isinstance(element, tuple): + name, attrs, content = element + table.fromXML(name, attrs, content, font) + else: + pass + + table.populateDefaults(propagator=getattr(font, "_propagator", None)) + + if noPostRead: + if cleanPropagation: + for conv in table.getConverters(): + if conv.isPropagated: + propagator = font._propagator + del propagator[conv.name] + if not propagator: + del font._propagator + + return table + + def __repr__(self): + return "Struct of " + repr(self.tableClass) + + +class StructWithLength(Struct): + def read(self, reader, font, tableDict): + pos = reader.pos + table = self.tableClass() + table.decompile(reader, font) + reader.seek(pos + table.StructLength) + return table + + def write(self, writer, font, tableDict, value, repeatIndex=None): + for convIndex, conv in enumerate(value.getConverters()): + if conv.name == "StructLength": + break + lengthIndex = len(writer.items) + convIndex + if isinstance(value, FormatSwitchingBaseTable): + lengthIndex += 1 # implicit Format field + deadbeef = {1: 0xDE, 2: 0xDEAD, 4: 0xDEADBEEF}[conv.staticSize] + + before = writer.getDataLength() + value.StructLength = deadbeef + value.compile(writer, font) + length = writer.getDataLength() - before + lengthWriter = writer.getSubWriter() + conv.write(lengthWriter, font, tableDict, length) + assert writer.items[lengthIndex] == b"\xde\xad\xbe\xef"[: conv.staticSize] + writer.items[lengthIndex] = lengthWriter.getAllData() + + +class Table(Struct): + staticSize = 2 + + def readOffset(self, reader): + return reader.readUShort() + + def writeNullOffset(self, writer): + writer.writeUShort(0) + + def read(self, reader, font, tableDict): + offset = self.readOffset(reader) + if offset == 0: + return None + table = self.tableClass() + reader = reader.getSubReader(offset) + if font.lazy: + table.reader = reader + table.font = font + else: + table.decompile(reader, font) + return table + + def write(self, writer, font, tableDict, value, repeatIndex=None): + if value is None: + self.writeNullOffset(writer) + else: + subWriter = writer.getSubWriter() + subWriter.name = self.name + if repeatIndex is not None: + subWriter.repeatIndex = repeatIndex + writer.writeSubTable(subWriter, offsetSize=self.staticSize) + value.compile(subWriter, font) + + +class LTable(Table): + staticSize = 4 + + def readOffset(self, reader): + return reader.readULong() + + def writeNullOffset(self, writer): + writer.writeULong(0) + + +# Table pointed to by a 24-bit, 3-byte long offset +class Table24(Table): + staticSize = 3 + + def readOffset(self, reader): + return reader.readUInt24() + + def writeNullOffset(self, writer): + writer.writeUInt24(0) + + +# TODO Clean / merge the SubTable and SubStruct + + +class SubStruct(Struct): + def getConverter(self, tableType, lookupType): + tableClass = self.lookupTypes[tableType][lookupType] + return self.__class__(self.name, self.repeat, self.aux, tableClass) + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + super(SubStruct, self).xmlWrite(xmlWriter, font, value, None, attrs) + + +class SubTable(Table): + def getConverter(self, tableType, lookupType): + tableClass = self.lookupTypes[tableType][lookupType] + return self.__class__(self.name, self.repeat, self.aux, tableClass) + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + super(SubTable, self).xmlWrite(xmlWriter, font, value, None, attrs) + + +class ExtSubTable(LTable, SubTable): + def write(self, writer, font, tableDict, value, repeatIndex=None): + writer.Extension = True # actually, mere presence of the field flags it as an Ext Subtable writer. + Table.write(self, writer, font, tableDict, value, repeatIndex) + + +class FeatureParams(Table): + def getConverter(self, featureTag): + tableClass = self.featureParamTypes.get(featureTag, self.defaultFeatureParams) + return self.__class__(self.name, self.repeat, self.aux, tableClass) + + +class ValueFormat(IntValue): + staticSize = 2 + + def __init__(self, name, repeat, aux, tableClass=None, *, description=""): + BaseConverter.__init__( + self, name, repeat, aux, tableClass, description=description + ) + self.which = "ValueFormat" + ("2" if name[-1] == "2" else "1") + + def read(self, reader, font, tableDict): + format = reader.readUShort() + reader[self.which] = ValueRecordFactory(format) + return format + + def write(self, writer, font, tableDict, format, repeatIndex=None): + writer.writeUShort(format) + writer[self.which] = ValueRecordFactory(format) + + +class ValueRecord(ValueFormat): + def getRecordSize(self, reader): + return 2 * len(reader[self.which]) + + def read(self, reader, font, tableDict): + return reader[self.which].readValueRecord(reader, font) + + def write(self, writer, font, tableDict, value, repeatIndex=None): + writer[self.which].writeValueRecord(writer, font, value) + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + if value is None: + pass # NULL table, ignore + else: + value.toXML(xmlWriter, font, self.name, attrs) + + def xmlRead(self, attrs, content, font): + from .otBase import ValueRecord + + value = ValueRecord() + value.fromXML(None, attrs, content, font) + return value + + +class AATLookup(BaseConverter): + BIN_SEARCH_HEADER_SIZE = 10 + + def __init__(self, name, repeat, aux, tableClass, *, description=""): + BaseConverter.__init__( + self, name, repeat, aux, tableClass, description=description + ) + if issubclass(self.tableClass, SimpleValue): + self.converter = self.tableClass(name="Value", repeat=None, aux=None) + else: + self.converter = Table( + name="Value", repeat=None, aux=None, tableClass=self.tableClass + ) + + def read(self, reader, font, tableDict): + format = reader.readUShort() + if format == 0: + return self.readFormat0(reader, font) + elif format == 2: + return self.readFormat2(reader, font) + elif format == 4: + return self.readFormat4(reader, font) + elif format == 6: + return self.readFormat6(reader, font) + elif format == 8: + return self.readFormat8(reader, font) + else: + assert False, "unsupported lookup format: %d" % format + + def write(self, writer, font, tableDict, value, repeatIndex=None): + values = list( + sorted([(font.getGlyphID(glyph), val) for glyph, val in value.items()]) + ) + # TODO: Also implement format 4. + formats = list( + sorted( + filter( + None, + [ + self.buildFormat0(writer, font, values), + self.buildFormat2(writer, font, values), + self.buildFormat6(writer, font, values), + self.buildFormat8(writer, font, values), + ], + ) + ) + ) + # We use the format ID as secondary sort key to make the output + # deterministic when multiple formats have same encoded size. + dataSize, lookupFormat, writeMethod = formats[0] + pos = writer.getDataLength() + writeMethod() + actualSize = writer.getDataLength() - pos + assert ( + actualSize == dataSize + ), "AATLookup format %d claimed to write %d bytes, but wrote %d" % ( + lookupFormat, + dataSize, + actualSize, + ) + + @staticmethod + def writeBinSearchHeader(writer, numUnits, unitSize): + writer.writeUShort(unitSize) + writer.writeUShort(numUnits) + searchRange, entrySelector, rangeShift = getSearchRange( + n=numUnits, itemSize=unitSize + ) + writer.writeUShort(searchRange) + writer.writeUShort(entrySelector) + writer.writeUShort(rangeShift) + + def buildFormat0(self, writer, font, values): + numGlyphs = len(font.getGlyphOrder()) + if len(values) != numGlyphs: + return None + valueSize = self.converter.staticSize + return ( + 2 + numGlyphs * valueSize, + 0, + lambda: self.writeFormat0(writer, font, values), + ) + + def writeFormat0(self, writer, font, values): + writer.writeUShort(0) + for glyphID_, value in values: + self.converter.write( + writer, font, tableDict=None, value=value, repeatIndex=None + ) + + def buildFormat2(self, writer, font, values): + segStart, segValue = values[0] + segEnd = segStart + segments = [] + for glyphID, curValue in values[1:]: + if glyphID != segEnd + 1 or curValue != segValue: + segments.append((segStart, segEnd, segValue)) + segStart = segEnd = glyphID + segValue = curValue + else: + segEnd = glyphID + segments.append((segStart, segEnd, segValue)) + valueSize = self.converter.staticSize + numUnits, unitSize = len(segments) + 1, valueSize + 4 + return ( + 2 + self.BIN_SEARCH_HEADER_SIZE + numUnits * unitSize, + 2, + lambda: self.writeFormat2(writer, font, segments), + ) + + def writeFormat2(self, writer, font, segments): + writer.writeUShort(2) + valueSize = self.converter.staticSize + numUnits, unitSize = len(segments), valueSize + 4 + self.writeBinSearchHeader(writer, numUnits, unitSize) + for firstGlyph, lastGlyph, value in segments: + writer.writeUShort(lastGlyph) + writer.writeUShort(firstGlyph) + self.converter.write( + writer, font, tableDict=None, value=value, repeatIndex=None + ) + writer.writeUShort(0xFFFF) + writer.writeUShort(0xFFFF) + writer.writeData(b"\x00" * valueSize) + + def buildFormat6(self, writer, font, values): + valueSize = self.converter.staticSize + numUnits, unitSize = len(values), valueSize + 2 + return ( + 2 + self.BIN_SEARCH_HEADER_SIZE + (numUnits + 1) * unitSize, + 6, + lambda: self.writeFormat6(writer, font, values), + ) + + def writeFormat6(self, writer, font, values): + writer.writeUShort(6) + valueSize = self.converter.staticSize + numUnits, unitSize = len(values), valueSize + 2 + self.writeBinSearchHeader(writer, numUnits, unitSize) + for glyphID, value in values: + writer.writeUShort(glyphID) + self.converter.write( + writer, font, tableDict=None, value=value, repeatIndex=None + ) + writer.writeUShort(0xFFFF) + writer.writeData(b"\x00" * valueSize) + + def buildFormat8(self, writer, font, values): + minGlyphID, maxGlyphID = values[0][0], values[-1][0] + if len(values) != maxGlyphID - minGlyphID + 1: + return None + valueSize = self.converter.staticSize + return ( + 6 + len(values) * valueSize, + 8, + lambda: self.writeFormat8(writer, font, values), + ) + + def writeFormat8(self, writer, font, values): + firstGlyphID = values[0][0] + writer.writeUShort(8) + writer.writeUShort(firstGlyphID) + writer.writeUShort(len(values)) + for _, value in values: + self.converter.write( + writer, font, tableDict=None, value=value, repeatIndex=None + ) + + def readFormat0(self, reader, font): + numGlyphs = len(font.getGlyphOrder()) + data = self.converter.readArray(reader, font, tableDict=None, count=numGlyphs) + return {font.getGlyphName(k): value for k, value in enumerate(data)} + + def readFormat2(self, reader, font): + mapping = {} + pos = reader.pos - 2 # start of table is at UShort for format + unitSize, numUnits = reader.readUShort(), reader.readUShort() + assert unitSize >= 4 + self.converter.staticSize, unitSize + for i in range(numUnits): + reader.seek(pos + i * unitSize + 12) + last = reader.readUShort() + first = reader.readUShort() + value = self.converter.read(reader, font, tableDict=None) + if last != 0xFFFF: + for k in range(first, last + 1): + mapping[font.getGlyphName(k)] = value + return mapping + + def readFormat4(self, reader, font): + mapping = {} + pos = reader.pos - 2 # start of table is at UShort for format + unitSize = reader.readUShort() + assert unitSize >= 6, unitSize + for i in range(reader.readUShort()): + reader.seek(pos + i * unitSize + 12) + last = reader.readUShort() + first = reader.readUShort() + offset = reader.readUShort() + if last != 0xFFFF: + dataReader = reader.getSubReader(0) # relative to current position + dataReader.seek(pos + offset) # relative to start of table + data = self.converter.readArray( + dataReader, font, tableDict=None, count=last - first + 1 + ) + for k, v in enumerate(data): + mapping[font.getGlyphName(first + k)] = v + return mapping + + def readFormat6(self, reader, font): + mapping = {} + pos = reader.pos - 2 # start of table is at UShort for format + unitSize = reader.readUShort() + assert unitSize >= 2 + self.converter.staticSize, unitSize + for i in range(reader.readUShort()): + reader.seek(pos + i * unitSize + 12) + glyphID = reader.readUShort() + value = self.converter.read(reader, font, tableDict=None) + if glyphID != 0xFFFF: + mapping[font.getGlyphName(glyphID)] = value + return mapping + + def readFormat8(self, reader, font): + first = reader.readUShort() + count = reader.readUShort() + data = self.converter.readArray(reader, font, tableDict=None, count=count) + return {font.getGlyphName(first + k): value for (k, value) in enumerate(data)} + + def xmlRead(self, attrs, content, font): + value = {} + for element in content: + if isinstance(element, tuple): + name, a, eltContent = element + if name == "Lookup": + value[a["glyph"]] = self.converter.xmlRead(a, eltContent, font) + return value + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + xmlWriter.begintag(name, attrs) + xmlWriter.newline() + for glyph, value in sorted(value.items()): + self.converter.xmlWrite( + xmlWriter, font, value=value, name="Lookup", attrs=[("glyph", glyph)] + ) + xmlWriter.endtag(name) + xmlWriter.newline() + + +# The AAT 'ankr' table has an unusual structure: An offset to an AATLookup +# followed by an offset to a glyph data table. Other than usual, the +# offsets in the AATLookup are not relative to the beginning of +# the beginning of the 'ankr' table, but relative to the glyph data table. +# So, to find the anchor data for a glyph, one needs to add the offset +# to the data table to the offset found in the AATLookup, and then use +# the sum of these two offsets to find the actual data. +class AATLookupWithDataOffset(BaseConverter): + def read(self, reader, font, tableDict): + lookupOffset = reader.readULong() + dataOffset = reader.readULong() + lookupReader = reader.getSubReader(lookupOffset) + lookup = AATLookup("DataOffsets", None, None, UShort) + offsets = lookup.read(lookupReader, font, tableDict) + result = {} + for glyph, offset in offsets.items(): + dataReader = reader.getSubReader(offset + dataOffset) + item = self.tableClass() + item.decompile(dataReader, font) + result[glyph] = item + return result + + def write(self, writer, font, tableDict, value, repeatIndex=None): + # We do not work with OTTableWriter sub-writers because + # the offsets in our AATLookup are relative to our data + # table, for which we need to provide an offset value itself. + # It might have been possible to somehow make a kludge for + # performing this indirect offset computation directly inside + # OTTableWriter. But this would have made the internal logic + # of OTTableWriter even more complex than it already is, + # so we decided to roll our own offset computation for the + # contents of the AATLookup and associated data table. + offsetByGlyph, offsetByData, dataLen = {}, {}, 0 + compiledData = [] + for glyph in sorted(value, key=font.getGlyphID): + subWriter = OTTableWriter() + value[glyph].compile(subWriter, font) + data = subWriter.getAllData() + offset = offsetByData.get(data, None) + if offset == None: + offset = dataLen + dataLen = dataLen + len(data) + offsetByData[data] = offset + compiledData.append(data) + offsetByGlyph[glyph] = offset + # For calculating the offsets to our AATLookup and data table, + # we can use the regular OTTableWriter infrastructure. + lookupWriter = writer.getSubWriter() + lookup = AATLookup("DataOffsets", None, None, UShort) + lookup.write(lookupWriter, font, tableDict, offsetByGlyph, None) + + dataWriter = writer.getSubWriter() + writer.writeSubTable(lookupWriter, offsetSize=4) + writer.writeSubTable(dataWriter, offsetSize=4) + for d in compiledData: + dataWriter.writeData(d) + + def xmlRead(self, attrs, content, font): + lookup = AATLookup("DataOffsets", None, None, self.tableClass) + return lookup.xmlRead(attrs, content, font) + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + lookup = AATLookup("DataOffsets", None, None, self.tableClass) + lookup.xmlWrite(xmlWriter, font, value, name, attrs) + + +class MorxSubtableConverter(BaseConverter): + _PROCESSING_ORDERS = { + # bits 30 and 28 of morx.CoverageFlags; see morx spec + (False, False): "LayoutOrder", + (True, False): "ReversedLayoutOrder", + (False, True): "LogicalOrder", + (True, True): "ReversedLogicalOrder", + } + + _PROCESSING_ORDERS_REVERSED = {val: key for key, val in _PROCESSING_ORDERS.items()} + + def __init__(self, name, repeat, aux, tableClass=None, *, description=""): + BaseConverter.__init__( + self, name, repeat, aux, tableClass, description=description + ) + + def _setTextDirectionFromCoverageFlags(self, flags, subtable): + if (flags & 0x20) != 0: + subtable.TextDirection = "Any" + elif (flags & 0x80) != 0: + subtable.TextDirection = "Vertical" + else: + subtable.TextDirection = "Horizontal" + + def read(self, reader, font, tableDict): + pos = reader.pos + m = MorxSubtable() + m.StructLength = reader.readULong() + flags = reader.readUInt8() + orderKey = ((flags & 0x40) != 0, (flags & 0x10) != 0) + m.ProcessingOrder = self._PROCESSING_ORDERS[orderKey] + self._setTextDirectionFromCoverageFlags(flags, m) + m.Reserved = reader.readUShort() + m.Reserved |= (flags & 0xF) << 16 + m.MorphType = reader.readUInt8() + m.SubFeatureFlags = reader.readULong() + tableClass = lookupTypes["morx"].get(m.MorphType) + if tableClass is None: + assert False, "unsupported 'morx' lookup type %s" % m.MorphType + # To decode AAT ligatures, we need to know the subtable size. + # The easiest way to pass this along is to create a new reader + # that works on just the subtable as its data. + headerLength = reader.pos - pos + data = reader.data[reader.pos : reader.pos + m.StructLength - headerLength] + assert len(data) == m.StructLength - headerLength + subReader = OTTableReader(data=data, tableTag=reader.tableTag) + m.SubStruct = tableClass() + m.SubStruct.decompile(subReader, font) + reader.seek(pos + m.StructLength) + return m + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + xmlWriter.begintag(name, attrs) + xmlWriter.newline() + xmlWriter.comment("StructLength=%d" % value.StructLength) + xmlWriter.newline() + xmlWriter.simpletag("TextDirection", value=value.TextDirection) + xmlWriter.newline() + xmlWriter.simpletag("ProcessingOrder", value=value.ProcessingOrder) + xmlWriter.newline() + if value.Reserved != 0: + xmlWriter.simpletag("Reserved", value="0x%04x" % value.Reserved) + xmlWriter.newline() + xmlWriter.comment("MorphType=%d" % value.MorphType) + xmlWriter.newline() + xmlWriter.simpletag("SubFeatureFlags", value="0x%08x" % value.SubFeatureFlags) + xmlWriter.newline() + value.SubStruct.toXML(xmlWriter, font) + xmlWriter.endtag(name) + xmlWriter.newline() + + def xmlRead(self, attrs, content, font): + m = MorxSubtable() + covFlags = 0 + m.Reserved = 0 + for eltName, eltAttrs, eltContent in filter(istuple, content): + if eltName == "CoverageFlags": + # Only in XML from old versions of fonttools. + covFlags = safeEval(eltAttrs["value"]) + orderKey = ((covFlags & 0x40) != 0, (covFlags & 0x10) != 0) + m.ProcessingOrder = self._PROCESSING_ORDERS[orderKey] + self._setTextDirectionFromCoverageFlags(covFlags, m) + elif eltName == "ProcessingOrder": + m.ProcessingOrder = eltAttrs["value"] + assert m.ProcessingOrder in self._PROCESSING_ORDERS_REVERSED, ( + "unknown ProcessingOrder: %s" % m.ProcessingOrder + ) + elif eltName == "TextDirection": + m.TextDirection = eltAttrs["value"] + assert m.TextDirection in {"Horizontal", "Vertical", "Any"}, ( + "unknown TextDirection %s" % m.TextDirection + ) + elif eltName == "Reserved": + m.Reserved = safeEval(eltAttrs["value"]) + elif eltName == "SubFeatureFlags": + m.SubFeatureFlags = safeEval(eltAttrs["value"]) + elif eltName.endswith("Morph"): + m.fromXML(eltName, eltAttrs, eltContent, font) + else: + assert False, eltName + m.Reserved = (covFlags & 0xF) << 16 | m.Reserved + return m + + def write(self, writer, font, tableDict, value, repeatIndex=None): + covFlags = (value.Reserved & 0x000F0000) >> 16 + reverseOrder, logicalOrder = self._PROCESSING_ORDERS_REVERSED[ + value.ProcessingOrder + ] + covFlags |= 0x80 if value.TextDirection == "Vertical" else 0 + covFlags |= 0x40 if reverseOrder else 0 + covFlags |= 0x20 if value.TextDirection == "Any" else 0 + covFlags |= 0x10 if logicalOrder else 0 + value.CoverageFlags = covFlags + lengthIndex = len(writer.items) + before = writer.getDataLength() + value.StructLength = 0xDEADBEEF + # The high nibble of value.Reserved is actuallly encoded + # into coverageFlags, so we need to clear it here. + origReserved = value.Reserved # including high nibble + value.Reserved = value.Reserved & 0xFFFF # without high nibble + value.compile(writer, font) + value.Reserved = origReserved # restore original value + assert writer.items[lengthIndex] == b"\xde\xad\xbe\xef" + length = writer.getDataLength() - before + writer.items[lengthIndex] = struct.pack(">L", length) + + +# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6Tables.html#ExtendedStateHeader +# TODO: Untangle the implementation of the various lookup-specific formats. +class STXHeader(BaseConverter): + def __init__(self, name, repeat, aux, tableClass, *, description=""): + BaseConverter.__init__( + self, name, repeat, aux, tableClass, description=description + ) + assert issubclass(self.tableClass, AATAction) + self.classLookup = AATLookup("GlyphClasses", None, None, UShort) + if issubclass(self.tableClass, ContextualMorphAction): + self.perGlyphLookup = AATLookup("PerGlyphLookup", None, None, GlyphID) + else: + self.perGlyphLookup = None + + def read(self, reader, font, tableDict): + table = AATStateTable() + pos = reader.pos + classTableReader = reader.getSubReader(0) + stateArrayReader = reader.getSubReader(0) + entryTableReader = reader.getSubReader(0) + actionReader = None + ligaturesReader = None + table.GlyphClassCount = reader.readULong() + classTableReader.seek(pos + reader.readULong()) + stateArrayReader.seek(pos + reader.readULong()) + entryTableReader.seek(pos + reader.readULong()) + if self.perGlyphLookup is not None: + perGlyphTableReader = reader.getSubReader(0) + perGlyphTableReader.seek(pos + reader.readULong()) + if issubclass(self.tableClass, LigatureMorphAction): + actionReader = reader.getSubReader(0) + actionReader.seek(pos + reader.readULong()) + ligComponentReader = reader.getSubReader(0) + ligComponentReader.seek(pos + reader.readULong()) + ligaturesReader = reader.getSubReader(0) + ligaturesReader.seek(pos + reader.readULong()) + numLigComponents = (ligaturesReader.pos - ligComponentReader.pos) // 2 + assert numLigComponents >= 0 + table.LigComponents = ligComponentReader.readUShortArray(numLigComponents) + table.Ligatures = self._readLigatures(ligaturesReader, font) + elif issubclass(self.tableClass, InsertionMorphAction): + actionReader = reader.getSubReader(0) + actionReader.seek(pos + reader.readULong()) + table.GlyphClasses = self.classLookup.read(classTableReader, font, tableDict) + numStates = int( + (entryTableReader.pos - stateArrayReader.pos) / (table.GlyphClassCount * 2) + ) + for stateIndex in range(numStates): + state = AATState() + table.States.append(state) + for glyphClass in range(table.GlyphClassCount): + entryIndex = stateArrayReader.readUShort() + state.Transitions[glyphClass] = self._readTransition( + entryTableReader, entryIndex, font, actionReader + ) + if self.perGlyphLookup is not None: + table.PerGlyphLookups = self._readPerGlyphLookups( + table, perGlyphTableReader, font + ) + return table + + def _readTransition(self, reader, entryIndex, font, actionReader): + transition = self.tableClass() + entryReader = reader.getSubReader( + reader.pos + entryIndex * transition.staticSize + ) + transition.decompile(entryReader, font, actionReader) + return transition + + def _readLigatures(self, reader, font): + limit = len(reader.data) + numLigatureGlyphs = (limit - reader.pos) // 2 + return font.getGlyphNameMany(reader.readUShortArray(numLigatureGlyphs)) + + def _countPerGlyphLookups(self, table): + # Somewhat annoyingly, the morx table does not encode + # the size of the per-glyph table. So we need to find + # the maximum value that MorphActions use as index + # into this table. + numLookups = 0 + for state in table.States: + for t in state.Transitions.values(): + if isinstance(t, ContextualMorphAction): + if t.MarkIndex != 0xFFFF: + numLookups = max(numLookups, t.MarkIndex + 1) + if t.CurrentIndex != 0xFFFF: + numLookups = max(numLookups, t.CurrentIndex + 1) + return numLookups + + def _readPerGlyphLookups(self, table, reader, font): + pos = reader.pos + lookups = [] + for _ in range(self._countPerGlyphLookups(table)): + lookupReader = reader.getSubReader(0) + lookupReader.seek(pos + reader.readULong()) + lookups.append(self.perGlyphLookup.read(lookupReader, font, {})) + return lookups + + def write(self, writer, font, tableDict, value, repeatIndex=None): + glyphClassWriter = OTTableWriter() + self.classLookup.write( + glyphClassWriter, font, tableDict, value.GlyphClasses, repeatIndex=None + ) + glyphClassData = pad(glyphClassWriter.getAllData(), 2) + glyphClassCount = max(value.GlyphClasses.values()) + 1 + glyphClassTableOffset = 16 # size of STXHeader + if self.perGlyphLookup is not None: + glyphClassTableOffset += 4 + + glyphClassTableOffset += self.tableClass.actionHeaderSize + actionData, actionIndex = self.tableClass.compileActions(font, value.States) + stateArrayData, entryTableData = self._compileStates( + font, value.States, glyphClassCount, actionIndex + ) + stateArrayOffset = glyphClassTableOffset + len(glyphClassData) + entryTableOffset = stateArrayOffset + len(stateArrayData) + perGlyphOffset = entryTableOffset + len(entryTableData) + perGlyphData = pad(self._compilePerGlyphLookups(value, font), 4) + if actionData is not None: + actionOffset = entryTableOffset + len(entryTableData) + else: + actionOffset = None + + ligaturesOffset, ligComponentsOffset = None, None + ligComponentsData = self._compileLigComponents(value, font) + ligaturesData = self._compileLigatures(value, font) + if ligComponentsData is not None: + assert len(perGlyphData) == 0 + ligComponentsOffset = actionOffset + len(actionData) + ligaturesOffset = ligComponentsOffset + len(ligComponentsData) + + writer.writeULong(glyphClassCount) + writer.writeULong(glyphClassTableOffset) + writer.writeULong(stateArrayOffset) + writer.writeULong(entryTableOffset) + if self.perGlyphLookup is not None: + writer.writeULong(perGlyphOffset) + if actionOffset is not None: + writer.writeULong(actionOffset) + if ligComponentsOffset is not None: + writer.writeULong(ligComponentsOffset) + writer.writeULong(ligaturesOffset) + writer.writeData(glyphClassData) + writer.writeData(stateArrayData) + writer.writeData(entryTableData) + writer.writeData(perGlyphData) + if actionData is not None: + writer.writeData(actionData) + if ligComponentsData is not None: + writer.writeData(ligComponentsData) + if ligaturesData is not None: + writer.writeData(ligaturesData) + + def _compileStates(self, font, states, glyphClassCount, actionIndex): + stateArrayWriter = OTTableWriter() + entries, entryIDs = [], {} + for state in states: + for glyphClass in range(glyphClassCount): + transition = state.Transitions[glyphClass] + entryWriter = OTTableWriter() + transition.compile(entryWriter, font, actionIndex) + entryData = entryWriter.getAllData() + assert ( + len(entryData) == transition.staticSize + ), "%s has staticSize %d, " "but actually wrote %d bytes" % ( + repr(transition), + transition.staticSize, + len(entryData), + ) + entryIndex = entryIDs.get(entryData) + if entryIndex is None: + entryIndex = len(entries) + entryIDs[entryData] = entryIndex + entries.append(entryData) + stateArrayWriter.writeUShort(entryIndex) + stateArrayData = pad(stateArrayWriter.getAllData(), 4) + entryTableData = pad(bytesjoin(entries), 4) + return stateArrayData, entryTableData + + def _compilePerGlyphLookups(self, table, font): + if self.perGlyphLookup is None: + return b"" + numLookups = self._countPerGlyphLookups(table) + assert len(table.PerGlyphLookups) == numLookups, ( + "len(AATStateTable.PerGlyphLookups) is %d, " + "but the actions inside the table refer to %d" + % (len(table.PerGlyphLookups), numLookups) + ) + writer = OTTableWriter() + for lookup in table.PerGlyphLookups: + lookupWriter = writer.getSubWriter() + self.perGlyphLookup.write(lookupWriter, font, {}, lookup, None) + writer.writeSubTable(lookupWriter, offsetSize=4) + return writer.getAllData() + + def _compileLigComponents(self, table, font): + if not hasattr(table, "LigComponents"): + return None + writer = OTTableWriter() + for component in table.LigComponents: + writer.writeUShort(component) + return writer.getAllData() + + def _compileLigatures(self, table, font): + if not hasattr(table, "Ligatures"): + return None + writer = OTTableWriter() + for glyphName in table.Ligatures: + writer.writeUShort(font.getGlyphID(glyphName)) + return writer.getAllData() + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + xmlWriter.begintag(name, attrs) + xmlWriter.newline() + xmlWriter.comment("GlyphClassCount=%s" % value.GlyphClassCount) + xmlWriter.newline() + for g, klass in sorted(value.GlyphClasses.items()): + xmlWriter.simpletag("GlyphClass", glyph=g, value=klass) + xmlWriter.newline() + for stateIndex, state in enumerate(value.States): + xmlWriter.begintag("State", index=stateIndex) + xmlWriter.newline() + for glyphClass, trans in sorted(state.Transitions.items()): + trans.toXML( + xmlWriter, + font=font, + attrs={"onGlyphClass": glyphClass}, + name="Transition", + ) + xmlWriter.endtag("State") + xmlWriter.newline() + for i, lookup in enumerate(value.PerGlyphLookups): + xmlWriter.begintag("PerGlyphLookup", index=i) + xmlWriter.newline() + for glyph, val in sorted(lookup.items()): + xmlWriter.simpletag("Lookup", glyph=glyph, value=val) + xmlWriter.newline() + xmlWriter.endtag("PerGlyphLookup") + xmlWriter.newline() + if hasattr(value, "LigComponents"): + xmlWriter.begintag("LigComponents") + xmlWriter.newline() + for i, val in enumerate(getattr(value, "LigComponents")): + xmlWriter.simpletag("LigComponent", index=i, value=val) + xmlWriter.newline() + xmlWriter.endtag("LigComponents") + xmlWriter.newline() + self._xmlWriteLigatures(xmlWriter, font, value, name, attrs) + xmlWriter.endtag(name) + xmlWriter.newline() + + def _xmlWriteLigatures(self, xmlWriter, font, value, name, attrs): + if not hasattr(value, "Ligatures"): + return + xmlWriter.begintag("Ligatures") + xmlWriter.newline() + for i, g in enumerate(getattr(value, "Ligatures")): + xmlWriter.simpletag("Ligature", index=i, glyph=g) + xmlWriter.newline() + xmlWriter.endtag("Ligatures") + xmlWriter.newline() + + def xmlRead(self, attrs, content, font): + table = AATStateTable() + for eltName, eltAttrs, eltContent in filter(istuple, content): + if eltName == "GlyphClass": + glyph = eltAttrs["glyph"] + value = eltAttrs["value"] + table.GlyphClasses[glyph] = safeEval(value) + elif eltName == "State": + state = self._xmlReadState(eltAttrs, eltContent, font) + table.States.append(state) + elif eltName == "PerGlyphLookup": + lookup = self.perGlyphLookup.xmlRead(eltAttrs, eltContent, font) + table.PerGlyphLookups.append(lookup) + elif eltName == "LigComponents": + table.LigComponents = self._xmlReadLigComponents( + eltAttrs, eltContent, font + ) + elif eltName == "Ligatures": + table.Ligatures = self._xmlReadLigatures(eltAttrs, eltContent, font) + table.GlyphClassCount = max(table.GlyphClasses.values()) + 1 + return table + + def _xmlReadState(self, attrs, content, font): + state = AATState() + for eltName, eltAttrs, eltContent in filter(istuple, content): + if eltName == "Transition": + glyphClass = safeEval(eltAttrs["onGlyphClass"]) + transition = self.tableClass() + transition.fromXML(eltName, eltAttrs, eltContent, font) + state.Transitions[glyphClass] = transition + return state + + def _xmlReadLigComponents(self, attrs, content, font): + ligComponents = [] + for eltName, eltAttrs, _eltContent in filter(istuple, content): + if eltName == "LigComponent": + ligComponents.append(safeEval(eltAttrs["value"])) + return ligComponents + + def _xmlReadLigatures(self, attrs, content, font): + ligs = [] + for eltName, eltAttrs, _eltContent in filter(istuple, content): + if eltName == "Ligature": + ligs.append(eltAttrs["glyph"]) + return ligs + + +class CIDGlyphMap(BaseConverter): + def read(self, reader, font, tableDict): + numCIDs = reader.readUShort() + result = {} + for cid, glyphID in enumerate(reader.readUShortArray(numCIDs)): + if glyphID != 0xFFFF: + result[cid] = font.getGlyphName(glyphID) + return result + + def write(self, writer, font, tableDict, value, repeatIndex=None): + items = {cid: font.getGlyphID(glyph) for cid, glyph in value.items()} + count = max(items) + 1 if items else 0 + writer.writeUShort(count) + for cid in range(count): + writer.writeUShort(items.get(cid, 0xFFFF)) + + def xmlRead(self, attrs, content, font): + result = {} + for eName, eAttrs, _eContent in filter(istuple, content): + if eName == "CID": + result[safeEval(eAttrs["cid"])] = eAttrs["glyph"].strip() + return result + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + xmlWriter.begintag(name, attrs) + xmlWriter.newline() + for cid, glyph in sorted(value.items()): + if glyph is not None and glyph != 0xFFFF: + xmlWriter.simpletag("CID", cid=cid, glyph=glyph) + xmlWriter.newline() + xmlWriter.endtag(name) + xmlWriter.newline() + + +class GlyphCIDMap(BaseConverter): + def read(self, reader, font, tableDict): + glyphOrder = font.getGlyphOrder() + count = reader.readUShort() + cids = reader.readUShortArray(count) + if count > len(glyphOrder): + log.warning( + "GlyphCIDMap has %d elements, " + "but the font has only %d glyphs; " + "ignoring the rest" % (count, len(glyphOrder)) + ) + result = {} + for glyphID in range(min(len(cids), len(glyphOrder))): + cid = cids[glyphID] + if cid != 0xFFFF: + result[glyphOrder[glyphID]] = cid + return result + + def write(self, writer, font, tableDict, value, repeatIndex=None): + items = { + font.getGlyphID(g): cid + for g, cid in value.items() + if cid is not None and cid != 0xFFFF + } + count = max(items) + 1 if items else 0 + writer.writeUShort(count) + for glyphID in range(count): + writer.writeUShort(items.get(glyphID, 0xFFFF)) + + def xmlRead(self, attrs, content, font): + result = {} + for eName, eAttrs, _eContent in filter(istuple, content): + if eName == "CID": + result[eAttrs["glyph"]] = safeEval(eAttrs["value"]) + return result + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + xmlWriter.begintag(name, attrs) + xmlWriter.newline() + for glyph, cid in sorted(value.items()): + if cid is not None and cid != 0xFFFF: + xmlWriter.simpletag("CID", glyph=glyph, value=cid) + xmlWriter.newline() + xmlWriter.endtag(name) + xmlWriter.newline() + + +class DeltaValue(BaseConverter): + def read(self, reader, font, tableDict): + StartSize = tableDict["StartSize"] + EndSize = tableDict["EndSize"] + DeltaFormat = tableDict["DeltaFormat"] + assert DeltaFormat in (1, 2, 3), "illegal DeltaFormat" + nItems = EndSize - StartSize + 1 + nBits = 1 << DeltaFormat + minusOffset = 1 << nBits + mask = (1 << nBits) - 1 + signMask = 1 << (nBits - 1) + + DeltaValue = [] + tmp, shift = 0, 0 + for i in range(nItems): + if shift == 0: + tmp, shift = reader.readUShort(), 16 + shift = shift - nBits + value = (tmp >> shift) & mask + if value & signMask: + value = value - minusOffset + DeltaValue.append(value) + return DeltaValue + + def write(self, writer, font, tableDict, value, repeatIndex=None): + StartSize = tableDict["StartSize"] + EndSize = tableDict["EndSize"] + DeltaFormat = tableDict["DeltaFormat"] + DeltaValue = value + assert DeltaFormat in (1, 2, 3), "illegal DeltaFormat" + nItems = EndSize - StartSize + 1 + nBits = 1 << DeltaFormat + assert len(DeltaValue) == nItems + mask = (1 << nBits) - 1 + + tmp, shift = 0, 16 + for value in DeltaValue: + shift = shift - nBits + tmp = tmp | ((value & mask) << shift) + if shift == 0: + writer.writeUShort(tmp) + tmp, shift = 0, 16 + if shift != 16: + writer.writeUShort(tmp) + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + xmlWriter.simpletag(name, attrs + [("value", value)]) + xmlWriter.newline() + + def xmlRead(self, attrs, content, font): + return safeEval(attrs["value"]) + + +class VarIdxMapValue(BaseConverter): + def read(self, reader, font, tableDict): + fmt = tableDict["EntryFormat"] + nItems = tableDict["MappingCount"] + + innerBits = 1 + (fmt & 0x000F) + innerMask = (1 << innerBits) - 1 + outerMask = 0xFFFFFFFF - innerMask + outerShift = 16 - innerBits + + entrySize = 1 + ((fmt & 0x0030) >> 4) + readArray = { + 1: reader.readUInt8Array, + 2: reader.readUShortArray, + 3: reader.readUInt24Array, + 4: reader.readULongArray, + }[entrySize] + + return [ + (((raw & outerMask) << outerShift) | (raw & innerMask)) + for raw in readArray(nItems) + ] + + def write(self, writer, font, tableDict, value, repeatIndex=None): + fmt = tableDict["EntryFormat"] + mapping = value + writer["MappingCount"].setValue(len(mapping)) + + innerBits = 1 + (fmt & 0x000F) + innerMask = (1 << innerBits) - 1 + outerShift = 16 - innerBits + + entrySize = 1 + ((fmt & 0x0030) >> 4) + writeArray = { + 1: writer.writeUInt8Array, + 2: writer.writeUShortArray, + 3: writer.writeUInt24Array, + 4: writer.writeULongArray, + }[entrySize] + + writeArray( + [ + (((idx & 0xFFFF0000) >> outerShift) | (idx & innerMask)) + for idx in mapping + ] + ) + + +class VarDataValue(BaseConverter): + def read(self, reader, font, tableDict): + values = [] + + regionCount = tableDict["VarRegionCount"] + wordCount = tableDict["NumShorts"] + + # https://github.com/fonttools/fonttools/issues/2279 + longWords = bool(wordCount & 0x8000) + wordCount = wordCount & 0x7FFF + + if longWords: + readBigArray, readSmallArray = reader.readLongArray, reader.readShortArray + else: + readBigArray, readSmallArray = reader.readShortArray, reader.readInt8Array + + n1, n2 = min(regionCount, wordCount), max(regionCount, wordCount) + values.extend(readBigArray(n1)) + values.extend(readSmallArray(n2 - n1)) + if n2 > regionCount: # Padding + del values[regionCount:] + + return values + + def write(self, writer, font, tableDict, values, repeatIndex=None): + regionCount = tableDict["VarRegionCount"] + wordCount = tableDict["NumShorts"] + + # https://github.com/fonttools/fonttools/issues/2279 + longWords = bool(wordCount & 0x8000) + wordCount = wordCount & 0x7FFF + + (writeBigArray, writeSmallArray) = { + False: (writer.writeShortArray, writer.writeInt8Array), + True: (writer.writeLongArray, writer.writeShortArray), + }[longWords] + + n1, n2 = min(regionCount, wordCount), max(regionCount, wordCount) + writeBigArray(values[:n1]) + writeSmallArray(values[n1:regionCount]) + if n2 > regionCount: # Padding + writer.writeSmallArray([0] * (n2 - regionCount)) + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + xmlWriter.simpletag(name, attrs + [("value", value)]) + xmlWriter.newline() + + def xmlRead(self, attrs, content, font): + return safeEval(attrs["value"]) + + +class TupleValues: + def read(self, data, font): + return TupleVariation.decompileDeltas_(None, data)[0] + + def write(self, writer, font, tableDict, values, repeatIndex=None): + optimizeSpeed = font.cfg[OPTIMIZE_FONT_SPEED] + return bytes( + TupleVariation.compileDeltaValues_(values, optimizeSize=not optimizeSpeed) + ) + + def xmlRead(self, attrs, content, font): + return safeEval(attrs["value"]) + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + xmlWriter.simpletag(name, attrs + [("value", value)]) + xmlWriter.newline() + + +class CFF2Index(BaseConverter): + def __init__( + self, + name, + repeat, + aux, + tableClass=None, + *, + itemClass=None, + itemConverterClass=None, + description="", + ): + BaseConverter.__init__( + self, name, repeat, aux, tableClass, description=description + ) + self._itemClass = itemClass + self._converter = ( + itemConverterClass() if itemConverterClass is not None else None + ) + + def read(self, reader, font, tableDict): + count = reader.readULong() + if count == 0: + return [] + offSize = reader.readUInt8() + + def getReadArray(reader, offSize): + return { + 1: reader.readUInt8Array, + 2: reader.readUShortArray, + 3: reader.readUInt24Array, + 4: reader.readULongArray, + }[offSize] + + readArray = getReadArray(reader, offSize) + + lazy = font.lazy is not False and count > 8 + if not lazy: + offsets = readArray(count + 1) + items = [] + lastOffset = offsets.pop(0) + reader.readData(lastOffset - 1) # In case first offset is not 1 + + for offset in offsets: + assert lastOffset <= offset + item = reader.readData(offset - lastOffset) + + if self._itemClass is not None: + obj = self._itemClass() + obj.decompile(item, font, reader.localState) + item = obj + elif self._converter is not None: + item = self._converter.read(item, font) + + items.append(item) + lastOffset = offset + return items + else: + + def get_read_item(): + reader_copy = reader.copy() + offset_pos = reader.pos + data_pos = offset_pos + (count + 1) * offSize - 1 + readArray = getReadArray(reader_copy, offSize) + + def read_item(i): + reader_copy.seek(offset_pos + i * offSize) + offsets = readArray(2) + reader_copy.seek(data_pos + offsets[0]) + item = reader_copy.readData(offsets[1] - offsets[0]) + + if self._itemClass is not None: + obj = self._itemClass() + obj.decompile(item, font, reader_copy.localState) + item = obj + elif self._converter is not None: + item = self._converter.read(item, font) + return item + + return read_item + + read_item = get_read_item() + l = LazyList([read_item] * count) + + # TODO: Advance reader + + return l + + def write(self, writer, font, tableDict, values, repeatIndex=None): + items = values + + writer.writeULong(len(items)) + if not len(items): + return + + if self._itemClass is not None: + items = [item.compile(font) for item in items] + elif self._converter is not None: + items = [ + self._converter.write(writer, font, tableDict, item, i) + for i, item in enumerate(items) + ] + + offsets = [len(item) for item in items] + offsets = list(accumulate(offsets, initial=1)) + + lastOffset = offsets[-1] + offSize = ( + 1 + if lastOffset < 0x100 + else 2 if lastOffset < 0x10000 else 3 if lastOffset < 0x1000000 else 4 + ) + writer.writeUInt8(offSize) + + writeArray = { + 1: writer.writeUInt8Array, + 2: writer.writeUShortArray, + 3: writer.writeUInt24Array, + 4: writer.writeULongArray, + }[offSize] + + writeArray(offsets) + for item in items: + writer.writeData(item) + + def xmlRead(self, attrs, content, font): + if self._itemClass is not None: + obj = self._itemClass() + obj.fromXML(None, attrs, content, font) + return obj + elif self._converter is not None: + return self._converter.xmlRead(attrs, content, font) + else: + raise NotImplementedError() + + def xmlWrite(self, xmlWriter, font, value, name, attrs): + if self._itemClass is not None: + for i, item in enumerate(value): + item.toXML(xmlWriter, font, [("index", i)], name) + elif self._converter is not None: + for i, item in enumerate(value): + self._converter.xmlWrite( + xmlWriter, font, item, name, attrs + [("index", i)] + ) + else: + raise NotImplementedError() + + +class LookupFlag(UShort): + def xmlWrite(self, xmlWriter, font, value, name, attrs): + xmlWriter.simpletag(name, attrs + [("value", value)]) + flags = [] + if value & 0x01: + flags.append("rightToLeft") + if value & 0x02: + flags.append("ignoreBaseGlyphs") + if value & 0x04: + flags.append("ignoreLigatures") + if value & 0x08: + flags.append("ignoreMarks") + if value & 0x10: + flags.append("useMarkFilteringSet") + if value & 0xFF00: + flags.append("markAttachmentType[%i]" % (value >> 8)) + if flags: + xmlWriter.comment(" ".join(flags)) + xmlWriter.newline() + + +class _UInt8Enum(UInt8): + enumClass = NotImplemented + + def read(self, reader, font, tableDict): + return self.enumClass(super().read(reader, font, tableDict)) + + @classmethod + def fromString(cls, value): + return getattr(cls.enumClass, value.upper()) + + @classmethod + def toString(cls, value): + return cls.enumClass(value).name.lower() + + +class ExtendMode(_UInt8Enum): + enumClass = _ExtendMode + + +class CompositeMode(_UInt8Enum): + enumClass = _CompositeMode + + +converterMapping = { + # type class + "int8": Int8, + "int16": Short, + "int32": Long, + "uint8": UInt8, + "uint16": UShort, + "uint24": UInt24, + "uint32": ULong, + "char64": Char64, + "Flags32": Flags32, + "VarIndex": VarIndex, + "Version": Version, + "Tag": Tag, + "GlyphID": GlyphID, + "GlyphID32": GlyphID32, + "NameID": NameID, + "DeciPoints": DeciPoints, + "Fixed": Fixed, + "F2Dot14": F2Dot14, + "Angle": Angle, + "BiasedAngle": BiasedAngle, + "struct": Struct, + "Offset": Table, + "LOffset": LTable, + "Offset24": Table24, + "ValueRecord": ValueRecord, + "DeltaValue": DeltaValue, + "VarIdxMapValue": VarIdxMapValue, + "VarDataValue": VarDataValue, + "LookupFlag": LookupFlag, + "ExtendMode": ExtendMode, + "CompositeMode": CompositeMode, + "STATFlags": STATFlags, + "TupleList": partial(CFF2Index, itemConverterClass=TupleValues), + "VarCompositeGlyphList": partial(CFF2Index, itemClass=VarCompositeGlyph), + # AAT + "CIDGlyphMap": CIDGlyphMap, + "GlyphCIDMap": GlyphCIDMap, + "MortChain": StructWithLength, + "MortSubtable": StructWithLength, + "MorxChain": StructWithLength, + "MorxSubtable": MorxSubtableConverter, + # "Template" types + "AATLookup": lambda C: partial(AATLookup, tableClass=C), + "AATLookupWithDataOffset": lambda C: partial(AATLookupWithDataOffset, tableClass=C), + "STXHeader": lambda C: partial(STXHeader, tableClass=C), + "OffsetTo": lambda C: partial(Table, tableClass=C), + "LOffsetTo": lambda C: partial(LTable, tableClass=C), + "LOffset24To": lambda C: partial(Table24, tableClass=C), +} diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/otData.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/otData.py new file mode 100644 index 0000000000000000000000000000000000000000..f538aeb48ca5515edfb36d012da5f2661b6e832d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/otData.py @@ -0,0 +1,6400 @@ +otData = [ + # + # common + # + ("LookupOrder", []), + ( + "ScriptList", + [ + ("uint16", "ScriptCount", None, None, "Number of ScriptRecords"), + ( + "struct", + "ScriptRecord", + "ScriptCount", + 0, + "Array of ScriptRecords -listed alphabetically by ScriptTag", + ), + ], + ), + ( + "ScriptRecord", + [ + ("Tag", "ScriptTag", None, None, "4-byte ScriptTag identifier"), + ( + "Offset", + "Script", + None, + None, + "Offset to Script table-from beginning of ScriptList", + ), + ], + ), + ( + "Script", + [ + ( + "Offset", + "DefaultLangSys", + None, + None, + "Offset to DefaultLangSys table-from beginning of Script table-may be NULL", + ), + ( + "uint16", + "LangSysCount", + None, + None, + "Number of LangSysRecords for this script-excluding the DefaultLangSys", + ), + ( + "struct", + "LangSysRecord", + "LangSysCount", + 0, + "Array of LangSysRecords-listed alphabetically by LangSysTag", + ), + ], + ), + ( + "LangSysRecord", + [ + ("Tag", "LangSysTag", None, None, "4-byte LangSysTag identifier"), + ( + "Offset", + "LangSys", + None, + None, + "Offset to LangSys table-from beginning of Script table", + ), + ], + ), + ( + "LangSys", + [ + ( + "Offset", + "LookupOrder", + None, + None, + "= NULL (reserved for an offset to a reordering table)", + ), + ( + "uint16", + "ReqFeatureIndex", + None, + None, + "Index of a feature required for this language system- if no required features = 0xFFFF", + ), + ( + "uint16", + "FeatureCount", + None, + None, + "Number of FeatureIndex values for this language system-excludes the required feature", + ), + ( + "uint16", + "FeatureIndex", + "FeatureCount", + 0, + "Array of indices into the FeatureList-in arbitrary order", + ), + ], + ), + ( + "FeatureList", + [ + ( + "uint16", + "FeatureCount", + None, + None, + "Number of FeatureRecords in this table", + ), + ( + "struct", + "FeatureRecord", + "FeatureCount", + 0, + "Array of FeatureRecords-zero-based (first feature has FeatureIndex = 0)-listed alphabetically by FeatureTag", + ), + ], + ), + ( + "FeatureRecord", + [ + ("Tag", "FeatureTag", None, None, "4-byte feature identification tag"), + ( + "Offset", + "Feature", + None, + None, + "Offset to Feature table-from beginning of FeatureList", + ), + ], + ), + ( + "Feature", + [ + ( + "Offset", + "FeatureParams", + None, + None, + "= NULL (reserved for offset to FeatureParams)", + ), + ( + "uint16", + "LookupCount", + None, + None, + "Number of LookupList indices for this feature", + ), + ( + "uint16", + "LookupListIndex", + "LookupCount", + 0, + "Array of LookupList indices for this feature -zero-based (first lookup is LookupListIndex = 0)", + ), + ], + ), + ("FeatureParams", []), + ( + "FeatureParamsSize", + [ + ( + "DeciPoints", + "DesignSize", + None, + None, + "The design size in 720/inch units (decipoints).", + ), + ( + "uint16", + "SubfamilyID", + None, + None, + "Serves as an identifier that associates fonts in a subfamily.", + ), + ("NameID", "SubfamilyNameID", None, None, "Subfamily NameID."), + ( + "DeciPoints", + "RangeStart", + None, + None, + "Small end of recommended usage range (exclusive) in 720/inch units.", + ), + ( + "DeciPoints", + "RangeEnd", + None, + None, + "Large end of recommended usage range (inclusive) in 720/inch units.", + ), + ], + ), + ( + "FeatureParamsStylisticSet", + [ + ("uint16", "Version", None, None, "Set to 0."), + ("NameID", "UINameID", None, None, "UI NameID."), + ], + ), + ( + "FeatureParamsCharacterVariants", + [ + ("uint16", "Format", None, None, "Set to 0."), + ("NameID", "FeatUILabelNameID", None, None, "Feature UI label NameID."), + ( + "NameID", + "FeatUITooltipTextNameID", + None, + None, + "Feature UI tooltip text NameID.", + ), + ("NameID", "SampleTextNameID", None, None, "Sample text NameID."), + ("uint16", "NumNamedParameters", None, None, "Number of named parameters."), + ( + "NameID", + "FirstParamUILabelNameID", + None, + None, + "First NameID of UI feature parameters.", + ), + ( + "uint16", + "CharCount", + None, + None, + "Count of characters this feature provides glyph variants for.", + ), + ( + "uint24", + "Character", + "CharCount", + 0, + "Unicode characters for which this feature provides glyph variants.", + ), + ], + ), + ( + "LookupList", + [ + ("uint16", "LookupCount", None, None, "Number of lookups in this table"), + ( + "Offset", + "Lookup", + "LookupCount", + 0, + "Array of offsets to Lookup tables-from beginning of LookupList -zero based (first lookup is Lookup index = 0)", + ), + ], + ), + ( + "Lookup", + [ + ( + "uint16", + "LookupType", + None, + None, + "Different enumerations for GSUB and GPOS", + ), + ("LookupFlag", "LookupFlag", None, None, "Lookup qualifiers"), + ( + "uint16", + "SubTableCount", + None, + None, + "Number of SubTables for this lookup", + ), + ( + "Offset", + "SubTable", + "SubTableCount", + 0, + "Array of offsets to SubTables-from beginning of Lookup table", + ), + ( + "uint16", + "MarkFilteringSet", + None, + "LookupFlag & 0x0010", + "If set, indicates that the lookup table structure is followed by a MarkFilteringSet field. The layout engine skips over all mark glyphs not in the mark filtering set indicated.", + ), + ], + ), + ( + "CoverageFormat1", + [ + ("uint16", "CoverageFormat", None, None, "Format identifier-format = 1"), + ("uint16", "GlyphCount", None, None, "Number of glyphs in the GlyphArray"), + ( + "GlyphID", + "GlyphArray", + "GlyphCount", + 0, + "Array of GlyphIDs-in numerical order", + ), + ], + ), + ( + "CoverageFormat2", + [ + ("uint16", "CoverageFormat", None, None, "Format identifier-format = 2"), + ("uint16", "RangeCount", None, None, "Number of RangeRecords"), + ( + "struct", + "RangeRecord", + "RangeCount", + 0, + "Array of glyph ranges-ordered by Start GlyphID", + ), + ], + ), + ( + "RangeRecord", + [ + ("GlyphID", "Start", None, None, "First GlyphID in the range"), + ("GlyphID", "End", None, None, "Last GlyphID in the range"), + ( + "uint16", + "StartCoverageIndex", + None, + None, + "Coverage Index of first GlyphID in range", + ), + ], + ), + ( + "ClassDefFormat1", + [ + ("uint16", "ClassFormat", None, None, "Format identifier-format = 1"), + ( + "GlyphID", + "StartGlyph", + None, + None, + "First GlyphID of the ClassValueArray", + ), + ("uint16", "GlyphCount", None, None, "Size of the ClassValueArray"), + ( + "uint16", + "ClassValueArray", + "GlyphCount", + 0, + "Array of Class Values-one per GlyphID", + ), + ], + ), + ( + "ClassDefFormat2", + [ + ("uint16", "ClassFormat", None, None, "Format identifier-format = 2"), + ("uint16", "ClassRangeCount", None, None, "Number of ClassRangeRecords"), + ( + "struct", + "ClassRangeRecord", + "ClassRangeCount", + 0, + "Array of ClassRangeRecords-ordered by Start GlyphID", + ), + ], + ), + ( + "ClassRangeRecord", + [ + ("GlyphID", "Start", None, None, "First GlyphID in the range"), + ("GlyphID", "End", None, None, "Last GlyphID in the range"), + ("uint16", "Class", None, None, "Applied to all glyphs in the range"), + ], + ), + ( + "Device", + [ + ("uint16", "StartSize", None, None, "Smallest size to correct-in ppem"), + ("uint16", "EndSize", None, None, "Largest size to correct-in ppem"), + ( + "uint16", + "DeltaFormat", + None, + None, + "Format of DeltaValue array data: 1, 2, or 3", + ), + ( + "DeltaValue", + "DeltaValue", + None, + "DeltaFormat in (1,2,3)", + "Array of compressed data", + ), + ], + ), + # + # gpos + # + ( + "GPOS", + [ + ( + "Version", + "Version", + None, + None, + "Version of the GPOS table- 0x00010000 or 0x00010001", + ), + ( + "Offset", + "ScriptList", + None, + None, + "Offset to ScriptList table-from beginning of GPOS table", + ), + ( + "Offset", + "FeatureList", + None, + None, + "Offset to FeatureList table-from beginning of GPOS table", + ), + ( + "Offset", + "LookupList", + None, + None, + "Offset to LookupList table-from beginning of GPOS table", + ), + ( + "LOffset", + "FeatureVariations", + None, + "Version >= 0x00010001", + "Offset to FeatureVariations table-from beginning of GPOS table", + ), + ], + ), + ( + "SinglePosFormat1", + [ + ("uint16", "PosFormat", None, None, "Format identifier-format = 1"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of SinglePos subtable", + ), + ( + "uint16", + "ValueFormat", + None, + None, + "Defines the types of data in the ValueRecord", + ), + ( + "ValueRecord", + "Value", + None, + None, + "Defines positioning value(s)-applied to all glyphs in the Coverage table", + ), + ], + ), + ( + "SinglePosFormat2", + [ + ("uint16", "PosFormat", None, None, "Format identifier-format = 2"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of SinglePos subtable", + ), + ( + "uint16", + "ValueFormat", + None, + None, + "Defines the types of data in the ValueRecord", + ), + ("uint16", "ValueCount", None, None, "Number of ValueRecords"), + ( + "ValueRecord", + "Value", + "ValueCount", + 0, + "Array of ValueRecords-positioning values applied to glyphs", + ), + ], + ), + ( + "PairPosFormat1", + [ + ("uint16", "PosFormat", None, None, "Format identifier-format = 1"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of PairPos subtable-only the first glyph in each pair", + ), + ( + "uint16", + "ValueFormat1", + None, + None, + "Defines the types of data in ValueRecord1-for the first glyph in the pair -may be zero (0)", + ), + ( + "uint16", + "ValueFormat2", + None, + None, + "Defines the types of data in ValueRecord2-for the second glyph in the pair -may be zero (0)", + ), + ("uint16", "PairSetCount", None, None, "Number of PairSet tables"), + ( + "Offset", + "PairSet", + "PairSetCount", + 0, + "Array of offsets to PairSet tables-from beginning of PairPos subtable-ordered by Coverage Index", + ), + ], + ), + ( + "PairSet", + [ + ("uint16", "PairValueCount", None, None, "Number of PairValueRecords"), + ( + "struct", + "PairValueRecord", + "PairValueCount", + 0, + "Array of PairValueRecords-ordered by GlyphID of the second glyph", + ), + ], + ), + ( + "PairValueRecord", + [ + ( + "GlyphID", + "SecondGlyph", + None, + None, + "GlyphID of second glyph in the pair-first glyph is listed in the Coverage table", + ), + ( + "ValueRecord", + "Value1", + None, + None, + "Positioning data for the first glyph in the pair", + ), + ( + "ValueRecord", + "Value2", + None, + None, + "Positioning data for the second glyph in the pair", + ), + ], + ), + ( + "PairPosFormat2", + [ + ("uint16", "PosFormat", None, None, "Format identifier-format = 2"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of PairPos subtable-for the first glyph of the pair", + ), + ( + "uint16", + "ValueFormat1", + None, + None, + "ValueRecord definition-for the first glyph of the pair-may be zero (0)", + ), + ( + "uint16", + "ValueFormat2", + None, + None, + "ValueRecord definition-for the second glyph of the pair-may be zero (0)", + ), + ( + "Offset", + "ClassDef1", + None, + None, + "Offset to ClassDef table-from beginning of PairPos subtable-for the first glyph of the pair", + ), + ( + "Offset", + "ClassDef2", + None, + None, + "Offset to ClassDef table-from beginning of PairPos subtable-for the second glyph of the pair", + ), + ( + "uint16", + "Class1Count", + None, + None, + "Number of classes in ClassDef1 table-includes Class0", + ), + ( + "uint16", + "Class2Count", + None, + None, + "Number of classes in ClassDef2 table-includes Class0", + ), + ( + "struct", + "Class1Record", + "Class1Count", + 0, + "Array of Class1 records-ordered by Class1", + ), + ], + ), + ( + "Class1Record", + [ + ( + "struct", + "Class2Record", + "Class2Count", + 0, + "Array of Class2 records-ordered by Class2", + ), + ], + ), + ( + "Class2Record", + [ + ( + "ValueRecord", + "Value1", + None, + None, + "Positioning for first glyph-empty if ValueFormat1 = 0", + ), + ( + "ValueRecord", + "Value2", + None, + None, + "Positioning for second glyph-empty if ValueFormat2 = 0", + ), + ], + ), + ( + "CursivePosFormat1", + [ + ("uint16", "PosFormat", None, None, "Format identifier-format = 1"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of CursivePos subtable", + ), + ("uint16", "EntryExitCount", None, None, "Number of EntryExit records"), + ( + "struct", + "EntryExitRecord", + "EntryExitCount", + 0, + "Array of EntryExit records-in Coverage Index order", + ), + ], + ), + ( + "EntryExitRecord", + [ + ( + "Offset", + "EntryAnchor", + None, + None, + "Offset to EntryAnchor table-from beginning of CursivePos subtable-may be NULL", + ), + ( + "Offset", + "ExitAnchor", + None, + None, + "Offset to ExitAnchor table-from beginning of CursivePos subtable-may be NULL", + ), + ], + ), + ( + "MarkBasePosFormat1", + [ + ("uint16", "PosFormat", None, None, "Format identifier-format = 1"), + ( + "Offset", + "MarkCoverage", + None, + None, + "Offset to MarkCoverage table-from beginning of MarkBasePos subtable", + ), + ( + "Offset", + "BaseCoverage", + None, + None, + "Offset to BaseCoverage table-from beginning of MarkBasePos subtable", + ), + ("uint16", "ClassCount", None, None, "Number of classes defined for marks"), + ( + "Offset", + "MarkArray", + None, + None, + "Offset to MarkArray table-from beginning of MarkBasePos subtable", + ), + ( + "Offset", + "BaseArray", + None, + None, + "Offset to BaseArray table-from beginning of MarkBasePos subtable", + ), + ], + ), + ( + "BaseArray", + [ + ("uint16", "BaseCount", None, None, "Number of BaseRecords"), + ( + "struct", + "BaseRecord", + "BaseCount", + 0, + "Array of BaseRecords-in order of BaseCoverage Index", + ), + ], + ), + ( + "BaseRecord", + [ + ( + "Offset", + "BaseAnchor", + "ClassCount", + 0, + "Array of offsets (one per class) to Anchor tables-from beginning of BaseArray table-ordered by class-zero-based", + ), + ], + ), + ( + "MarkLigPosFormat1", + [ + ("uint16", "PosFormat", None, None, "Format identifier-format = 1"), + ( + "Offset", + "MarkCoverage", + None, + None, + "Offset to Mark Coverage table-from beginning of MarkLigPos subtable", + ), + ( + "Offset", + "LigatureCoverage", + None, + None, + "Offset to Ligature Coverage table-from beginning of MarkLigPos subtable", + ), + ("uint16", "ClassCount", None, None, "Number of defined mark classes"), + ( + "Offset", + "MarkArray", + None, + None, + "Offset to MarkArray table-from beginning of MarkLigPos subtable", + ), + ( + "Offset", + "LigatureArray", + None, + None, + "Offset to LigatureArray table-from beginning of MarkLigPos subtable", + ), + ], + ), + ( + "LigatureArray", + [ + ( + "uint16", + "LigatureCount", + None, + None, + "Number of LigatureAttach table offsets", + ), + ( + "Offset", + "LigatureAttach", + "LigatureCount", + 0, + "Array of offsets to LigatureAttach tables-from beginning of LigatureArray table-ordered by LigatureCoverage Index", + ), + ], + ), + ( + "LigatureAttach", + [ + ( + "uint16", + "ComponentCount", + None, + None, + "Number of ComponentRecords in this ligature", + ), + ( + "struct", + "ComponentRecord", + "ComponentCount", + 0, + "Array of Component records-ordered in writing direction", + ), + ], + ), + ( + "ComponentRecord", + [ + ( + "Offset", + "LigatureAnchor", + "ClassCount", + 0, + "Array of offsets (one per class) to Anchor tables-from beginning of LigatureAttach table-ordered by class-NULL if a component does not have an attachment for a class-zero-based array", + ), + ], + ), + ( + "MarkMarkPosFormat1", + [ + ("uint16", "PosFormat", None, None, "Format identifier-format = 1"), + ( + "Offset", + "Mark1Coverage", + None, + None, + "Offset to Combining Mark Coverage table-from beginning of MarkMarkPos subtable", + ), + ( + "Offset", + "Mark2Coverage", + None, + None, + "Offset to Base Mark Coverage table-from beginning of MarkMarkPos subtable", + ), + ( + "uint16", + "ClassCount", + None, + None, + "Number of Combining Mark classes defined", + ), + ( + "Offset", + "Mark1Array", + None, + None, + "Offset to MarkArray table for Mark1-from beginning of MarkMarkPos subtable", + ), + ( + "Offset", + "Mark2Array", + None, + None, + "Offset to Mark2Array table for Mark2-from beginning of MarkMarkPos subtable", + ), + ], + ), + ( + "Mark2Array", + [ + ("uint16", "Mark2Count", None, None, "Number of Mark2 records"), + ( + "struct", + "Mark2Record", + "Mark2Count", + 0, + "Array of Mark2 records-in Coverage order", + ), + ], + ), + ( + "Mark2Record", + [ + ( + "Offset", + "Mark2Anchor", + "ClassCount", + 0, + "Array of offsets (one per class) to Anchor tables-from beginning of Mark2Array table-zero-based array", + ), + ], + ), + ( + "PosLookupRecord", + [ + ( + "uint16", + "SequenceIndex", + None, + None, + "Index to input glyph sequence-first glyph = 0", + ), + ( + "uint16", + "LookupListIndex", + None, + None, + "Lookup to apply to that position-zero-based", + ), + ], + ), + ( + "ContextPosFormat1", + [ + ("uint16", "PosFormat", None, None, "Format identifier-format = 1"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of ContextPos subtable", + ), + ("uint16", "PosRuleSetCount", None, None, "Number of PosRuleSet tables"), + ( + "Offset", + "PosRuleSet", + "PosRuleSetCount", + 0, + "Array of offsets to PosRuleSet tables-from beginning of ContextPos subtable-ordered by Coverage Index", + ), + ], + ), + ( + "PosRuleSet", + [ + ("uint16", "PosRuleCount", None, None, "Number of PosRule tables"), + ( + "Offset", + "PosRule", + "PosRuleCount", + 0, + "Array of offsets to PosRule tables-from beginning of PosRuleSet-ordered by preference", + ), + ], + ), + ( + "PosRule", + [ + ( + "uint16", + "GlyphCount", + None, + None, + "Number of glyphs in the Input glyph sequence", + ), + ("uint16", "PosCount", None, None, "Number of PosLookupRecords"), + ( + "GlyphID", + "Input", + "GlyphCount", + -1, + "Array of input GlyphIDs-starting with the second glyph", + ), + ( + "struct", + "PosLookupRecord", + "PosCount", + 0, + "Array of positioning lookups-in design order", + ), + ], + ), + ( + "ContextPosFormat2", + [ + ("uint16", "PosFormat", None, None, "Format identifier-format = 2"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of ContextPos subtable", + ), + ( + "Offset", + "ClassDef", + None, + None, + "Offset to ClassDef table-from beginning of ContextPos subtable", + ), + ("uint16", "PosClassSetCount", None, None, "Number of PosClassSet tables"), + ( + "Offset", + "PosClassSet", + "PosClassSetCount", + 0, + "Array of offsets to PosClassSet tables-from beginning of ContextPos subtable-ordered by class-may be NULL", + ), + ], + ), + ( + "PosClassSet", + [ + ( + "uint16", + "PosClassRuleCount", + None, + None, + "Number of PosClassRule tables", + ), + ( + "Offset", + "PosClassRule", + "PosClassRuleCount", + 0, + "Array of offsets to PosClassRule tables-from beginning of PosClassSet-ordered by preference", + ), + ], + ), + ( + "PosClassRule", + [ + ("uint16", "GlyphCount", None, None, "Number of glyphs to be matched"), + ("uint16", "PosCount", None, None, "Number of PosLookupRecords"), + ( + "uint16", + "Class", + "GlyphCount", + -1, + "Array of classes-beginning with the second class-to be matched to the input glyph sequence", + ), + ( + "struct", + "PosLookupRecord", + "PosCount", + 0, + "Array of positioning lookups-in design order", + ), + ], + ), + ( + "ContextPosFormat3", + [ + ("uint16", "PosFormat", None, None, "Format identifier-format = 3"), + ( + "uint16", + "GlyphCount", + None, + None, + "Number of glyphs in the input sequence", + ), + ("uint16", "PosCount", None, None, "Number of PosLookupRecords"), + ( + "Offset", + "Coverage", + "GlyphCount", + 0, + "Array of offsets to Coverage tables-from beginning of ContextPos subtable", + ), + ( + "struct", + "PosLookupRecord", + "PosCount", + 0, + "Array of positioning lookups-in design order", + ), + ], + ), + ( + "ChainContextPosFormat1", + [ + ("uint16", "PosFormat", None, None, "Format identifier-format = 1"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of ContextPos subtable", + ), + ( + "uint16", + "ChainPosRuleSetCount", + None, + None, + "Number of ChainPosRuleSet tables", + ), + ( + "Offset", + "ChainPosRuleSet", + "ChainPosRuleSetCount", + 0, + "Array of offsets to ChainPosRuleSet tables-from beginning of ContextPos subtable-ordered by Coverage Index", + ), + ], + ), + ( + "ChainPosRuleSet", + [ + ( + "uint16", + "ChainPosRuleCount", + None, + None, + "Number of ChainPosRule tables", + ), + ( + "Offset", + "ChainPosRule", + "ChainPosRuleCount", + 0, + "Array of offsets to ChainPosRule tables-from beginning of ChainPosRuleSet-ordered by preference", + ), + ], + ), + ( + "ChainPosRule", + [ + ( + "uint16", + "BacktrackGlyphCount", + None, + None, + "Total number of glyphs in the backtrack sequence (number of glyphs to be matched before the first glyph)", + ), + ( + "GlyphID", + "Backtrack", + "BacktrackGlyphCount", + 0, + "Array of backtracking GlyphID's (to be matched before the input sequence)", + ), + ( + "uint16", + "InputGlyphCount", + None, + None, + "Total number of glyphs in the input sequence (includes the first glyph)", + ), + ( + "GlyphID", + "Input", + "InputGlyphCount", + -1, + "Array of input GlyphIDs (start with second glyph)", + ), + ( + "uint16", + "LookAheadGlyphCount", + None, + None, + "Total number of glyphs in the look ahead sequence (number of glyphs to be matched after the input sequence)", + ), + ( + "GlyphID", + "LookAhead", + "LookAheadGlyphCount", + 0, + "Array of lookahead GlyphID's (to be matched after the input sequence)", + ), + ("uint16", "PosCount", None, None, "Number of PosLookupRecords"), + ( + "struct", + "PosLookupRecord", + "PosCount", + 0, + "Array of PosLookupRecords (in design order)", + ), + ], + ), + ( + "ChainContextPosFormat2", + [ + ("uint16", "PosFormat", None, None, "Format identifier-format = 2"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of ChainContextPos subtable", + ), + ( + "Offset", + "BacktrackClassDef", + None, + None, + "Offset to ClassDef table containing backtrack sequence context-from beginning of ChainContextPos subtable", + ), + ( + "Offset", + "InputClassDef", + None, + None, + "Offset to ClassDef table containing input sequence context-from beginning of ChainContextPos subtable", + ), + ( + "Offset", + "LookAheadClassDef", + None, + None, + "Offset to ClassDef table containing lookahead sequence context-from beginning of ChainContextPos subtable", + ), + ( + "uint16", + "ChainPosClassSetCount", + None, + None, + "Number of ChainPosClassSet tables", + ), + ( + "Offset", + "ChainPosClassSet", + "ChainPosClassSetCount", + 0, + "Array of offsets to ChainPosClassSet tables-from beginning of ChainContextPos subtable-ordered by input class-may be NULL", + ), + ], + ), + ( + "ChainPosClassSet", + [ + ( + "uint16", + "ChainPosClassRuleCount", + None, + None, + "Number of ChainPosClassRule tables", + ), + ( + "Offset", + "ChainPosClassRule", + "ChainPosClassRuleCount", + 0, + "Array of offsets to ChainPosClassRule tables-from beginning of ChainPosClassSet-ordered by preference", + ), + ], + ), + ( + "ChainPosClassRule", + [ + ( + "uint16", + "BacktrackGlyphCount", + None, + None, + "Total number of glyphs in the backtrack sequence (number of glyphs to be matched before the first glyph)", + ), + ( + "uint16", + "Backtrack", + "BacktrackGlyphCount", + 0, + "Array of backtracking classes(to be matched before the input sequence)", + ), + ( + "uint16", + "InputGlyphCount", + None, + None, + "Total number of classes in the input sequence (includes the first class)", + ), + ( + "uint16", + "Input", + "InputGlyphCount", + -1, + "Array of input classes(start with second class; to be matched with the input glyph sequence)", + ), + ( + "uint16", + "LookAheadGlyphCount", + None, + None, + "Total number of classes in the look ahead sequence (number of classes to be matched after the input sequence)", + ), + ( + "uint16", + "LookAhead", + "LookAheadGlyphCount", + 0, + "Array of lookahead classes(to be matched after the input sequence)", + ), + ("uint16", "PosCount", None, None, "Number of PosLookupRecords"), + ( + "struct", + "PosLookupRecord", + "PosCount", + 0, + "Array of PosLookupRecords (in design order)", + ), + ], + ), + ( + "ChainContextPosFormat3", + [ + ("uint16", "PosFormat", None, None, "Format identifier-format = 3"), + ( + "uint16", + "BacktrackGlyphCount", + None, + None, + "Number of glyphs in the backtracking sequence", + ), + ( + "Offset", + "BacktrackCoverage", + "BacktrackGlyphCount", + 0, + "Array of offsets to coverage tables in backtracking sequence, in glyph sequence order", + ), + ( + "uint16", + "InputGlyphCount", + None, + None, + "Number of glyphs in input sequence", + ), + ( + "Offset", + "InputCoverage", + "InputGlyphCount", + 0, + "Array of offsets to coverage tables in input sequence, in glyph sequence order", + ), + ( + "uint16", + "LookAheadGlyphCount", + None, + None, + "Number of glyphs in lookahead sequence", + ), + ( + "Offset", + "LookAheadCoverage", + "LookAheadGlyphCount", + 0, + "Array of offsets to coverage tables in lookahead sequence, in glyph sequence order", + ), + ("uint16", "PosCount", None, None, "Number of PosLookupRecords"), + ( + "struct", + "PosLookupRecord", + "PosCount", + 0, + "Array of PosLookupRecords,in design order", + ), + ], + ), + ( + "ExtensionPosFormat1", + [ + ("uint16", "ExtFormat", None, None, "Format identifier. Set to 1."), + ( + "uint16", + "ExtensionLookupType", + None, + None, + "Lookup type of subtable referenced by ExtensionOffset (i.e. the extension subtable).", + ), + ("LOffset", "ExtSubTable", None, None, "Offset to SubTable"), + ], + ), + # ('ValueRecord', [ + # ('int16', 'XPlacement', None, None, 'Horizontal adjustment for placement-in design units'), + # ('int16', 'YPlacement', None, None, 'Vertical adjustment for placement-in design units'), + # ('int16', 'XAdvance', None, None, 'Horizontal adjustment for advance-in design units (only used for horizontal writing)'), + # ('int16', 'YAdvance', None, None, 'Vertical adjustment for advance-in design units (only used for vertical writing)'), + # ('Offset', 'XPlaDevice', None, None, 'Offset to Device table for horizontal placement-measured from beginning of PosTable (may be NULL)'), + # ('Offset', 'YPlaDevice', None, None, 'Offset to Device table for vertical placement-measured from beginning of PosTable (may be NULL)'), + # ('Offset', 'XAdvDevice', None, None, 'Offset to Device table for horizontal advance-measured from beginning of PosTable (may be NULL)'), + # ('Offset', 'YAdvDevice', None, None, 'Offset to Device table for vertical advance-measured from beginning of PosTable (may be NULL)'), + # ]), + ( + "AnchorFormat1", + [ + ("uint16", "AnchorFormat", None, None, "Format identifier-format = 1"), + ("int16", "XCoordinate", None, None, "Horizontal value-in design units"), + ("int16", "YCoordinate", None, None, "Vertical value-in design units"), + ], + ), + ( + "AnchorFormat2", + [ + ("uint16", "AnchorFormat", None, None, "Format identifier-format = 2"), + ("int16", "XCoordinate", None, None, "Horizontal value-in design units"), + ("int16", "YCoordinate", None, None, "Vertical value-in design units"), + ("uint16", "AnchorPoint", None, None, "Index to glyph contour point"), + ], + ), + ( + "AnchorFormat3", + [ + ("uint16", "AnchorFormat", None, None, "Format identifier-format = 3"), + ("int16", "XCoordinate", None, None, "Horizontal value-in design units"), + ("int16", "YCoordinate", None, None, "Vertical value-in design units"), + ( + "Offset", + "XDeviceTable", + None, + None, + "Offset to Device table for X coordinate- from beginning of Anchor table (may be NULL)", + ), + ( + "Offset", + "YDeviceTable", + None, + None, + "Offset to Device table for Y coordinate- from beginning of Anchor table (may be NULL)", + ), + ], + ), + ( + "MarkArray", + [ + ("uint16", "MarkCount", None, None, "Number of MarkRecords"), + ( + "struct", + "MarkRecord", + "MarkCount", + 0, + "Array of MarkRecords-in Coverage order", + ), + ], + ), + ( + "MarkRecord", + [ + ("uint16", "Class", None, None, "Class defined for this mark"), + ( + "Offset", + "MarkAnchor", + None, + None, + "Offset to Anchor table-from beginning of MarkArray table", + ), + ], + ), + # + # gsub + # + ( + "GSUB", + [ + ( + "Version", + "Version", + None, + None, + "Version of the GSUB table- 0x00010000 or 0x00010001", + ), + ( + "Offset", + "ScriptList", + None, + None, + "Offset to ScriptList table-from beginning of GSUB table", + ), + ( + "Offset", + "FeatureList", + None, + None, + "Offset to FeatureList table-from beginning of GSUB table", + ), + ( + "Offset", + "LookupList", + None, + None, + "Offset to LookupList table-from beginning of GSUB table", + ), + ( + "LOffset", + "FeatureVariations", + None, + "Version >= 0x00010001", + "Offset to FeatureVariations table-from beginning of GSUB table", + ), + ], + ), + ( + "SingleSubstFormat1", + [ + ("uint16", "SubstFormat", None, None, "Format identifier-format = 1"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of Substitution table", + ), + ( + "uint16", + "DeltaGlyphID", + None, + None, + "Add to original GlyphID modulo 65536 to get substitute GlyphID", + ), + ], + ), + ( + "SingleSubstFormat2", + [ + ("uint16", "SubstFormat", None, None, "Format identifier-format = 2"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of Substitution table", + ), + ( + "uint16", + "GlyphCount", + None, + None, + "Number of GlyphIDs in the Substitute array", + ), + ( + "GlyphID", + "Substitute", + "GlyphCount", + 0, + "Array of substitute GlyphIDs-ordered by Coverage Index", + ), + ], + ), + ( + "MultipleSubstFormat1", + [ + ("uint16", "SubstFormat", None, None, "Format identifier-format = 1"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of Substitution table", + ), + ( + "uint16", + "SequenceCount", + None, + None, + "Number of Sequence table offsets in the Sequence array", + ), + ( + "Offset", + "Sequence", + "SequenceCount", + 0, + "Array of offsets to Sequence tables-from beginning of Substitution table-ordered by Coverage Index", + ), + ], + ), + ( + "Sequence", + [ + ( + "uint16", + "GlyphCount", + None, + None, + "Number of GlyphIDs in the Substitute array. This should always be greater than 0.", + ), + ( + "GlyphID", + "Substitute", + "GlyphCount", + 0, + "String of GlyphIDs to substitute", + ), + ], + ), + ( + "AlternateSubstFormat1", + [ + ("uint16", "SubstFormat", None, None, "Format identifier-format = 1"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of Substitution table", + ), + ( + "uint16", + "AlternateSetCount", + None, + None, + "Number of AlternateSet tables", + ), + ( + "Offset", + "AlternateSet", + "AlternateSetCount", + 0, + "Array of offsets to AlternateSet tables-from beginning of Substitution table-ordered by Coverage Index", + ), + ], + ), + ( + "AlternateSet", + [ + ( + "uint16", + "GlyphCount", + None, + None, + "Number of GlyphIDs in the Alternate array", + ), + ( + "GlyphID", + "Alternate", + "GlyphCount", + 0, + "Array of alternate GlyphIDs-in arbitrary order", + ), + ], + ), + ( + "LigatureSubstFormat1", + [ + ("uint16", "SubstFormat", None, None, "Format identifier-format = 1"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of Substitution table", + ), + ("uint16", "LigSetCount", None, None, "Number of LigatureSet tables"), + ( + "Offset", + "LigatureSet", + "LigSetCount", + 0, + "Array of offsets to LigatureSet tables-from beginning of Substitution table-ordered by Coverage Index", + ), + ], + ), + ( + "LigatureSet", + [ + ("uint16", "LigatureCount", None, None, "Number of Ligature tables"), + ( + "Offset", + "Ligature", + "LigatureCount", + 0, + "Array of offsets to Ligature tables-from beginning of LigatureSet table-ordered by preference", + ), + ], + ), + ( + "Ligature", + [ + ("GlyphID", "LigGlyph", None, None, "GlyphID of ligature to substitute"), + ("uint16", "CompCount", None, None, "Number of components in the ligature"), + ( + "GlyphID", + "Component", + "CompCount", + -1, + "Array of component GlyphIDs-start with the second component-ordered in writing direction", + ), + ], + ), + ( + "SubstLookupRecord", + [ + ( + "uint16", + "SequenceIndex", + None, + None, + "Index into current glyph sequence-first glyph = 0", + ), + ( + "uint16", + "LookupListIndex", + None, + None, + "Lookup to apply to that position-zero-based", + ), + ], + ), + ( + "ContextSubstFormat1", + [ + ("uint16", "SubstFormat", None, None, "Format identifier-format = 1"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of Substitution table", + ), + ( + "uint16", + "SubRuleSetCount", + None, + None, + "Number of SubRuleSet tables-must equal GlyphCount in Coverage table", + ), + ( + "Offset", + "SubRuleSet", + "SubRuleSetCount", + 0, + "Array of offsets to SubRuleSet tables-from beginning of Substitution table-ordered by Coverage Index", + ), + ], + ), + ( + "SubRuleSet", + [ + ("uint16", "SubRuleCount", None, None, "Number of SubRule tables"), + ( + "Offset", + "SubRule", + "SubRuleCount", + 0, + "Array of offsets to SubRule tables-from beginning of SubRuleSet table-ordered by preference", + ), + ], + ), + ( + "SubRule", + [ + ( + "uint16", + "GlyphCount", + None, + None, + "Total number of glyphs in input glyph sequence-includes the first glyph", + ), + ("uint16", "SubstCount", None, None, "Number of SubstLookupRecords"), + ( + "GlyphID", + "Input", + "GlyphCount", + -1, + "Array of input GlyphIDs-start with second glyph", + ), + ( + "struct", + "SubstLookupRecord", + "SubstCount", + 0, + "Array of SubstLookupRecords-in design order", + ), + ], + ), + ( + "ContextSubstFormat2", + [ + ("uint16", "SubstFormat", None, None, "Format identifier-format = 2"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of Substitution table", + ), + ( + "Offset", + "ClassDef", + None, + None, + "Offset to glyph ClassDef table-from beginning of Substitution table", + ), + ("uint16", "SubClassSetCount", None, None, "Number of SubClassSet tables"), + ( + "Offset", + "SubClassSet", + "SubClassSetCount", + 0, + "Array of offsets to SubClassSet tables-from beginning of Substitution table-ordered by class-may be NULL", + ), + ], + ), + ( + "SubClassSet", + [ + ( + "uint16", + "SubClassRuleCount", + None, + None, + "Number of SubClassRule tables", + ), + ( + "Offset", + "SubClassRule", + "SubClassRuleCount", + 0, + "Array of offsets to SubClassRule tables-from beginning of SubClassSet-ordered by preference", + ), + ], + ), + ( + "SubClassRule", + [ + ( + "uint16", + "GlyphCount", + None, + None, + "Total number of classes specified for the context in the rule-includes the first class", + ), + ("uint16", "SubstCount", None, None, "Number of SubstLookupRecords"), + ( + "uint16", + "Class", + "GlyphCount", + -1, + "Array of classes-beginning with the second class-to be matched to the input glyph class sequence", + ), + ( + "struct", + "SubstLookupRecord", + "SubstCount", + 0, + "Array of Substitution lookups-in design order", + ), + ], + ), + ( + "ContextSubstFormat3", + [ + ("uint16", "SubstFormat", None, None, "Format identifier-format = 3"), + ( + "uint16", + "GlyphCount", + None, + None, + "Number of glyphs in the input glyph sequence", + ), + ("uint16", "SubstCount", None, None, "Number of SubstLookupRecords"), + ( + "Offset", + "Coverage", + "GlyphCount", + 0, + "Array of offsets to Coverage table-from beginning of Substitution table-in glyph sequence order", + ), + ( + "struct", + "SubstLookupRecord", + "SubstCount", + 0, + "Array of SubstLookupRecords-in design order", + ), + ], + ), + ( + "ChainContextSubstFormat1", + [ + ("uint16", "SubstFormat", None, None, "Format identifier-format = 1"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of Substitution table", + ), + ( + "uint16", + "ChainSubRuleSetCount", + None, + None, + "Number of ChainSubRuleSet tables-must equal GlyphCount in Coverage table", + ), + ( + "Offset", + "ChainSubRuleSet", + "ChainSubRuleSetCount", + 0, + "Array of offsets to ChainSubRuleSet tables-from beginning of Substitution table-ordered by Coverage Index", + ), + ], + ), + ( + "ChainSubRuleSet", + [ + ( + "uint16", + "ChainSubRuleCount", + None, + None, + "Number of ChainSubRule tables", + ), + ( + "Offset", + "ChainSubRule", + "ChainSubRuleCount", + 0, + "Array of offsets to ChainSubRule tables-from beginning of ChainSubRuleSet table-ordered by preference", + ), + ], + ), + ( + "ChainSubRule", + [ + ( + "uint16", + "BacktrackGlyphCount", + None, + None, + "Total number of glyphs in the backtrack sequence (number of glyphs to be matched before the first glyph)", + ), + ( + "GlyphID", + "Backtrack", + "BacktrackGlyphCount", + 0, + "Array of backtracking GlyphID's (to be matched before the input sequence)", + ), + ( + "uint16", + "InputGlyphCount", + None, + None, + "Total number of glyphs in the input sequence (includes the first glyph)", + ), + ( + "GlyphID", + "Input", + "InputGlyphCount", + -1, + "Array of input GlyphIDs (start with second glyph)", + ), + ( + "uint16", + "LookAheadGlyphCount", + None, + None, + "Total number of glyphs in the look ahead sequence (number of glyphs to be matched after the input sequence)", + ), + ( + "GlyphID", + "LookAhead", + "LookAheadGlyphCount", + 0, + "Array of lookahead GlyphID's (to be matched after the input sequence)", + ), + ("uint16", "SubstCount", None, None, "Number of SubstLookupRecords"), + ( + "struct", + "SubstLookupRecord", + "SubstCount", + 0, + "Array of SubstLookupRecords (in design order)", + ), + ], + ), + ( + "ChainContextSubstFormat2", + [ + ("uint16", "SubstFormat", None, None, "Format identifier-format = 2"), + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table-from beginning of Substitution table", + ), + ( + "Offset", + "BacktrackClassDef", + None, + None, + "Offset to glyph ClassDef table containing backtrack sequence data-from beginning of Substitution table", + ), + ( + "Offset", + "InputClassDef", + None, + None, + "Offset to glyph ClassDef table containing input sequence data-from beginning of Substitution table", + ), + ( + "Offset", + "LookAheadClassDef", + None, + None, + "Offset to glyph ClassDef table containing lookahead sequence data-from beginning of Substitution table", + ), + ( + "uint16", + "ChainSubClassSetCount", + None, + None, + "Number of ChainSubClassSet tables", + ), + ( + "Offset", + "ChainSubClassSet", + "ChainSubClassSetCount", + 0, + "Array of offsets to ChainSubClassSet tables-from beginning of Substitution table-ordered by input class-may be NULL", + ), + ], + ), + ( + "ChainSubClassSet", + [ + ( + "uint16", + "ChainSubClassRuleCount", + None, + None, + "Number of ChainSubClassRule tables", + ), + ( + "Offset", + "ChainSubClassRule", + "ChainSubClassRuleCount", + 0, + "Array of offsets to ChainSubClassRule tables-from beginning of ChainSubClassSet-ordered by preference", + ), + ], + ), + ( + "ChainSubClassRule", + [ + ( + "uint16", + "BacktrackGlyphCount", + None, + None, + "Total number of glyphs in the backtrack sequence (number of glyphs to be matched before the first glyph)", + ), + ( + "uint16", + "Backtrack", + "BacktrackGlyphCount", + 0, + "Array of backtracking classes(to be matched before the input sequence)", + ), + ( + "uint16", + "InputGlyphCount", + None, + None, + "Total number of classes in the input sequence (includes the first class)", + ), + ( + "uint16", + "Input", + "InputGlyphCount", + -1, + "Array of input classes(start with second class; to be matched with the input glyph sequence)", + ), + ( + "uint16", + "LookAheadGlyphCount", + None, + None, + "Total number of classes in the look ahead sequence (number of classes to be matched after the input sequence)", + ), + ( + "uint16", + "LookAhead", + "LookAheadGlyphCount", + 0, + "Array of lookahead classes(to be matched after the input sequence)", + ), + ("uint16", "SubstCount", None, None, "Number of SubstLookupRecords"), + ( + "struct", + "SubstLookupRecord", + "SubstCount", + 0, + "Array of SubstLookupRecords (in design order)", + ), + ], + ), + ( + "ChainContextSubstFormat3", + [ + ("uint16", "SubstFormat", None, None, "Format identifier-format = 3"), + ( + "uint16", + "BacktrackGlyphCount", + None, + None, + "Number of glyphs in the backtracking sequence", + ), + ( + "Offset", + "BacktrackCoverage", + "BacktrackGlyphCount", + 0, + "Array of offsets to coverage tables in backtracking sequence, in glyph sequence order", + ), + ( + "uint16", + "InputGlyphCount", + None, + None, + "Number of glyphs in input sequence", + ), + ( + "Offset", + "InputCoverage", + "InputGlyphCount", + 0, + "Array of offsets to coverage tables in input sequence, in glyph sequence order", + ), + ( + "uint16", + "LookAheadGlyphCount", + None, + None, + "Number of glyphs in lookahead sequence", + ), + ( + "Offset", + "LookAheadCoverage", + "LookAheadGlyphCount", + 0, + "Array of offsets to coverage tables in lookahead sequence, in glyph sequence order", + ), + ("uint16", "SubstCount", None, None, "Number of SubstLookupRecords"), + ( + "struct", + "SubstLookupRecord", + "SubstCount", + 0, + "Array of SubstLookupRecords, in design order", + ), + ], + ), + ( + "ExtensionSubstFormat1", + [ + ("uint16", "ExtFormat", None, None, "Format identifier. Set to 1."), + ( + "uint16", + "ExtensionLookupType", + None, + None, + "Lookup type of subtable referenced by ExtensionOffset (i.e. the extension subtable).", + ), + ( + "LOffset", + "ExtSubTable", + None, + None, + "Array of offsets to Lookup tables-from beginning of LookupList -zero based (first lookup is Lookup index = 0)", + ), + ], + ), + ( + "ReverseChainSingleSubstFormat1", + [ + ("uint16", "SubstFormat", None, None, "Format identifier-format = 1"), + ( + "Offset", + "Coverage", + None, + 0, + "Offset to Coverage table - from beginning of Substitution table", + ), + ( + "uint16", + "BacktrackGlyphCount", + None, + None, + "Number of glyphs in the backtracking sequence", + ), + ( + "Offset", + "BacktrackCoverage", + "BacktrackGlyphCount", + 0, + "Array of offsets to coverage tables in backtracking sequence, in glyph sequence order", + ), + ( + "uint16", + "LookAheadGlyphCount", + None, + None, + "Number of glyphs in lookahead sequence", + ), + ( + "Offset", + "LookAheadCoverage", + "LookAheadGlyphCount", + 0, + "Array of offsets to coverage tables in lookahead sequence, in glyph sequence order", + ), + ( + "uint16", + "GlyphCount", + None, + None, + "Number of GlyphIDs in the Substitute array", + ), + ( + "GlyphID", + "Substitute", + "GlyphCount", + 0, + "Array of substitute GlyphIDs-ordered by Coverage index", + ), + ], + ), + # + # gdef + # + ( + "GDEF", + [ + ( + "Version", + "Version", + None, + None, + "Version of the GDEF table- 0x00010000, 0x00010002, or 0x00010003", + ), + ( + "Offset", + "GlyphClassDef", + None, + None, + "Offset to class definition table for glyph type-from beginning of GDEF header (may be NULL)", + ), + ( + "Offset", + "AttachList", + None, + None, + "Offset to list of glyphs with attachment points-from beginning of GDEF header (may be NULL)", + ), + ( + "Offset", + "LigCaretList", + None, + None, + "Offset to list of positioning points for ligature carets-from beginning of GDEF header (may be NULL)", + ), + ( + "Offset", + "MarkAttachClassDef", + None, + None, + "Offset to class definition table for mark attachment type-from beginning of GDEF header (may be NULL)", + ), + ( + "Offset", + "MarkGlyphSetsDef", + None, + "Version >= 0x00010002", + "Offset to the table of mark set definitions-from beginning of GDEF header (may be NULL)", + ), + ( + "LOffset", + "VarStore", + None, + "Version >= 0x00010003", + "Offset to variation store (may be NULL)", + ), + ], + ), + ( + "AttachList", + [ + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table - from beginning of AttachList table", + ), + ( + "uint16", + "GlyphCount", + None, + None, + "Number of glyphs with attachment points", + ), + ( + "Offset", + "AttachPoint", + "GlyphCount", + 0, + "Array of offsets to AttachPoint tables-from beginning of AttachList table-in Coverage Index order", + ), + ], + ), + ( + "AttachPoint", + [ + ( + "uint16", + "PointCount", + None, + None, + "Number of attachment points on this glyph", + ), + ( + "uint16", + "PointIndex", + "PointCount", + 0, + "Array of contour point indices -in increasing numerical order", + ), + ], + ), + ( + "LigCaretList", + [ + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table - from beginning of LigCaretList table", + ), + ("uint16", "LigGlyphCount", None, None, "Number of ligature glyphs"), + ( + "Offset", + "LigGlyph", + "LigGlyphCount", + 0, + "Array of offsets to LigGlyph tables-from beginning of LigCaretList table-in Coverage Index order", + ), + ], + ), + ( + "LigGlyph", + [ + ( + "uint16", + "CaretCount", + None, + None, + "Number of CaretValues for this ligature (components - 1)", + ), + ( + "Offset", + "CaretValue", + "CaretCount", + 0, + "Array of offsets to CaretValue tables-from beginning of LigGlyph table-in increasing coordinate order", + ), + ], + ), + ( + "CaretValueFormat1", + [ + ("uint16", "CaretValueFormat", None, None, "Format identifier-format = 1"), + ("int16", "Coordinate", None, None, "X or Y value, in design units"), + ], + ), + ( + "CaretValueFormat2", + [ + ("uint16", "CaretValueFormat", None, None, "Format identifier-format = 2"), + ("uint16", "CaretValuePoint", None, None, "Contour point index on glyph"), + ], + ), + ( + "CaretValueFormat3", + [ + ("uint16", "CaretValueFormat", None, None, "Format identifier-format = 3"), + ("int16", "Coordinate", None, None, "X or Y value, in design units"), + ( + "Offset", + "DeviceTable", + None, + None, + "Offset to Device table for X or Y value-from beginning of CaretValue table", + ), + ], + ), + ( + "MarkGlyphSetsDef", + [ + ("uint16", "MarkSetTableFormat", None, None, "Format identifier == 1"), + ("uint16", "MarkSetCount", None, None, "Number of mark sets defined"), + ( + "LOffset", + "Coverage", + "MarkSetCount", + 0, + "Array of offsets to mark set coverage tables.", + ), + ], + ), + # + # base + # + ( + "BASE", + [ + ( + "Version", + "Version", + None, + None, + "Version of the BASE table-initially 0x00010000", + ), + ( + "Offset", + "HorizAxis", + None, + None, + "Offset to horizontal Axis table-from beginning of BASE table-may be NULL", + ), + ( + "Offset", + "VertAxis", + None, + None, + "Offset to vertical Axis table-from beginning of BASE table-may be NULL", + ), + ( + "LOffset", + "VarStore", + None, + "Version >= 0x00010001", + "Offset to variation store (may be NULL)", + ), + ], + ), + ( + "Axis", + [ + ( + "Offset", + "BaseTagList", + None, + None, + "Offset to BaseTagList table-from beginning of Axis table-may be NULL", + ), + ( + "Offset", + "BaseScriptList", + None, + None, + "Offset to BaseScriptList table-from beginning of Axis table", + ), + ], + ), + ( + "BaseTagList", + [ + ( + "uint16", + "BaseTagCount", + None, + None, + "Number of baseline identification tags in this text direction-may be zero (0)", + ), + ( + "Tag", + "BaselineTag", + "BaseTagCount", + 0, + "Array of 4-byte baseline identification tags-must be in alphabetical order", + ), + ], + ), + ( + "BaseScriptList", + [ + ( + "uint16", + "BaseScriptCount", + None, + None, + "Number of BaseScriptRecords defined", + ), + ( + "struct", + "BaseScriptRecord", + "BaseScriptCount", + 0, + "Array of BaseScriptRecords-in alphabetical order by BaseScriptTag", + ), + ], + ), + ( + "BaseScriptRecord", + [ + ("Tag", "BaseScriptTag", None, None, "4-byte script identification tag"), + ( + "Offset", + "BaseScript", + None, + None, + "Offset to BaseScript table-from beginning of BaseScriptList", + ), + ], + ), + ( + "BaseScript", + [ + ( + "Offset", + "BaseValues", + None, + None, + "Offset to BaseValues table-from beginning of BaseScript table-may be NULL", + ), + ( + "Offset", + "DefaultMinMax", + None, + None, + "Offset to MinMax table- from beginning of BaseScript table-may be NULL", + ), + ( + "uint16", + "BaseLangSysCount", + None, + None, + "Number of BaseLangSysRecords defined-may be zero (0)", + ), + ( + "struct", + "BaseLangSysRecord", + "BaseLangSysCount", + 0, + "Array of BaseLangSysRecords-in alphabetical order by BaseLangSysTag", + ), + ], + ), + ( + "BaseLangSysRecord", + [ + ( + "Tag", + "BaseLangSysTag", + None, + None, + "4-byte language system identification tag", + ), + ( + "Offset", + "MinMax", + None, + None, + "Offset to MinMax table-from beginning of BaseScript table", + ), + ], + ), + ( + "BaseValues", + [ + ( + "uint16", + "DefaultIndex", + None, + None, + "Index number of default baseline for this script-equals index position of baseline tag in BaselineArray of the BaseTagList", + ), + ( + "uint16", + "BaseCoordCount", + None, + None, + "Number of BaseCoord tables defined-should equal BaseTagCount in the BaseTagList", + ), + ( + "Offset", + "BaseCoord", + "BaseCoordCount", + 0, + "Array of offsets to BaseCoord-from beginning of BaseValues table-order matches BaselineTag array in the BaseTagList", + ), + ], + ), + ( + "MinMax", + [ + ( + "Offset", + "MinCoord", + None, + None, + "Offset to BaseCoord table-defines minimum extent value-from the beginning of MinMax table-may be NULL", + ), + ( + "Offset", + "MaxCoord", + None, + None, + "Offset to BaseCoord table-defines maximum extent value-from the beginning of MinMax table-may be NULL", + ), + ( + "uint16", + "FeatMinMaxCount", + None, + None, + "Number of FeatMinMaxRecords-may be zero (0)", + ), + ( + "struct", + "FeatMinMaxRecord", + "FeatMinMaxCount", + 0, + "Array of FeatMinMaxRecords-in alphabetical order, by FeatureTableTag", + ), + ], + ), + ( + "FeatMinMaxRecord", + [ + ( + "Tag", + "FeatureTableTag", + None, + None, + "4-byte feature identification tag-must match FeatureTag in FeatureList", + ), + ( + "Offset", + "MinCoord", + None, + None, + "Offset to BaseCoord table-defines minimum extent value-from beginning of MinMax table-may be NULL", + ), + ( + "Offset", + "MaxCoord", + None, + None, + "Offset to BaseCoord table-defines maximum extent value-from beginning of MinMax table-may be NULL", + ), + ], + ), + ( + "BaseCoordFormat1", + [ + ("uint16", "BaseCoordFormat", None, None, "Format identifier-format = 1"), + ("int16", "Coordinate", None, None, "X or Y value, in design units"), + ], + ), + ( + "BaseCoordFormat2", + [ + ("uint16", "BaseCoordFormat", None, None, "Format identifier-format = 2"), + ("int16", "Coordinate", None, None, "X or Y value, in design units"), + ("GlyphID", "ReferenceGlyph", None, None, "GlyphID of control glyph"), + ( + "uint16", + "BaseCoordPoint", + None, + None, + "Index of contour point on the ReferenceGlyph", + ), + ], + ), + ( + "BaseCoordFormat3", + [ + ("uint16", "BaseCoordFormat", None, None, "Format identifier-format = 3"), + ("int16", "Coordinate", None, None, "X or Y value, in design units"), + ( + "Offset", + "DeviceTable", + None, + None, + "Offset to Device table for X or Y value", + ), + ], + ), + # + # jstf + # + ( + "JSTF", + [ + ( + "Version", + "Version", + None, + None, + "Version of the JSTF table-initially set to 0x00010000", + ), + ( + "uint16", + "JstfScriptCount", + None, + None, + "Number of JstfScriptRecords in this table", + ), + ( + "struct", + "JstfScriptRecord", + "JstfScriptCount", + 0, + "Array of JstfScriptRecords-in alphabetical order, by JstfScriptTag", + ), + ], + ), + ( + "JstfScriptRecord", + [ + ("Tag", "JstfScriptTag", None, None, "4-byte JstfScript identification"), + ( + "Offset", + "JstfScript", + None, + None, + "Offset to JstfScript table-from beginning of JSTF Header", + ), + ], + ), + ( + "JstfScript", + [ + ( + "Offset", + "ExtenderGlyph", + None, + None, + "Offset to ExtenderGlyph table-from beginning of JstfScript table-may be NULL", + ), + ( + "Offset", + "DefJstfLangSys", + None, + None, + "Offset to Default JstfLangSys table-from beginning of JstfScript table-may be NULL", + ), + ( + "uint16", + "JstfLangSysCount", + None, + None, + "Number of JstfLangSysRecords in this table- may be zero (0)", + ), + ( + "struct", + "JstfLangSysRecord", + "JstfLangSysCount", + 0, + "Array of JstfLangSysRecords-in alphabetical order, by JstfLangSysTag", + ), + ], + ), + ( + "JstfLangSysRecord", + [ + ("Tag", "JstfLangSysTag", None, None, "4-byte JstfLangSys identifier"), + ( + "Offset", + "JstfLangSys", + None, + None, + "Offset to JstfLangSys table-from beginning of JstfScript table", + ), + ], + ), + ( + "ExtenderGlyph", + [ + ( + "uint16", + "GlyphCount", + None, + None, + "Number of Extender Glyphs in this script", + ), + ( + "GlyphID", + "ExtenderGlyph", + "GlyphCount", + 0, + "GlyphIDs-in increasing numerical order", + ), + ], + ), + ( + "JstfLangSys", + [ + ( + "uint16", + "JstfPriorityCount", + None, + None, + "Number of JstfPriority tables", + ), + ( + "Offset", + "JstfPriority", + "JstfPriorityCount", + 0, + "Array of offsets to JstfPriority tables-from beginning of JstfLangSys table-in priority order", + ), + ], + ), + ( + "JstfPriority", + [ + ( + "Offset", + "ShrinkageEnableGSUB", + None, + None, + "Offset to Shrinkage Enable JstfGSUBModList table-from beginning of JstfPriority table-may be NULL", + ), + ( + "Offset", + "ShrinkageDisableGSUB", + None, + None, + "Offset to Shrinkage Disable JstfGSUBModList table-from beginning of JstfPriority table-may be NULL", + ), + ( + "Offset", + "ShrinkageEnableGPOS", + None, + None, + "Offset to Shrinkage Enable JstfGPOSModList table-from beginning of JstfPriority table-may be NULL", + ), + ( + "Offset", + "ShrinkageDisableGPOS", + None, + None, + "Offset to Shrinkage Disable JstfGPOSModList table-from beginning of JstfPriority table-may be NULL", + ), + ( + "Offset", + "ShrinkageJstfMax", + None, + None, + "Offset to Shrinkage JstfMax table-from beginning of JstfPriority table -may be NULL", + ), + ( + "Offset", + "ExtensionEnableGSUB", + None, + None, + "Offset to Extension Enable JstfGSUBModList table-may be NULL", + ), + ( + "Offset", + "ExtensionDisableGSUB", + None, + None, + "Offset to Extension Disable JstfGSUBModList table-from beginning of JstfPriority table-may be NULL", + ), + ( + "Offset", + "ExtensionEnableGPOS", + None, + None, + "Offset to Extension Enable JstfGSUBModList table-may be NULL", + ), + ( + "Offset", + "ExtensionDisableGPOS", + None, + None, + "Offset to Extension Disable JstfGSUBModList table-from beginning of JstfPriority table-may be NULL", + ), + ( + "Offset", + "ExtensionJstfMax", + None, + None, + "Offset to Extension JstfMax table-from beginning of JstfPriority table -may be NULL", + ), + ], + ), + ( + "JstfGSUBModList", + [ + ( + "uint16", + "LookupCount", + None, + None, + "Number of lookups for this modification", + ), + ( + "uint16", + "GSUBLookupIndex", + "LookupCount", + 0, + "Array of LookupIndex identifiers in GSUB-in increasing numerical order", + ), + ], + ), + ( + "JstfGPOSModList", + [ + ( + "uint16", + "LookupCount", + None, + None, + "Number of lookups for this modification", + ), + ( + "uint16", + "GPOSLookupIndex", + "LookupCount", + 0, + "Array of LookupIndex identifiers in GPOS-in increasing numerical order", + ), + ], + ), + ( + "JstfMax", + [ + ( + "uint16", + "LookupCount", + None, + None, + "Number of lookup Indices for this modification", + ), + ( + "Offset", + "Lookup", + "LookupCount", + 0, + "Array of offsets to GPOS-type lookup tables-from beginning of JstfMax table-in design order", + ), + ], + ), + # + # STAT + # + ( + "STAT", + [ + ( + "Version", + "Version", + None, + None, + "Version of the table-initially set to 0x00010000, currently 0x00010002.", + ), + ( + "uint16", + "DesignAxisRecordSize", + None, + None, + "Size in bytes of each design axis record", + ), + ("uint16", "DesignAxisCount", None, None, "Number of design axis records"), + ( + "LOffsetTo(AxisRecordArray)", + "DesignAxisRecord", + None, + None, + "Offset in bytes from the beginning of the STAT table to the start of the design axes array", + ), + ("uint16", "AxisValueCount", None, None, "Number of axis value tables"), + ( + "LOffsetTo(AxisValueArray)", + "AxisValueArray", + None, + None, + "Offset in bytes from the beginning of the STAT table to the start of the axes value offset array", + ), + ( + "NameID", + "ElidedFallbackNameID", + None, + "Version >= 0x00010001", + "NameID to use when all style attributes are elided.", + ), + ], + ), + ( + "AxisRecordArray", + [ + ("AxisRecord", "Axis", "DesignAxisCount", 0, "Axis records"), + ], + ), + ( + "AxisRecord", + [ + ( + "Tag", + "AxisTag", + None, + None, + "A tag identifying the axis of design variation", + ), + ( + "NameID", + "AxisNameID", + None, + None, + 'The name ID for entries in the "name" table that provide a display string for this axis', + ), + ( + "uint16", + "AxisOrdering", + None, + None, + "A value that applications can use to determine primary sorting of face names, or for ordering of descriptors when composing family or face names", + ), + ( + "uint8", + "MoreBytes", + "DesignAxisRecordSize", + -8, + "Extra bytes. Set to empty array.", + ), + ], + ), + ( + "AxisValueArray", + [ + ("Offset", "AxisValue", "AxisValueCount", 0, "Axis values"), + ], + ), + ( + "AxisValueFormat1", + [ + ("uint16", "Format", None, None, "Format, = 1"), + ( + "uint16", + "AxisIndex", + None, + None, + "Index into the axis record array identifying the axis of design variation to which the axis value record applies.", + ), + ("STATFlags", "Flags", None, None, "Flags."), + ("NameID", "ValueNameID", None, None, ""), + ("Fixed", "Value", None, None, ""), + ], + ), + ( + "AxisValueFormat2", + [ + ("uint16", "Format", None, None, "Format, = 2"), + ( + "uint16", + "AxisIndex", + None, + None, + "Index into the axis record array identifying the axis of design variation to which the axis value record applies.", + ), + ("STATFlags", "Flags", None, None, "Flags."), + ("NameID", "ValueNameID", None, None, ""), + ("Fixed", "NominalValue", None, None, ""), + ("Fixed", "RangeMinValue", None, None, ""), + ("Fixed", "RangeMaxValue", None, None, ""), + ], + ), + ( + "AxisValueFormat3", + [ + ("uint16", "Format", None, None, "Format, = 3"), + ( + "uint16", + "AxisIndex", + None, + None, + "Index into the axis record array identifying the axis of design variation to which the axis value record applies.", + ), + ("STATFlags", "Flags", None, None, "Flags."), + ("NameID", "ValueNameID", None, None, ""), + ("Fixed", "Value", None, None, ""), + ("Fixed", "LinkedValue", None, None, ""), + ], + ), + ( + "AxisValueFormat4", + [ + ("uint16", "Format", None, None, "Format, = 4"), + ( + "uint16", + "AxisCount", + None, + None, + "The total number of axes contributing to this axis-values combination.", + ), + ("STATFlags", "Flags", None, None, "Flags."), + ("NameID", "ValueNameID", None, None, ""), + ( + "struct", + "AxisValueRecord", + "AxisCount", + 0, + "Array of AxisValue records that provide the combination of axis values, one for each contributing axis. ", + ), + ], + ), + ( + "AxisValueRecord", + [ + ( + "uint16", + "AxisIndex", + None, + None, + "Index into the axis record array identifying the axis of design variation to which the axis value record applies.", + ), + ("Fixed", "Value", None, None, "A numeric value for this attribute value."), + ], + ), + # + # Variation fonts + # + # GSUB/GPOS FeatureVariations + ( + "FeatureVariations", + [ + ( + "Version", + "Version", + None, + None, + "Version of the table-initially set to 0x00010000", + ), + ( + "uint32", + "FeatureVariationCount", + None, + None, + "Number of records in the FeatureVariationRecord array", + ), + ( + "struct", + "FeatureVariationRecord", + "FeatureVariationCount", + 0, + "Array of FeatureVariationRecord", + ), + ], + ), + ( + "FeatureVariationRecord", + [ + ( + "LOffset", + "ConditionSet", + None, + None, + "Offset to a ConditionSet table, from beginning of the FeatureVariations table.", + ), + ( + "LOffset", + "FeatureTableSubstitution", + None, + None, + "Offset to a FeatureTableSubstitution table, from beginning of the FeatureVariations table", + ), + ], + ), + ( + "ConditionList", + [ + ( + "uint32", + "ConditionCount", + None, + None, + "Number of condition tables in the ConditionTable array", + ), + ( + "LOffset", + "ConditionTable", + "ConditionCount", + 0, + "Array of offset to condition tables, from the beginning of the ConditionList table.", + ), + ], + ), + ( + "ConditionSet", + [ + ( + "uint16", + "ConditionCount", + None, + None, + "Number of condition tables in the ConditionTable array", + ), + ( + "LOffset", + "ConditionTable", + "ConditionCount", + 0, + "Array of offset to condition tables, from the beginning of the ConditionSet table.", + ), + ], + ), + ( + "ConditionTableFormat1", + [ + ("uint16", "Format", None, None, "Format, = 1"), + ( + "uint16", + "AxisIndex", + None, + None, + "Index for the variation axis within the fvar table, base 0.", + ), + ( + "F2Dot14", + "FilterRangeMinValue", + None, + None, + "Minimum normalized axis value of the font variation instances that satisfy this condition.", + ), + ( + "F2Dot14", + "FilterRangeMaxValue", + None, + None, + "Maximum value that satisfies this condition.", + ), + ], + ), + ( + "ConditionTableFormat2", + [ + ("uint16", "Format", None, None, "Format, = 2"), + ( + "int16", + "DefaultValue", + None, + None, + "Value at default instance.", + ), + ( + "uint32", + "VarIdx", + None, + None, + "Variation index to vary the value based on current designspace location.", + ), + ], + ), + ( + "ConditionTableFormat3", + [ + ("uint16", "Format", None, None, "Format, = 3"), + ( + "uint8", + "ConditionCount", + None, + None, + "Index for the variation axis within the fvar table, base 0.", + ), + ( + "Offset24", + "ConditionTable", + "ConditionCount", + 0, + "Array of condition tables for this conjunction (AND) expression.", + ), + ], + ), + ( + "ConditionTableFormat4", + [ + ("uint16", "Format", None, None, "Format, = 4"), + ( + "uint8", + "ConditionCount", + None, + None, + "Index for the variation axis within the fvar table, base 0.", + ), + ( + "Offset24", + "ConditionTable", + "ConditionCount", + 0, + "Array of condition tables for this disjunction (OR) expression.", + ), + ], + ), + ( + "ConditionTableFormat5", + [ + ("uint16", "Format", None, None, "Format, = 5"), + ( + "Offset24", + "ConditionTable", + None, + None, + "Condition to negate.", + ), + ], + ), + ( + "FeatureTableSubstitution", + [ + ( + "Version", + "Version", + None, + None, + "Version of the table-initially set to 0x00010000", + ), + ( + "uint16", + "SubstitutionCount", + None, + None, + "Number of records in the FeatureVariationRecords array", + ), + ( + "FeatureTableSubstitutionRecord", + "SubstitutionRecord", + "SubstitutionCount", + 0, + "Array of FeatureTableSubstitutionRecord", + ), + ], + ), + ( + "FeatureTableSubstitutionRecord", + [ + ("uint16", "FeatureIndex", None, None, "The feature table index to match."), + ( + "LOffset", + "Feature", + None, + None, + "Offset to an alternate feature table, from start of the FeatureTableSubstitution table.", + ), + ], + ), + # VariationStore + ( + "VarRegionAxis", + [ + ("F2Dot14", "StartCoord", None, None, ""), + ("F2Dot14", "PeakCoord", None, None, ""), + ("F2Dot14", "EndCoord", None, None, ""), + ], + ), + ( + "VarRegion", + [ + ("struct", "VarRegionAxis", "RegionAxisCount", 0, ""), + ], + ), + ( + "VarRegionList", + [ + ("uint16", "RegionAxisCount", None, None, ""), + ("uint16", "RegionCount", None, None, ""), + ("VarRegion", "Region", "RegionCount", 0, ""), + ], + ), + ( + "VarData", + [ + ("uint16", "ItemCount", None, None, ""), + ("uint16", "NumShorts", None, None, ""), + ("uint16", "VarRegionCount", None, None, ""), + ("uint16", "VarRegionIndex", "VarRegionCount", 0, ""), + ("VarDataValue", "Item", "ItemCount", 0, ""), + ], + ), + ( + "VarStore", + [ + ("uint16", "Format", None, None, "Set to 1."), + ("LOffset", "VarRegionList", None, None, ""), + ("uint16", "VarDataCount", None, None, ""), + ("LOffset", "VarData", "VarDataCount", 0, ""), + ], + ), + # Variation helpers + ( + "VarIdxMap", + [ + ("uint16", "EntryFormat", None, None, ""), # Automatically computed + ("uint16", "MappingCount", None, None, ""), # Automatically computed + ("VarIdxMapValue", "mapping", "", 0, "Array of compressed data"), + ], + ), + ( + "DeltaSetIndexMapFormat0", + [ + ("uint8", "Format", None, None, "Format of the DeltaSetIndexMap = 0"), + ("uint8", "EntryFormat", None, None, ""), # Automatically computed + ("uint16", "MappingCount", None, None, ""), # Automatically computed + ("VarIdxMapValue", "mapping", "", 0, "Array of compressed data"), + ], + ), + ( + "DeltaSetIndexMapFormat1", + [ + ("uint8", "Format", None, None, "Format of the DeltaSetIndexMap = 1"), + ("uint8", "EntryFormat", None, None, ""), # Automatically computed + ("uint32", "MappingCount", None, None, ""), # Automatically computed + ("VarIdxMapValue", "mapping", "", 0, "Array of compressed data"), + ], + ), + # MultiVariationStore + ( + "SparseVarRegionAxis", + [ + ("uint16", "AxisIndex", None, None, ""), + ("F2Dot14", "StartCoord", None, None, ""), + ("F2Dot14", "PeakCoord", None, None, ""), + ("F2Dot14", "EndCoord", None, None, ""), + ], + ), + ( + "SparseVarRegion", + [ + ("uint16", "SparseRegionCount", None, None, ""), + ("struct", "SparseVarRegionAxis", "SparseRegionCount", 0, ""), + ], + ), + ( + "SparseVarRegionList", + [ + ("uint16", "RegionCount", None, None, ""), + ("LOffsetTo(SparseVarRegion)", "Region", "RegionCount", 0, ""), + ], + ), + ( + "MultiVarData", + [ + ("uint8", "Format", None, None, "Set to 1."), + ("uint16", "VarRegionCount", None, None, ""), + ("uint16", "VarRegionIndex", "VarRegionCount", 0, ""), + ("TupleList", "Item", "", 0, ""), + ], + ), + ( + "MultiVarStore", + [ + ("uint16", "Format", None, None, "Set to 1."), + ("LOffset", "SparseVarRegionList", None, None, ""), + ("uint16", "MultiVarDataCount", None, None, ""), + ("LOffset", "MultiVarData", "MultiVarDataCount", 0, ""), + ], + ), + # VariableComposites + ( + "VARC", + [ + ( + "Version", + "Version", + None, + None, + "Version of the HVAR table-initially = 0x00010000", + ), + ("LOffset", "Coverage", None, None, ""), + ("LOffset", "MultiVarStore", None, None, "(may be NULL)"), + ("LOffset", "ConditionList", None, None, "(may be NULL)"), + ("LOffset", "AxisIndicesList", None, None, "(may be NULL)"), + ("LOffset", "VarCompositeGlyphs", None, None, ""), + ], + ), + ( + "AxisIndicesList", + [ + ("TupleList", "Item", "", 0, ""), + ], + ), + ( + "VarCompositeGlyphs", + [ + ("VarCompositeGlyphList", "VarCompositeGlyph", "", None, ""), + ], + ), + # Glyph advance variations + ( + "HVAR", + [ + ( + "Version", + "Version", + None, + None, + "Version of the HVAR table-initially = 0x00010000", + ), + ("LOffset", "VarStore", None, None, ""), + ("LOffsetTo(VarIdxMap)", "AdvWidthMap", None, None, ""), + ("LOffsetTo(VarIdxMap)", "LsbMap", None, None, ""), + ("LOffsetTo(VarIdxMap)", "RsbMap", None, None, ""), + ], + ), + ( + "VVAR", + [ + ( + "Version", + "Version", + None, + None, + "Version of the VVAR table-initially = 0x00010000", + ), + ("LOffset", "VarStore", None, None, ""), + ("LOffsetTo(VarIdxMap)", "AdvHeightMap", None, None, ""), + ("LOffsetTo(VarIdxMap)", "TsbMap", None, None, ""), + ("LOffsetTo(VarIdxMap)", "BsbMap", None, None, ""), + ("LOffsetTo(VarIdxMap)", "VOrgMap", None, None, "Vertical origin mapping."), + ], + ), + # Font-wide metrics variations + ( + "MetricsValueRecord", + [ + ("Tag", "ValueTag", None, None, "4-byte font-wide measure identifier"), + ("uint32", "VarIdx", None, None, "Combined outer-inner variation index"), + ( + "uint8", + "MoreBytes", + "ValueRecordSize", + -8, + "Extra bytes. Set to empty array.", + ), + ], + ), + ( + "MVAR", + [ + ( + "Version", + "Version", + None, + None, + "Version of the MVAR table-initially = 0x00010000", + ), + ("uint16", "Reserved", None, None, "Set to 0"), + ("uint16", "ValueRecordSize", None, None, ""), + ("uint16", "ValueRecordCount", None, None, ""), + ("Offset", "VarStore", None, None, ""), + ("MetricsValueRecord", "ValueRecord", "ValueRecordCount", 0, ""), + ], + ), + # + # math + # + ( + "MATH", + [ + ( + "Version", + "Version", + None, + None, + "Version of the MATH table-initially set to 0x00010000.", + ), + ( + "Offset", + "MathConstants", + None, + None, + "Offset to MathConstants table - from the beginning of MATH table.", + ), + ( + "Offset", + "MathGlyphInfo", + None, + None, + "Offset to MathGlyphInfo table - from the beginning of MATH table.", + ), + ( + "Offset", + "MathVariants", + None, + None, + "Offset to MathVariants table - from the beginning of MATH table.", + ), + ], + ), + ( + "MathValueRecord", + [ + ("int16", "Value", None, None, "The X or Y value in design units."), + ( + "Offset", + "DeviceTable", + None, + None, + "Offset to the device table - from the beginning of parent table. May be NULL. Suggested format for device table is 1.", + ), + ], + ), + ( + "MathConstants", + [ + ( + "int16", + "ScriptPercentScaleDown", + None, + None, + "Percentage of scaling down for script level 1. Suggested value: 80%.", + ), + ( + "int16", + "ScriptScriptPercentScaleDown", + None, + None, + "Percentage of scaling down for script level 2 (ScriptScript). Suggested value: 60%.", + ), + ( + "uint16", + "DelimitedSubFormulaMinHeight", + None, + None, + "Minimum height required for a delimited expression to be treated as a subformula. Suggested value: normal line height x1.5.", + ), + ( + "uint16", + "DisplayOperatorMinHeight", + None, + None, + "Minimum height of n-ary operators (such as integral and summation) for formulas in display mode.", + ), + ( + "MathValueRecord", + "MathLeading", + None, + None, + "White space to be left between math formulas to ensure proper line spacing. For example, for applications that treat line gap as a part of line ascender, formulas with ink going above (os2.sTypoAscender + os2.sTypoLineGap - MathLeading) or with ink going below os2.sTypoDescender will result in increasing line height.", + ), + ("MathValueRecord", "AxisHeight", None, None, "Axis height of the font."), + ( + "MathValueRecord", + "AccentBaseHeight", + None, + None, + "Maximum (ink) height of accent base that does not require raising the accents. Suggested: x-height of the font (os2.sxHeight) plus any possible overshots.", + ), + ( + "MathValueRecord", + "FlattenedAccentBaseHeight", + None, + None, + "Maximum (ink) height of accent base that does not require flattening the accents. Suggested: cap height of the font (os2.sCapHeight).", + ), + ( + "MathValueRecord", + "SubscriptShiftDown", + None, + None, + "The standard shift down applied to subscript elements. Positive for moving in the downward direction. Suggested: os2.ySubscriptYOffset.", + ), + ( + "MathValueRecord", + "SubscriptTopMax", + None, + None, + "Maximum allowed height of the (ink) top of subscripts that does not require moving subscripts further down. Suggested: 4/5 x-height.", + ), + ( + "MathValueRecord", + "SubscriptBaselineDropMin", + None, + None, + "Minimum allowed drop of the baseline of subscripts relative to the (ink) bottom of the base. Checked for bases that are treated as a box or extended shape. Positive for subscript baseline dropped below the base bottom.", + ), + ( + "MathValueRecord", + "SuperscriptShiftUp", + None, + None, + "Standard shift up applied to superscript elements. Suggested: os2.ySuperscriptYOffset.", + ), + ( + "MathValueRecord", + "SuperscriptShiftUpCramped", + None, + None, + "Standard shift of superscripts relative to the base, in cramped style.", + ), + ( + "MathValueRecord", + "SuperscriptBottomMin", + None, + None, + "Minimum allowed height of the (ink) bottom of superscripts that does not require moving subscripts further up. Suggested: 1/4 x-height.", + ), + ( + "MathValueRecord", + "SuperscriptBaselineDropMax", + None, + None, + "Maximum allowed drop of the baseline of superscripts relative to the (ink) top of the base. Checked for bases that are treated as a box or extended shape. Positive for superscript baseline below the base top.", + ), + ( + "MathValueRecord", + "SubSuperscriptGapMin", + None, + None, + "Minimum gap between the superscript and subscript ink. Suggested: 4x default rule thickness.", + ), + ( + "MathValueRecord", + "SuperscriptBottomMaxWithSubscript", + None, + None, + "The maximum level to which the (ink) bottom of superscript can be pushed to increase the gap between superscript and subscript, before subscript starts being moved down. Suggested: 4/5 x-height.", + ), + ( + "MathValueRecord", + "SpaceAfterScript", + None, + None, + "Extra white space to be added after each subscript and superscript. Suggested: 0.5pt for a 12 pt font.", + ), + ( + "MathValueRecord", + "UpperLimitGapMin", + None, + None, + "Minimum gap between the (ink) bottom of the upper limit, and the (ink) top of the base operator.", + ), + ( + "MathValueRecord", + "UpperLimitBaselineRiseMin", + None, + None, + "Minimum distance between baseline of upper limit and (ink) top of the base operator.", + ), + ( + "MathValueRecord", + "LowerLimitGapMin", + None, + None, + "Minimum gap between (ink) top of the lower limit, and (ink) bottom of the base operator.", + ), + ( + "MathValueRecord", + "LowerLimitBaselineDropMin", + None, + None, + "Minimum distance between baseline of the lower limit and (ink) bottom of the base operator.", + ), + ( + "MathValueRecord", + "StackTopShiftUp", + None, + None, + "Standard shift up applied to the top element of a stack.", + ), + ( + "MathValueRecord", + "StackTopDisplayStyleShiftUp", + None, + None, + "Standard shift up applied to the top element of a stack in display style.", + ), + ( + "MathValueRecord", + "StackBottomShiftDown", + None, + None, + "Standard shift down applied to the bottom element of a stack. Positive for moving in the downward direction.", + ), + ( + "MathValueRecord", + "StackBottomDisplayStyleShiftDown", + None, + None, + "Standard shift down applied to the bottom element of a stack in display style. Positive for moving in the downward direction.", + ), + ( + "MathValueRecord", + "StackGapMin", + None, + None, + "Minimum gap between (ink) bottom of the top element of a stack, and the (ink) top of the bottom element. Suggested: 3x default rule thickness.", + ), + ( + "MathValueRecord", + "StackDisplayStyleGapMin", + None, + None, + "Minimum gap between (ink) bottom of the top element of a stack, and the (ink) top of the bottom element in display style. Suggested: 7x default rule thickness.", + ), + ( + "MathValueRecord", + "StretchStackTopShiftUp", + None, + None, + "Standard shift up applied to the top element of the stretch stack.", + ), + ( + "MathValueRecord", + "StretchStackBottomShiftDown", + None, + None, + "Standard shift down applied to the bottom element of the stretch stack. Positive for moving in the downward direction.", + ), + ( + "MathValueRecord", + "StretchStackGapAboveMin", + None, + None, + "Minimum gap between the ink of the stretched element, and the (ink) bottom of the element above. Suggested: UpperLimitGapMin", + ), + ( + "MathValueRecord", + "StretchStackGapBelowMin", + None, + None, + "Minimum gap between the ink of the stretched element, and the (ink) top of the element below. Suggested: LowerLimitGapMin.", + ), + ( + "MathValueRecord", + "FractionNumeratorShiftUp", + None, + None, + "Standard shift up applied to the numerator.", + ), + ( + "MathValueRecord", + "FractionNumeratorDisplayStyleShiftUp", + None, + None, + "Standard shift up applied to the numerator in display style. Suggested: StackTopDisplayStyleShiftUp.", + ), + ( + "MathValueRecord", + "FractionDenominatorShiftDown", + None, + None, + "Standard shift down applied to the denominator. Positive for moving in the downward direction.", + ), + ( + "MathValueRecord", + "FractionDenominatorDisplayStyleShiftDown", + None, + None, + "Standard shift down applied to the denominator in display style. Positive for moving in the downward direction. Suggested: StackBottomDisplayStyleShiftDown.", + ), + ( + "MathValueRecord", + "FractionNumeratorGapMin", + None, + None, + "Minimum tolerated gap between the (ink) bottom of the numerator and the ink of the fraction bar. Suggested: default rule thickness", + ), + ( + "MathValueRecord", + "FractionNumDisplayStyleGapMin", + None, + None, + "Minimum tolerated gap between the (ink) bottom of the numerator and the ink of the fraction bar in display style. Suggested: 3x default rule thickness.", + ), + ( + "MathValueRecord", + "FractionRuleThickness", + None, + None, + "Thickness of the fraction bar. Suggested: default rule thickness.", + ), + ( + "MathValueRecord", + "FractionDenominatorGapMin", + None, + None, + "Minimum tolerated gap between the (ink) top of the denominator and the ink of the fraction bar. Suggested: default rule thickness", + ), + ( + "MathValueRecord", + "FractionDenomDisplayStyleGapMin", + None, + None, + "Minimum tolerated gap between the (ink) top of the denominator and the ink of the fraction bar in display style. Suggested: 3x default rule thickness.", + ), + ( + "MathValueRecord", + "SkewedFractionHorizontalGap", + None, + None, + "Horizontal distance between the top and bottom elements of a skewed fraction.", + ), + ( + "MathValueRecord", + "SkewedFractionVerticalGap", + None, + None, + "Vertical distance between the ink of the top and bottom elements of a skewed fraction.", + ), + ( + "MathValueRecord", + "OverbarVerticalGap", + None, + None, + "Distance between the overbar and the (ink) top of he base. Suggested: 3x default rule thickness.", + ), + ( + "MathValueRecord", + "OverbarRuleThickness", + None, + None, + "Thickness of overbar. Suggested: default rule thickness.", + ), + ( + "MathValueRecord", + "OverbarExtraAscender", + None, + None, + "Extra white space reserved above the overbar. Suggested: default rule thickness.", + ), + ( + "MathValueRecord", + "UnderbarVerticalGap", + None, + None, + "Distance between underbar and (ink) bottom of the base. Suggested: 3x default rule thickness.", + ), + ( + "MathValueRecord", + "UnderbarRuleThickness", + None, + None, + "Thickness of underbar. Suggested: default rule thickness.", + ), + ( + "MathValueRecord", + "UnderbarExtraDescender", + None, + None, + "Extra white space reserved below the underbar. Always positive. Suggested: default rule thickness.", + ), + ( + "MathValueRecord", + "RadicalVerticalGap", + None, + None, + "Space between the (ink) top of the expression and the bar over it. Suggested: 1 1/4 default rule thickness.", + ), + ( + "MathValueRecord", + "RadicalDisplayStyleVerticalGap", + None, + None, + "Space between the (ink) top of the expression and the bar over it. Suggested: default rule thickness + 1/4 x-height.", + ), + ( + "MathValueRecord", + "RadicalRuleThickness", + None, + None, + "Thickness of the radical rule. This is the thickness of the rule in designed or constructed radical signs. Suggested: default rule thickness.", + ), + ( + "MathValueRecord", + "RadicalExtraAscender", + None, + None, + "Extra white space reserved above the radical. Suggested: RadicalRuleThickness.", + ), + ( + "MathValueRecord", + "RadicalKernBeforeDegree", + None, + None, + "Extra horizontal kern before the degree of a radical, if such is present. Suggested: 5/18 of em.", + ), + ( + "MathValueRecord", + "RadicalKernAfterDegree", + None, + None, + "Negative kern after the degree of a radical, if such is present. Suggested: 10/18 of em.", + ), + ( + "uint16", + "RadicalDegreeBottomRaisePercent", + None, + None, + "Height of the bottom of the radical degree, if such is present, in proportion to the ascender of the radical sign. Suggested: 60%.", + ), + ], + ), + ( + "MathGlyphInfo", + [ + ( + "Offset", + "MathItalicsCorrectionInfo", + None, + None, + "Offset to MathItalicsCorrectionInfo table - from the beginning of MathGlyphInfo table.", + ), + ( + "Offset", + "MathTopAccentAttachment", + None, + None, + "Offset to MathTopAccentAttachment table - from the beginning of MathGlyphInfo table.", + ), + ( + "Offset", + "ExtendedShapeCoverage", + None, + None, + "Offset to coverage table for Extended Shape glyphs - from the beginning of MathGlyphInfo table. When the left or right glyph of a box is an extended shape variant, the (ink) box (and not the default position defined by values in MathConstants table) should be used for vertical positioning purposes. May be NULL.", + ), + ( + "Offset", + "MathKernInfo", + None, + None, + "Offset to MathKernInfo table - from the beginning of MathGlyphInfo table.", + ), + ], + ), + ( + "MathItalicsCorrectionInfo", + [ + ( + "Offset", + "Coverage", + None, + None, + "Offset to Coverage table - from the beginning of MathItalicsCorrectionInfo table.", + ), + ( + "uint16", + "ItalicsCorrectionCount", + None, + None, + "Number of italics correction values. Should coincide with the number of covered glyphs.", + ), + ( + "MathValueRecord", + "ItalicsCorrection", + "ItalicsCorrectionCount", + 0, + "Array of MathValueRecords defining italics correction values for each covered glyph.", + ), + ], + ), + ( + "MathTopAccentAttachment", + [ + ( + "Offset", + "TopAccentCoverage", + None, + None, + "Offset to Coverage table - from the beginning of MathTopAccentAttachment table.", + ), + ( + "uint16", + "TopAccentAttachmentCount", + None, + None, + "Number of top accent attachment point values. Should coincide with the number of covered glyphs", + ), + ( + "MathValueRecord", + "TopAccentAttachment", + "TopAccentAttachmentCount", + 0, + "Array of MathValueRecords defining top accent attachment points for each covered glyph", + ), + ], + ), + ( + "MathKernInfo", + [ + ( + "Offset", + "MathKernCoverage", + None, + None, + "Offset to Coverage table - from the beginning of the MathKernInfo table.", + ), + ("uint16", "MathKernCount", None, None, "Number of MathKernInfoRecords."), + ( + "MathKernInfoRecord", + "MathKernInfoRecords", + "MathKernCount", + 0, + "Array of MathKernInfoRecords, per-glyph information for mathematical positioning of subscripts and superscripts.", + ), + ], + ), + ( + "MathKernInfoRecord", + [ + ( + "Offset", + "TopRightMathKern", + None, + None, + "Offset to MathKern table for top right corner - from the beginning of MathKernInfo table. May be NULL.", + ), + ( + "Offset", + "TopLeftMathKern", + None, + None, + "Offset to MathKern table for the top left corner - from the beginning of MathKernInfo table. May be NULL.", + ), + ( + "Offset", + "BottomRightMathKern", + None, + None, + "Offset to MathKern table for bottom right corner - from the beginning of MathKernInfo table. May be NULL.", + ), + ( + "Offset", + "BottomLeftMathKern", + None, + None, + "Offset to MathKern table for bottom left corner - from the beginning of MathKernInfo table. May be NULL.", + ), + ], + ), + ( + "MathKern", + [ + ( + "uint16", + "HeightCount", + None, + None, + "Number of heights on which the kern value changes.", + ), + ( + "MathValueRecord", + "CorrectionHeight", + "HeightCount", + 0, + "Array of correction heights at which the kern value changes. Sorted by the height value in design units.", + ), + ( + "MathValueRecord", + "KernValue", + "HeightCount", + 1, + "Array of kern values corresponding to heights. First value is the kern value for all heights less or equal than the first height in this table.Last value is the value to be applied for all heights greater than the last height in this table. Negative values are interpreted as move glyphs closer to each other.", + ), + ], + ), + ( + "MathVariants", + [ + ( + "uint16", + "MinConnectorOverlap", + None, + None, + "Minimum overlap of connecting glyphs during glyph construction, in design units.", + ), + ( + "Offset", + "VertGlyphCoverage", + None, + None, + "Offset to Coverage table - from the beginning of MathVariants table.", + ), + ( + "Offset", + "HorizGlyphCoverage", + None, + None, + "Offset to Coverage table - from the beginning of MathVariants table.", + ), + ( + "uint16", + "VertGlyphCount", + None, + None, + "Number of glyphs for which information is provided for vertically growing variants.", + ), + ( + "uint16", + "HorizGlyphCount", + None, + None, + "Number of glyphs for which information is provided for horizontally growing variants.", + ), + ( + "Offset", + "VertGlyphConstruction", + "VertGlyphCount", + 0, + "Array of offsets to MathGlyphConstruction tables - from the beginning of the MathVariants table, for shapes growing in vertical direction.", + ), + ( + "Offset", + "HorizGlyphConstruction", + "HorizGlyphCount", + 0, + "Array of offsets to MathGlyphConstruction tables - from the beginning of the MathVariants table, for shapes growing in horizontal direction.", + ), + ], + ), + ( + "MathGlyphConstruction", + [ + ( + "Offset", + "GlyphAssembly", + None, + None, + "Offset to GlyphAssembly table for this shape - from the beginning of MathGlyphConstruction table. May be NULL", + ), + ( + "uint16", + "VariantCount", + None, + None, + "Count of glyph growing variants for this glyph.", + ), + ( + "MathGlyphVariantRecord", + "MathGlyphVariantRecord", + "VariantCount", + 0, + "MathGlyphVariantRecords for alternative variants of the glyphs.", + ), + ], + ), + ( + "MathGlyphVariantRecord", + [ + ("GlyphID", "VariantGlyph", None, None, "Glyph ID for the variant."), + ( + "uint16", + "AdvanceMeasurement", + None, + None, + "Advance width/height, in design units, of the variant, in the direction of requested glyph extension.", + ), + ], + ), + ( + "GlyphAssembly", + [ + ( + "MathValueRecord", + "ItalicsCorrection", + None, + None, + "Italics correction of this GlyphAssembly. Should not depend on the assembly size.", + ), + ("uint16", "PartCount", None, None, "Number of parts in this assembly."), + ( + "GlyphPartRecord", + "PartRecords", + "PartCount", + 0, + "Array of part records, from left to right and bottom to top.", + ), + ], + ), + ( + "GlyphPartRecord", + [ + ("GlyphID", "glyph", None, None, "Glyph ID for the part."), + ( + "uint16", + "StartConnectorLength", + None, + None, + "Advance width/ height of the straight bar connector material, in design units, is at the beginning of the glyph, in the direction of the extension.", + ), + ( + "uint16", + "EndConnectorLength", + None, + None, + "Advance width/ height of the straight bar connector material, in design units, is at the end of the glyph, in the direction of the extension.", + ), + ( + "uint16", + "FullAdvance", + None, + None, + "Full advance width/height for this part, in the direction of the extension. In design units.", + ), + ( + "uint16", + "PartFlags", + None, + None, + "Part qualifiers. PartFlags enumeration currently uses only one bit: 0x0001 fExtender: If set, the part can be skipped or repeated. 0xFFFE Reserved", + ), + ], + ), + ## + ## Apple Advanced Typography (AAT) tables + ## + ( + "AATLookupSegment", + [ + ("uint16", "lastGlyph", None, None, "Last glyph index in this segment."), + ("uint16", "firstGlyph", None, None, "First glyph index in this segment."), + ( + "uint16", + "value", + None, + None, + "A 16-bit offset from the start of the table to the data.", + ), + ], + ), + # + # ankr + # + ( + "ankr", + [ + ("struct", "AnchorPoints", None, None, "Anchor points table."), + ], + ), + ( + "AnchorPointsFormat0", + [ + ("uint16", "Format", None, None, "Format of the anchor points table, = 0."), + ("uint16", "Flags", None, None, "Flags. Currenty unused, set to zero."), + ( + "AATLookupWithDataOffset(AnchorGlyphData)", + "Anchors", + None, + None, + "Table of with anchor overrides for each glyph.", + ), + ], + ), + ( + "AnchorGlyphData", + [ + ( + "uint32", + "AnchorPointCount", + None, + None, + "Number of anchor points for this glyph.", + ), + ( + "struct", + "AnchorPoint", + "AnchorPointCount", + 0, + "Individual anchor points.", + ), + ], + ), + ( + "AnchorPoint", + [ + ("int16", "XCoordinate", None, None, "X coordinate of this anchor point."), + ("int16", "YCoordinate", None, None, "Y coordinate of this anchor point."), + ], + ), + # + # bsln + # + ( + "bsln", + [ + ( + "Version", + "Version", + None, + None, + "Version number of the AAT baseline table (0x00010000 for the initial version).", + ), + ("struct", "Baseline", None, None, "Baseline table."), + ], + ), + ( + "BaselineFormat0", + [ + ("uint16", "Format", None, None, "Format of the baseline table, = 0."), + ( + "uint16", + "DefaultBaseline", + None, + None, + "Default baseline value for all glyphs. This value can be from 0 through 31.", + ), + ( + "uint16", + "Delta", + 32, + 0, + "These are the FUnit distance deltas from the font’s natural baseline to the other baselines used in the font. A total of 32 deltas must be assigned.", + ), + ], + ), + ( + "BaselineFormat1", + [ + ("uint16", "Format", None, None, "Format of the baseline table, = 1."), + ( + "uint16", + "DefaultBaseline", + None, + None, + "Default baseline value for all glyphs. This value can be from 0 through 31.", + ), + ( + "uint16", + "Delta", + 32, + 0, + "These are the FUnit distance deltas from the font’s natural baseline to the other baselines used in the font. A total of 32 deltas must be assigned.", + ), + ( + "AATLookup(uint16)", + "BaselineValues", + None, + None, + "Lookup table that maps glyphs to their baseline values.", + ), + ], + ), + ( + "BaselineFormat2", + [ + ("uint16", "Format", None, None, "Format of the baseline table, = 1."), + ( + "uint16", + "DefaultBaseline", + None, + None, + "Default baseline value for all glyphs. This value can be from 0 through 31.", + ), + ( + "GlyphID", + "StandardGlyph", + None, + None, + "Glyph index of the glyph in this font to be used to set the baseline values. This glyph must contain a set of control points (whose numbers are contained in the following field) that determines baseline distances.", + ), + ( + "uint16", + "ControlPoint", + 32, + 0, + "Array of 32 control point numbers, associated with the standard glyph. A value of 0xFFFF means there is no corresponding control point in the standard glyph.", + ), + ], + ), + ( + "BaselineFormat3", + [ + ("uint16", "Format", None, None, "Format of the baseline table, = 1."), + ( + "uint16", + "DefaultBaseline", + None, + None, + "Default baseline value for all glyphs. This value can be from 0 through 31.", + ), + ( + "GlyphID", + "StandardGlyph", + None, + None, + "Glyph index of the glyph in this font to be used to set the baseline values. This glyph must contain a set of control points (whose numbers are contained in the following field) that determines baseline distances.", + ), + ( + "uint16", + "ControlPoint", + 32, + 0, + "Array of 32 control point numbers, associated with the standard glyph. A value of 0xFFFF means there is no corresponding control point in the standard glyph.", + ), + ( + "AATLookup(uint16)", + "BaselineValues", + None, + None, + "Lookup table that maps glyphs to their baseline values.", + ), + ], + ), + # + # cidg + # + ( + "cidg", + [ + ("struct", "CIDGlyphMapping", None, None, "CID-to-glyph mapping table."), + ], + ), + ( + "CIDGlyphMappingFormat0", + [ + ( + "uint16", + "Format", + None, + None, + "Format of the CID-to-glyph mapping table, = 0.", + ), + ("uint16", "DataFormat", None, None, "Currenty unused, set to zero."), + ("uint32", "StructLength", None, None, "Size of the table in bytes."), + ("uint16", "Registry", None, None, "The registry ID."), + ( + "char64", + "RegistryName", + None, + None, + "The registry name in ASCII; unused bytes should be set to 0.", + ), + ("uint16", "Order", None, None, "The order ID."), + ( + "char64", + "OrderName", + None, + None, + "The order name in ASCII; unused bytes should be set to 0.", + ), + ("uint16", "SupplementVersion", None, None, "The supplement version."), + ( + "CIDGlyphMap", + "Mapping", + None, + None, + "A mapping from CIDs to the glyphs in the font, starting with CID 0. If a CID from the identified collection has no glyph in the font, 0xFFFF is used", + ), + ], + ), + # + # feat + # + ( + "feat", + [ + ( + "Version", + "Version", + None, + None, + "Version of the feat table-initially set to 0x00010000.", + ), + ("FeatureNames", "FeatureNames", None, None, "The feature names."), + ], + ), + ( + "FeatureNames", + [ + ( + "uint16", + "FeatureNameCount", + None, + None, + "Number of entries in the feature name array.", + ), + ("uint16", "Reserved1", None, None, "Reserved (set to zero)."), + ("uint32", "Reserved2", None, None, "Reserved (set to zero)."), + ( + "FeatureName", + "FeatureName", + "FeatureNameCount", + 0, + "The feature name array.", + ), + ], + ), + ( + "FeatureName", + [ + ("uint16", "FeatureType", None, None, "Feature type."), + ( + "uint16", + "SettingsCount", + None, + None, + "The number of records in the setting name array.", + ), + ( + "LOffset", + "Settings", + None, + None, + "Offset to setting table for this feature.", + ), + ( + "uint16", + "FeatureFlags", + None, + None, + "Single-bit flags associated with the feature type.", + ), + ( + "NameID", + "FeatureNameID", + None, + None, + "The name table index for the feature name.", + ), + ], + ), + ( + "Settings", + [ + ("Setting", "Setting", "SettingsCount", 0, "The setting array."), + ], + ), + ( + "Setting", + [ + ("uint16", "SettingValue", None, None, "The setting."), + ( + "NameID", + "SettingNameID", + None, + None, + "The name table index for the setting name.", + ), + ], + ), + # + # gcid + # + ( + "gcid", + [ + ("struct", "GlyphCIDMapping", None, None, "Glyph to CID mapping table."), + ], + ), + ( + "GlyphCIDMappingFormat0", + [ + ( + "uint16", + "Format", + None, + None, + "Format of the glyph-to-CID mapping table, = 0.", + ), + ("uint16", "DataFormat", None, None, "Currenty unused, set to zero."), + ("uint32", "StructLength", None, None, "Size of the table in bytes."), + ("uint16", "Registry", None, None, "The registry ID."), + ( + "char64", + "RegistryName", + None, + None, + "The registry name in ASCII; unused bytes should be set to 0.", + ), + ("uint16", "Order", None, None, "The order ID."), + ( + "char64", + "OrderName", + None, + None, + "The order name in ASCII; unused bytes should be set to 0.", + ), + ("uint16", "SupplementVersion", None, None, "The supplement version."), + ( + "GlyphCIDMap", + "Mapping", + None, + None, + "The CIDs for the glyphs in the font, starting with glyph 0. If a glyph does not correspond to a CID in the identified collection, 0xFFFF is used", + ), + ], + ), + # + # lcar + # + ( + "lcar", + [ + ( + "Version", + "Version", + None, + None, + "Version number of the ligature caret table (0x00010000 for the initial version).", + ), + ("struct", "LigatureCarets", None, None, "Ligature carets table."), + ], + ), + ( + "LigatureCaretsFormat0", + [ + ( + "uint16", + "Format", + None, + None, + "Format of the ligature caret table. Format 0 indicates division points are distances in font units, Format 1 indicates division points are indexes of control points.", + ), + ( + "AATLookup(LigCaretDistances)", + "Carets", + None, + None, + "Lookup table associating ligature glyphs with their caret positions, in font unit distances.", + ), + ], + ), + ( + "LigatureCaretsFormat1", + [ + ( + "uint16", + "Format", + None, + None, + "Format of the ligature caret table. Format 0 indicates division points are distances in font units, Format 1 indicates division points are indexes of control points.", + ), + ( + "AATLookup(LigCaretPoints)", + "Carets", + None, + None, + "Lookup table associating ligature glyphs with their caret positions, as control points.", + ), + ], + ), + ( + "LigCaretDistances", + [ + ("uint16", "DivsionPointCount", None, None, "Number of division points."), + ( + "int16", + "DivisionPoint", + "DivsionPointCount", + 0, + "Distance in font units through which a subdivision is made orthogonally to the baseline.", + ), + ], + ), + ( + "LigCaretPoints", + [ + ("uint16", "DivsionPointCount", None, None, "Number of division points."), + ( + "int16", + "DivisionPoint", + "DivsionPointCount", + 0, + "The number of the control point through which a subdivision is made orthogonally to the baseline.", + ), + ], + ), + # + # mort + # + ( + "mort", + [ + ("Version", "Version", None, None, "Version of the mort table."), + ( + "uint32", + "MorphChainCount", + None, + None, + "Number of metamorphosis chains.", + ), + ( + "MortChain", + "MorphChain", + "MorphChainCount", + 0, + "Array of metamorphosis chains.", + ), + ], + ), + ( + "MortChain", + [ + ( + "Flags32", + "DefaultFlags", + None, + None, + "The default specification for subtables.", + ), + ( + "uint32", + "StructLength", + None, + None, + "Total byte count, including this header; must be a multiple of 4.", + ), + ( + "uint16", + "MorphFeatureCount", + None, + None, + "Number of metamorphosis feature entries.", + ), + ( + "uint16", + "MorphSubtableCount", + None, + None, + "The number of subtables in the chain.", + ), + ( + "struct", + "MorphFeature", + "MorphFeatureCount", + 0, + "Array of metamorphosis features.", + ), + ( + "MortSubtable", + "MorphSubtable", + "MorphSubtableCount", + 0, + "Array of metamorphosis subtables.", + ), + ], + ), + ( + "MortSubtable", + [ + ( + "uint16", + "StructLength", + None, + None, + "Total subtable length, including this header.", + ), + ( + "uint8", + "CoverageFlags", + None, + None, + "Most significant byte of coverage flags.", + ), + ("uint8", "MorphType", None, None, "Subtable type."), + ( + "Flags32", + "SubFeatureFlags", + None, + None, + "The 32-bit mask identifying which subtable this is (the subtable being executed if the AND of this value and the processed defaultFlags is nonzero).", + ), + ("SubStruct", "SubStruct", None, None, "SubTable."), + ], + ), + # + # morx + # + ( + "morx", + [ + ("uint16", "Version", None, None, "Version of the morx table."), + ("uint16", "Reserved", None, None, "Reserved (set to zero)."), + ( + "uint32", + "MorphChainCount", + None, + None, + "Number of extended metamorphosis chains.", + ), + ( + "MorxChain", + "MorphChain", + "MorphChainCount", + 0, + "Array of extended metamorphosis chains.", + ), + ], + ), + ( + "MorxChain", + [ + ( + "Flags32", + "DefaultFlags", + None, + None, + "The default specification for subtables.", + ), + ( + "uint32", + "StructLength", + None, + None, + "Total byte count, including this header; must be a multiple of 4.", + ), + ( + "uint32", + "MorphFeatureCount", + None, + None, + "Number of feature subtable entries.", + ), + ( + "uint32", + "MorphSubtableCount", + None, + None, + "The number of subtables in the chain.", + ), + ( + "MorphFeature", + "MorphFeature", + "MorphFeatureCount", + 0, + "Array of metamorphosis features.", + ), + ( + "MorxSubtable", + "MorphSubtable", + "MorphSubtableCount", + 0, + "Array of extended metamorphosis subtables.", + ), + ], + ), + ( + "MorphFeature", + [ + ("uint16", "FeatureType", None, None, "The type of feature."), + ( + "uint16", + "FeatureSetting", + None, + None, + "The feature's setting (aka selector).", + ), + ( + "Flags32", + "EnableFlags", + None, + None, + "Flags for the settings that this feature and setting enables.", + ), + ( + "Flags32", + "DisableFlags", + None, + None, + "Complement of flags for the settings that this feature and setting disable.", + ), + ], + ), + # Apple TrueType Reference Manual, chapter “The ‘morx’ table”, + # section “Metamorphosis Subtables”. + # https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html + ( + "MorxSubtable", + [ + ( + "uint32", + "StructLength", + None, + None, + "Total subtable length, including this header.", + ), + ( + "uint8", + "CoverageFlags", + None, + None, + "Most significant byte of coverage flags.", + ), + ("uint16", "Reserved", None, None, "Unused."), + ("uint8", "MorphType", None, None, "Subtable type."), + ( + "Flags32", + "SubFeatureFlags", + None, + None, + "The 32-bit mask identifying which subtable this is (the subtable being executed if the AND of this value and the processed defaultFlags is nonzero).", + ), + ("SubStruct", "SubStruct", None, None, "SubTable."), + ], + ), + ( + "StateHeader", + [ + ( + "uint32", + "ClassCount", + None, + None, + "Number of classes, which is the number of 16-bit entry indices in a single line in the state array.", + ), + ( + "uint32", + "MorphClass", + None, + None, + "Offset from the start of this state table header to the start of the class table.", + ), + ( + "uint32", + "StateArrayOffset", + None, + None, + "Offset from the start of this state table header to the start of the state array.", + ), + ( + "uint32", + "EntryTableOffset", + None, + None, + "Offset from the start of this state table header to the start of the entry table.", + ), + ], + ), + ( + "RearrangementMorph", + [ + ( + "STXHeader(RearrangementMorphAction)", + "StateTable", + None, + None, + "Finite-state transducer table for indic rearrangement.", + ), + ], + ), + ( + "ContextualMorph", + [ + ( + "STXHeader(ContextualMorphAction)", + "StateTable", + None, + None, + "Finite-state transducer for contextual glyph substitution.", + ), + ], + ), + ( + "LigatureMorph", + [ + ( + "STXHeader(LigatureMorphAction)", + "StateTable", + None, + None, + "Finite-state transducer for ligature substitution.", + ), + ], + ), + ( + "NoncontextualMorph", + [ + ( + "AATLookup(GlyphID)", + "Substitution", + None, + None, + "The noncontextual glyph substitution table.", + ), + ], + ), + ( + "InsertionMorph", + [ + ( + "STXHeader(InsertionMorphAction)", + "StateTable", + None, + None, + "Finite-state transducer for glyph insertion.", + ), + ], + ), + ( + "MorphClass", + [ + ( + "uint16", + "FirstGlyph", + None, + None, + "Glyph index of the first glyph in the class table.", + ), + # ('uint16', 'GlyphCount', None, None, 'Number of glyphs in class table.'), + # ('uint8', 'GlyphClass', 'GlyphCount', 0, 'The class codes (indexed by glyph index minus firstGlyph). Class codes range from 0 to the value of stateSize minus 1.'), + ], + ), + # If the 'morx' table version is 3 or greater, then the last subtable in the chain is followed by a subtableGlyphCoverageArray, as described below. + # ('Offset', 'MarkGlyphSetsDef', None, 'round(Version*0x10000) >= 0x00010002', 'Offset to the table of mark set definitions-from beginning of GDEF header (may be NULL)'), + # + # prop + # + ( + "prop", + [ + ( + "Fixed", + "Version", + None, + None, + "Version number of the AAT glyphs property table. Version 1.0 is the initial table version. Version 2.0, which is recognized by macOS 8.5 and later, adds support for the “attaches on right” bit. Version 3.0, which gets recognized by macOS X and iOS, adds support for the additional directional properties defined in Unicode 3.0.", + ), + ("struct", "GlyphProperties", None, None, "Glyph properties."), + ], + ), + ( + "GlyphPropertiesFormat0", + [ + ("uint16", "Format", None, None, "Format, = 0."), + ( + "uint16", + "DefaultProperties", + None, + None, + "Default properties applied to a glyph. Since there is no lookup table in prop format 0, the default properties get applied to every glyph in the font.", + ), + ], + ), + ( + "GlyphPropertiesFormat1", + [ + ("uint16", "Format", None, None, "Format, = 1."), + ( + "uint16", + "DefaultProperties", + None, + None, + "Default properties applied to a glyph if that glyph is not present in the Properties lookup table.", + ), + ( + "AATLookup(uint16)", + "Properties", + None, + None, + "Lookup data associating glyphs with their properties.", + ), + ], + ), + # + # opbd + # + ( + "opbd", + [ + ( + "Version", + "Version", + None, + None, + "Version number of the optical bounds table (0x00010000 for the initial version).", + ), + ("struct", "OpticalBounds", None, None, "Optical bounds table."), + ], + ), + ( + "OpticalBoundsFormat0", + [ + ( + "uint16", + "Format", + None, + None, + "Format of the optical bounds table, = 0.", + ), + ( + "AATLookup(OpticalBoundsDeltas)", + "OpticalBoundsDeltas", + None, + None, + "Lookup table associating glyphs with their optical bounds, given as deltas in font units.", + ), + ], + ), + ( + "OpticalBoundsFormat1", + [ + ( + "uint16", + "Format", + None, + None, + "Format of the optical bounds table, = 1.", + ), + ( + "AATLookup(OpticalBoundsPoints)", + "OpticalBoundsPoints", + None, + None, + "Lookup table associating glyphs with their optical bounds, given as references to control points.", + ), + ], + ), + ( + "OpticalBoundsDeltas", + [ + ( + "int16", + "Left", + None, + None, + "Delta value for the left-side optical edge.", + ), + ("int16", "Top", None, None, "Delta value for the top-side optical edge."), + ( + "int16", + "Right", + None, + None, + "Delta value for the right-side optical edge.", + ), + ( + "int16", + "Bottom", + None, + None, + "Delta value for the bottom-side optical edge.", + ), + ], + ), + ( + "OpticalBoundsPoints", + [ + ( + "int16", + "Left", + None, + None, + "Control point index for the left-side optical edge, or -1 if this glyph has none.", + ), + ( + "int16", + "Top", + None, + None, + "Control point index for the top-side optical edge, or -1 if this glyph has none.", + ), + ( + "int16", + "Right", + None, + None, + "Control point index for the right-side optical edge, or -1 if this glyph has none.", + ), + ( + "int16", + "Bottom", + None, + None, + "Control point index for the bottom-side optical edge, or -1 if this glyph has none.", + ), + ], + ), + # + # TSIC + # + ( + "TSIC", + [ + ( + "Version", + "Version", + None, + None, + "Version of table initially set to 0x00010000.", + ), + ("uint16", "Flags", None, None, "TSIC flags - set to 0"), + ("uint16", "AxisCount", None, None, "Axis count from fvar"), + ("uint16", "RecordCount", None, None, "TSIC record count"), + ("uint16", "Reserved", None, None, "Set to 0"), + ("Tag", "AxisArray", "AxisCount", 0, "Array of axis tags in fvar order"), + ( + "LocationRecord", + "RecordLocations", + "RecordCount", + 0, + "Location in variation space of TSIC record", + ), + ("TSICRecord", "Record", "RecordCount", 0, "Array of TSIC records"), + ], + ), + ( + "LocationRecord", + [ + ("F2Dot14", "Axis", "AxisCount", 0, "Axis record"), + ], + ), + ( + "TSICRecord", + [ + ("uint16", "Flags", None, None, "Record flags - set to 0"), + ("uint16", "NumCVTEntries", None, None, "Number of CVT number value pairs"), + ("uint16", "NameLength", None, None, "Length of optional user record name"), + ("uint16", "NameArray", "NameLength", 0, "Unicode 16 name"), + ("uint16", "CVTArray", "NumCVTEntries", 0, "CVT number array"), + ("int16", "CVTValueArray", "NumCVTEntries", 0, "CVT value"), + ], + ), + # + # COLR + # + ( + "COLR", + [ + ("uint16", "Version", None, None, "Table version number (starts at 0)."), + ( + "uint16", + "BaseGlyphRecordCount", + None, + None, + "Number of Base Glyph Records.", + ), + ( + "LOffset", + "BaseGlyphRecordArray", + None, + None, + "Offset (from beginning of COLR table) to Base Glyph records.", + ), + ( + "LOffset", + "LayerRecordArray", + None, + None, + "Offset (from beginning of COLR table) to Layer Records.", + ), + ("uint16", "LayerRecordCount", None, None, "Number of Layer Records."), + ( + "LOffset", + "BaseGlyphList", + None, + "Version >= 1", + "Offset (from beginning of COLR table) to array of Version-1 Base Glyph records.", + ), + ( + "LOffset", + "LayerList", + None, + "Version >= 1", + "Offset (from beginning of COLR table) to LayerList.", + ), + ( + "LOffset", + "ClipList", + None, + "Version >= 1", + "Offset to ClipList table (may be NULL)", + ), + ( + "LOffsetTo(DeltaSetIndexMap)", + "VarIndexMap", + None, + "Version >= 1", + "Offset to DeltaSetIndexMap table (may be NULL)", + ), + ( + "LOffset", + "VarStore", + None, + "Version >= 1", + "Offset to variation store (may be NULL)", + ), + ], + ), + ( + "BaseGlyphRecordArray", + [ + ( + "BaseGlyphRecord", + "BaseGlyphRecord", + "BaseGlyphRecordCount", + 0, + "Base Glyph records.", + ), + ], + ), + ( + "BaseGlyphRecord", + [ + ( + "GlyphID", + "BaseGlyph", + None, + None, + "Glyph ID of reference glyph. This glyph is for reference only and is not rendered for color.", + ), + ( + "uint16", + "FirstLayerIndex", + None, + None, + "Index (from beginning of the Layer Records) to the layer record. There will be numLayers consecutive entries for this base glyph.", + ), + ( + "uint16", + "NumLayers", + None, + None, + "Number of color layers associated with this glyph.", + ), + ], + ), + ( + "LayerRecordArray", + [ + ("LayerRecord", "LayerRecord", "LayerRecordCount", 0, "Layer records."), + ], + ), + ( + "LayerRecord", + [ + ( + "GlyphID", + "LayerGlyph", + None, + None, + "Glyph ID of layer glyph (must be in z-order from bottom to top).", + ), + ( + "uint16", + "PaletteIndex", + None, + None, + "Index value to use with a selected color palette.", + ), + ], + ), + ( + "BaseGlyphList", + [ + ( + "uint32", + "BaseGlyphCount", + None, + None, + "Number of Version-1 Base Glyph records", + ), + ( + "struct", + "BaseGlyphPaintRecord", + "BaseGlyphCount", + 0, + "Array of Version-1 Base Glyph records", + ), + ], + ), + ( + "BaseGlyphPaintRecord", + [ + ("GlyphID", "BaseGlyph", None, None, "Glyph ID of reference glyph."), + ( + "LOffset", + "Paint", + None, + None, + "Offset (from beginning of BaseGlyphPaintRecord) to Paint, typically a PaintColrLayers.", + ), + ], + ), + ( + "LayerList", + [ + ("uint32", "LayerCount", None, None, "Number of Version-1 Layers"), + ( + "LOffset", + "Paint", + "LayerCount", + 0, + "Array of offsets to Paint tables, from the start of the LayerList table.", + ), + ], + ), + ( + "ClipListFormat1", + [ + ( + "uint8", + "Format", + None, + None, + "Format for ClipList with 16bit glyph IDs: 1", + ), + ("uint32", "ClipCount", None, None, "Number of Clip records."), + ( + "struct", + "ClipRecord", + "ClipCount", + 0, + "Array of Clip records sorted by glyph ID.", + ), + ], + ), + ( + "ClipRecord", + [ + ("uint16", "StartGlyphID", None, None, "First glyph ID in the range."), + ("uint16", "EndGlyphID", None, None, "Last glyph ID in the range."), + ("Offset24", "ClipBox", None, None, "Offset to a ClipBox table."), + ], + ), + ( + "ClipBoxFormat1", + [ + ( + "uint8", + "Format", + None, + None, + "Format for ClipBox without variation: set to 1.", + ), + ("int16", "xMin", None, None, "Minimum x of clip box."), + ("int16", "yMin", None, None, "Minimum y of clip box."), + ("int16", "xMax", None, None, "Maximum x of clip box."), + ("int16", "yMax", None, None, "Maximum y of clip box."), + ], + ), + ( + "ClipBoxFormat2", + [ + ("uint8", "Format", None, None, "Format for variable ClipBox: set to 2."), + ("int16", "xMin", None, None, "Minimum x of clip box. VarIndexBase + 0."), + ("int16", "yMin", None, None, "Minimum y of clip box. VarIndexBase + 1."), + ("int16", "xMax", None, None, "Maximum x of clip box. VarIndexBase + 2."), + ("int16", "yMax", None, None, "Maximum y of clip box. VarIndexBase + 3."), + ( + "VarIndex", + "VarIndexBase", + None, + None, + "Base index into DeltaSetIndexMap.", + ), + ], + ), + # COLRv1 Affine2x3 uses the same column-major order to serialize a 2D + # Affine Transformation as the one used by fontTools.misc.transform. + # However, for historical reasons, the labels 'xy' and 'yx' are swapped. + # Their fundamental meaning is the same though. + # COLRv1 Affine2x3 follows the names found in FreeType and Cairo. + # In all case, the second element in the 6-tuple correspond to the + # y-part of the x basis vector, and the third to the x-part of the y + # basis vector. + # See https://github.com/googlefonts/colr-gradients-spec/pull/85 + ( + "Affine2x3", + [ + ("Fixed", "xx", None, None, "x-part of x basis vector"), + ("Fixed", "yx", None, None, "y-part of x basis vector"), + ("Fixed", "xy", None, None, "x-part of y basis vector"), + ("Fixed", "yy", None, None, "y-part of y basis vector"), + ("Fixed", "dx", None, None, "Translation in x direction"), + ("Fixed", "dy", None, None, "Translation in y direction"), + ], + ), + ( + "VarAffine2x3", + [ + ("Fixed", "xx", None, None, "x-part of x basis vector. VarIndexBase + 0."), + ("Fixed", "yx", None, None, "y-part of x basis vector. VarIndexBase + 1."), + ("Fixed", "xy", None, None, "x-part of y basis vector. VarIndexBase + 2."), + ("Fixed", "yy", None, None, "y-part of y basis vector. VarIndexBase + 3."), + ( + "Fixed", + "dx", + None, + None, + "Translation in x direction. VarIndexBase + 4.", + ), + ( + "Fixed", + "dy", + None, + None, + "Translation in y direction. VarIndexBase + 5.", + ), + ( + "VarIndex", + "VarIndexBase", + None, + None, + "Base index into DeltaSetIndexMap.", + ), + ], + ), + ( + "ColorStop", + [ + ("F2Dot14", "StopOffset", None, None, ""), + ("uint16", "PaletteIndex", None, None, "Index for a CPAL palette entry."), + ("F2Dot14", "Alpha", None, None, "Values outsided [0.,1.] reserved"), + ], + ), + ( + "VarColorStop", + [ + ("F2Dot14", "StopOffset", None, None, "VarIndexBase + 0."), + ("uint16", "PaletteIndex", None, None, "Index for a CPAL palette entry."), + ( + "F2Dot14", + "Alpha", + None, + None, + "Values outsided [0.,1.] reserved. VarIndexBase + 1.", + ), + ( + "VarIndex", + "VarIndexBase", + None, + None, + "Base index into DeltaSetIndexMap.", + ), + ], + ), + ( + "ColorLine", + [ + ( + "ExtendMode", + "Extend", + None, + None, + "Enum {PAD = 0, REPEAT = 1, REFLECT = 2}", + ), + ("uint16", "StopCount", None, None, "Number of Color stops."), + ("ColorStop", "ColorStop", "StopCount", 0, "Array of Color stops."), + ], + ), + ( + "VarColorLine", + [ + ( + "ExtendMode", + "Extend", + None, + None, + "Enum {PAD = 0, REPEAT = 1, REFLECT = 2}", + ), + ("uint16", "StopCount", None, None, "Number of Color stops."), + ("VarColorStop", "ColorStop", "StopCount", 0, "Array of Color stops."), + ], + ), + # PaintColrLayers + ( + "PaintFormat1", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 1"), + ( + "uint8", + "NumLayers", + None, + None, + "Number of offsets to Paint to read from LayerList.", + ), + ("uint32", "FirstLayerIndex", None, None, "Index into LayerList."), + ], + ), + # PaintSolid + ( + "PaintFormat2", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 2"), + ("uint16", "PaletteIndex", None, None, "Index for a CPAL palette entry."), + ("F2Dot14", "Alpha", None, None, "Values outsided [0.,1.] reserved"), + ], + ), + # PaintVarSolid + ( + "PaintFormat3", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 3"), + ("uint16", "PaletteIndex", None, None, "Index for a CPAL palette entry."), + ( + "F2Dot14", + "Alpha", + None, + None, + "Values outsided [0.,1.] reserved. VarIndexBase + 0.", + ), + ( + "VarIndex", + "VarIndexBase", + None, + None, + "Base index into DeltaSetIndexMap.", + ), + ], + ), + # PaintLinearGradient + ( + "PaintFormat4", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 4"), + ( + "Offset24", + "ColorLine", + None, + None, + "Offset (from beginning of PaintLinearGradient table) to ColorLine subtable.", + ), + ("int16", "x0", None, None, ""), + ("int16", "y0", None, None, ""), + ("int16", "x1", None, None, ""), + ("int16", "y1", None, None, ""), + ("int16", "x2", None, None, ""), + ("int16", "y2", None, None, ""), + ], + ), + # PaintVarLinearGradient + ( + "PaintFormat5", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 5"), + ( + "LOffset24To(VarColorLine)", + "ColorLine", + None, + None, + "Offset (from beginning of PaintVarLinearGradient table) to VarColorLine subtable.", + ), + ("int16", "x0", None, None, "VarIndexBase + 0."), + ("int16", "y0", None, None, "VarIndexBase + 1."), + ("int16", "x1", None, None, "VarIndexBase + 2."), + ("int16", "y1", None, None, "VarIndexBase + 3."), + ("int16", "x2", None, None, "VarIndexBase + 4."), + ("int16", "y2", None, None, "VarIndexBase + 5."), + ( + "VarIndex", + "VarIndexBase", + None, + None, + "Base index into DeltaSetIndexMap.", + ), + ], + ), + # PaintRadialGradient + ( + "PaintFormat6", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 6"), + ( + "Offset24", + "ColorLine", + None, + None, + "Offset (from beginning of PaintRadialGradient table) to ColorLine subtable.", + ), + ("int16", "x0", None, None, ""), + ("int16", "y0", None, None, ""), + ("uint16", "r0", None, None, ""), + ("int16", "x1", None, None, ""), + ("int16", "y1", None, None, ""), + ("uint16", "r1", None, None, ""), + ], + ), + # PaintVarRadialGradient + ( + "PaintFormat7", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 7"), + ( + "LOffset24To(VarColorLine)", + "ColorLine", + None, + None, + "Offset (from beginning of PaintVarRadialGradient table) to VarColorLine subtable.", + ), + ("int16", "x0", None, None, "VarIndexBase + 0."), + ("int16", "y0", None, None, "VarIndexBase + 1."), + ("uint16", "r0", None, None, "VarIndexBase + 2."), + ("int16", "x1", None, None, "VarIndexBase + 3."), + ("int16", "y1", None, None, "VarIndexBase + 4."), + ("uint16", "r1", None, None, "VarIndexBase + 5."), + ( + "VarIndex", + "VarIndexBase", + None, + None, + "Base index into DeltaSetIndexMap.", + ), + ], + ), + # PaintSweepGradient + ( + "PaintFormat8", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 8"), + ( + "Offset24", + "ColorLine", + None, + None, + "Offset (from beginning of PaintSweepGradient table) to ColorLine subtable.", + ), + ("int16", "centerX", None, None, "Center x coordinate."), + ("int16", "centerY", None, None, "Center y coordinate."), + ( + "BiasedAngle", + "startAngle", + None, + None, + "Start of the angular range of the gradient.", + ), + ( + "BiasedAngle", + "endAngle", + None, + None, + "End of the angular range of the gradient.", + ), + ], + ), + # PaintVarSweepGradient + ( + "PaintFormat9", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 9"), + ( + "LOffset24To(VarColorLine)", + "ColorLine", + None, + None, + "Offset (from beginning of PaintVarSweepGradient table) to VarColorLine subtable.", + ), + ("int16", "centerX", None, None, "Center x coordinate. VarIndexBase + 0."), + ("int16", "centerY", None, None, "Center y coordinate. VarIndexBase + 1."), + ( + "BiasedAngle", + "startAngle", + None, + None, + "Start of the angular range of the gradient. VarIndexBase + 2.", + ), + ( + "BiasedAngle", + "endAngle", + None, + None, + "End of the angular range of the gradient. VarIndexBase + 3.", + ), + ( + "VarIndex", + "VarIndexBase", + None, + None, + "Base index into DeltaSetIndexMap.", + ), + ], + ), + # PaintGlyph + ( + "PaintFormat10", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 10"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintGlyph table) to Paint subtable.", + ), + ("GlyphID", "Glyph", None, None, "Glyph ID for the source outline."), + ], + ), + # PaintColrGlyph + ( + "PaintFormat11", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 11"), + ( + "GlyphID", + "Glyph", + None, + None, + "Virtual glyph ID for a BaseGlyphList base glyph.", + ), + ], + ), + # PaintTransform + ( + "PaintFormat12", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 12"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintTransform table) to Paint subtable.", + ), + ( + "LOffset24To(Affine2x3)", + "Transform", + None, + None, + "2x3 matrix for 2D affine transformations.", + ), + ], + ), + # PaintVarTransform + ( + "PaintFormat13", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 13"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintVarTransform table) to Paint subtable.", + ), + ( + "LOffset24To(VarAffine2x3)", + "Transform", + None, + None, + "2x3 matrix for 2D affine transformations.", + ), + ], + ), + # PaintTranslate + ( + "PaintFormat14", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 14"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintTranslate table) to Paint subtable.", + ), + ("int16", "dx", None, None, "Translation in x direction."), + ("int16", "dy", None, None, "Translation in y direction."), + ], + ), + # PaintVarTranslate + ( + "PaintFormat15", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 15"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintVarTranslate table) to Paint subtable.", + ), + ( + "int16", + "dx", + None, + None, + "Translation in x direction. VarIndexBase + 0.", + ), + ( + "int16", + "dy", + None, + None, + "Translation in y direction. VarIndexBase + 1.", + ), + ( + "VarIndex", + "VarIndexBase", + None, + None, + "Base index into DeltaSetIndexMap.", + ), + ], + ), + # PaintScale + ( + "PaintFormat16", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 16"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintScale table) to Paint subtable.", + ), + ("F2Dot14", "scaleX", None, None, ""), + ("F2Dot14", "scaleY", None, None, ""), + ], + ), + # PaintVarScale + ( + "PaintFormat17", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 17"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintVarScale table) to Paint subtable.", + ), + ("F2Dot14", "scaleX", None, None, "VarIndexBase + 0."), + ("F2Dot14", "scaleY", None, None, "VarIndexBase + 1."), + ( + "VarIndex", + "VarIndexBase", + None, + None, + "Base index into DeltaSetIndexMap.", + ), + ], + ), + # PaintScaleAroundCenter + ( + "PaintFormat18", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 18"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintScaleAroundCenter table) to Paint subtable.", + ), + ("F2Dot14", "scaleX", None, None, ""), + ("F2Dot14", "scaleY", None, None, ""), + ("int16", "centerX", None, None, ""), + ("int16", "centerY", None, None, ""), + ], + ), + # PaintVarScaleAroundCenter + ( + "PaintFormat19", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 19"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintVarScaleAroundCenter table) to Paint subtable.", + ), + ("F2Dot14", "scaleX", None, None, "VarIndexBase + 0."), + ("F2Dot14", "scaleY", None, None, "VarIndexBase + 1."), + ("int16", "centerX", None, None, "VarIndexBase + 2."), + ("int16", "centerY", None, None, "VarIndexBase + 3."), + ( + "VarIndex", + "VarIndexBase", + None, + None, + "Base index into DeltaSetIndexMap.", + ), + ], + ), + # PaintScaleUniform + ( + "PaintFormat20", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 20"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintScaleUniform table) to Paint subtable.", + ), + ("F2Dot14", "scale", None, None, ""), + ], + ), + # PaintVarScaleUniform + ( + "PaintFormat21", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 21"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintVarScaleUniform table) to Paint subtable.", + ), + ("F2Dot14", "scale", None, None, "VarIndexBase + 0."), + ( + "VarIndex", + "VarIndexBase", + None, + None, + "Base index into DeltaSetIndexMap.", + ), + ], + ), + # PaintScaleUniformAroundCenter + ( + "PaintFormat22", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 22"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintScaleUniformAroundCenter table) to Paint subtable.", + ), + ("F2Dot14", "scale", None, None, ""), + ("int16", "centerX", None, None, ""), + ("int16", "centerY", None, None, ""), + ], + ), + # PaintVarScaleUniformAroundCenter + ( + "PaintFormat23", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 23"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintVarScaleUniformAroundCenter table) to Paint subtable.", + ), + ("F2Dot14", "scale", None, None, "VarIndexBase + 0"), + ("int16", "centerX", None, None, "VarIndexBase + 1"), + ("int16", "centerY", None, None, "VarIndexBase + 2"), + ( + "VarIndex", + "VarIndexBase", + None, + None, + "Base index into DeltaSetIndexMap.", + ), + ], + ), + # PaintRotate + ( + "PaintFormat24", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 24"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintRotate table) to Paint subtable.", + ), + ("Angle", "angle", None, None, ""), + ], + ), + # PaintVarRotate + ( + "PaintFormat25", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 25"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintVarRotate table) to Paint subtable.", + ), + ("Angle", "angle", None, None, "VarIndexBase + 0."), + ( + "VarIndex", + "VarIndexBase", + None, + None, + "Base index into DeltaSetIndexMap.", + ), + ], + ), + # PaintRotateAroundCenter + ( + "PaintFormat26", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 26"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintRotateAroundCenter table) to Paint subtable.", + ), + ("Angle", "angle", None, None, ""), + ("int16", "centerX", None, None, ""), + ("int16", "centerY", None, None, ""), + ], + ), + # PaintVarRotateAroundCenter + ( + "PaintFormat27", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 27"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintVarRotateAroundCenter table) to Paint subtable.", + ), + ("Angle", "angle", None, None, "VarIndexBase + 0."), + ("int16", "centerX", None, None, "VarIndexBase + 1."), + ("int16", "centerY", None, None, "VarIndexBase + 2."), + ( + "VarIndex", + "VarIndexBase", + None, + None, + "Base index into DeltaSetIndexMap.", + ), + ], + ), + # PaintSkew + ( + "PaintFormat28", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 28"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintSkew table) to Paint subtable.", + ), + ("Angle", "xSkewAngle", None, None, ""), + ("Angle", "ySkewAngle", None, None, ""), + ], + ), + # PaintVarSkew + ( + "PaintFormat29", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 29"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintVarSkew table) to Paint subtable.", + ), + ("Angle", "xSkewAngle", None, None, "VarIndexBase + 0."), + ("Angle", "ySkewAngle", None, None, "VarIndexBase + 1."), + ( + "VarIndex", + "VarIndexBase", + None, + None, + "Base index into DeltaSetIndexMap.", + ), + ], + ), + # PaintSkewAroundCenter + ( + "PaintFormat30", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 30"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintSkewAroundCenter table) to Paint subtable.", + ), + ("Angle", "xSkewAngle", None, None, ""), + ("Angle", "ySkewAngle", None, None, ""), + ("int16", "centerX", None, None, ""), + ("int16", "centerY", None, None, ""), + ], + ), + # PaintVarSkewAroundCenter + ( + "PaintFormat31", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 31"), + ( + "Offset24", + "Paint", + None, + None, + "Offset (from beginning of PaintVarSkewAroundCenter table) to Paint subtable.", + ), + ("Angle", "xSkewAngle", None, None, "VarIndexBase + 0."), + ("Angle", "ySkewAngle", None, None, "VarIndexBase + 1."), + ("int16", "centerX", None, None, "VarIndexBase + 2."), + ("int16", "centerY", None, None, "VarIndexBase + 3."), + ( + "VarIndex", + "VarIndexBase", + None, + None, + "Base index into DeltaSetIndexMap.", + ), + ], + ), + # PaintComposite + ( + "PaintFormat32", + [ + ("uint8", "PaintFormat", None, None, "Format identifier-format = 32"), + ( + "LOffset24To(Paint)", + "SourcePaint", + None, + None, + "Offset (from beginning of PaintComposite table) to source Paint subtable.", + ), + ( + "CompositeMode", + "CompositeMode", + None, + None, + "A CompositeMode enumeration value.", + ), + ( + "LOffset24To(Paint)", + "BackdropPaint", + None, + None, + "Offset (from beginning of PaintComposite table) to backdrop Paint subtable.", + ), + ], + ), + # + # avar + # + ( + "AxisValueMap", + [ + ( + "F2Dot14", + "FromCoordinate", + None, + None, + "A normalized coordinate value obtained using default normalization", + ), + ( + "F2Dot14", + "ToCoordinate", + None, + None, + "The modified, normalized coordinate value", + ), + ], + ), + ( + "AxisSegmentMap", + [ + ( + "uint16", + "PositionMapCount", + None, + None, + "The number of correspondence pairs for this axis", + ), + ( + "AxisValueMap", + "AxisValueMap", + "PositionMapCount", + 0, + "The array of axis value map records for this axis", + ), + ], + ), + ( + "avar", + [ + ( + "Version", + "Version", + None, + None, + "Version of the avar table- 0x00010000 or 0x00020000", + ), + ("uint16", "Reserved", None, None, "Permanently reserved; set to zero"), + ( + "uint16", + "AxisCount", + None, + None, + 'The number of variation axes for this font. This must be the same number as axisCount in the "fvar" table', + ), + ( + "AxisSegmentMap", + "AxisSegmentMap", + "AxisCount", + 0, + 'The segment maps array — one segment map for each axis, in the order of axes specified in the "fvar" table', + ), + ( + "LOffsetTo(DeltaSetIndexMap)", + "VarIdxMap", + None, + "Version >= 0x00020000", + "", + ), + ("LOffset", "VarStore", None, "Version >= 0x00020000", ""), + ], + ), +] diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/otTables.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/otTables.py new file mode 100644 index 0000000000000000000000000000000000000000..ab5dace7265826cbf4f8aa12a940b26da50b9623 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/otTables.py @@ -0,0 +1,2703 @@ +# coding: utf-8 +"""fontTools.ttLib.tables.otTables -- A collection of classes representing the various +OpenType subtables. + +Most are constructed upon import from data in otData.py, all are populated with +converter objects from otConverters.py. +""" +import copy +from enum import IntEnum +from functools import reduce +from math import radians +import itertools +from collections import defaultdict, namedtuple +from fontTools.ttLib import OPTIMIZE_FONT_SPEED +from fontTools.ttLib.tables.TupleVariation import TupleVariation +from fontTools.ttLib.tables.otTraverse import dfs_base_table +from fontTools.misc.arrayTools import quantizeRect +from fontTools.misc.roundTools import otRound +from fontTools.misc.transform import Transform, Identity, DecomposedTransform +from fontTools.misc.textTools import bytesjoin, pad, safeEval +from fontTools.misc.vector import Vector +from fontTools.pens.boundsPen import ControlBoundsPen +from fontTools.pens.transformPen import TransformPen +from .otBase import ( + BaseTable, + FormatSwitchingBaseTable, + ValueRecord, + CountReference, + getFormatSwitchingBaseTableClass, +) +from fontTools.misc.fixedTools import ( + fixedToFloat as fi2fl, + floatToFixed as fl2fi, + floatToFixedToStr as fl2str, + strToFixedToFloat as str2fl, +) +from fontTools.feaLib.lookupDebugInfo import LookupDebugInfo, LOOKUP_DEBUG_INFO_KEY +import logging +import struct +import array +import sys +from enum import IntFlag +from typing import TYPE_CHECKING, Iterator, List, Optional, Set + +if TYPE_CHECKING: + from fontTools.ttLib.ttGlyphSet import _TTGlyphSet + + +log = logging.getLogger(__name__) + + +class VarComponentFlags(IntFlag): + RESET_UNSPECIFIED_AXES = 1 << 0 + + HAVE_AXES = 1 << 1 + + AXIS_VALUES_HAVE_VARIATION = 1 << 2 + TRANSFORM_HAS_VARIATION = 1 << 3 + + HAVE_TRANSLATE_X = 1 << 4 + HAVE_TRANSLATE_Y = 1 << 5 + HAVE_ROTATION = 1 << 6 + + HAVE_CONDITION = 1 << 7 + + HAVE_SCALE_X = 1 << 8 + HAVE_SCALE_Y = 1 << 9 + HAVE_TCENTER_X = 1 << 10 + HAVE_TCENTER_Y = 1 << 11 + + GID_IS_24BIT = 1 << 12 + + HAVE_SKEW_X = 1 << 13 + HAVE_SKEW_Y = 1 << 14 + + RESERVED_MASK = (1 << 32) - (1 << 15) + + +VarTransformMappingValues = namedtuple( + "VarTransformMappingValues", + ["flag", "fractionalBits", "scale", "defaultValue"], +) + +VAR_TRANSFORM_MAPPING = { + "translateX": VarTransformMappingValues( + VarComponentFlags.HAVE_TRANSLATE_X, 0, 1, 0 + ), + "translateY": VarTransformMappingValues( + VarComponentFlags.HAVE_TRANSLATE_Y, 0, 1, 0 + ), + "rotation": VarTransformMappingValues(VarComponentFlags.HAVE_ROTATION, 12, 180, 0), + "scaleX": VarTransformMappingValues(VarComponentFlags.HAVE_SCALE_X, 10, 1, 1), + "scaleY": VarTransformMappingValues(VarComponentFlags.HAVE_SCALE_Y, 10, 1, 1), + "skewX": VarTransformMappingValues(VarComponentFlags.HAVE_SKEW_X, 12, -180, 0), + "skewY": VarTransformMappingValues(VarComponentFlags.HAVE_SKEW_Y, 12, 180, 0), + "tCenterX": VarTransformMappingValues(VarComponentFlags.HAVE_TCENTER_X, 0, 1, 0), + "tCenterY": VarTransformMappingValues(VarComponentFlags.HAVE_TCENTER_Y, 0, 1, 0), +} + +# Probably should be somewhere in fontTools.misc +_packer = { + 1: lambda v: struct.pack(">B", v), + 2: lambda v: struct.pack(">H", v), + 3: lambda v: struct.pack(">L", v)[1:], + 4: lambda v: struct.pack(">L", v), +} +_unpacker = { + 1: lambda v: struct.unpack(">B", v)[0], + 2: lambda v: struct.unpack(">H", v)[0], + 3: lambda v: struct.unpack(">L", b"\0" + v)[0], + 4: lambda v: struct.unpack(">L", v)[0], +} + + +def _read_uint32var(data, i): + """Read a variable-length number from data starting at index i. + + Return the number and the next index. + """ + + b0 = data[i] + if b0 < 0x80: + return b0, i + 1 + elif b0 < 0xC0: + return (b0 - 0x80) << 8 | data[i + 1], i + 2 + elif b0 < 0xE0: + return (b0 - 0xC0) << 16 | data[i + 1] << 8 | data[i + 2], i + 3 + elif b0 < 0xF0: + return (b0 - 0xE0) << 24 | data[i + 1] << 16 | data[i + 2] << 8 | data[ + i + 3 + ], i + 4 + else: + return (b0 - 0xF0) << 32 | data[i + 1] << 24 | data[i + 2] << 16 | data[ + i + 3 + ] << 8 | data[i + 4], i + 5 + + +def _write_uint32var(v): + """Write a variable-length number. + + Return the data. + """ + if v < 0x80: + return struct.pack(">B", v) + elif v < 0x4000: + return struct.pack(">H", (v | 0x8000)) + elif v < 0x200000: + return struct.pack(">L", (v | 0xC00000))[1:] + elif v < 0x10000000: + return struct.pack(">L", (v | 0xE0000000)) + else: + return struct.pack(">B", 0xF0) + struct.pack(">L", v) + + +class VarComponent: + def __init__(self): + self.populateDefaults() + + def populateDefaults(self, propagator=None): + self.flags = 0 + self.glyphName = None + self.conditionIndex = None + self.axisIndicesIndex = None + self.axisValues = () + self.axisValuesVarIndex = NO_VARIATION_INDEX + self.transformVarIndex = NO_VARIATION_INDEX + self.transform = DecomposedTransform() + + def decompile(self, data, font, localState): + i = 0 + self.flags, i = _read_uint32var(data, i) + flags = self.flags + + gidSize = 3 if flags & VarComponentFlags.GID_IS_24BIT else 2 + glyphID = _unpacker[gidSize](data[i : i + gidSize]) + i += gidSize + self.glyphName = font.glyphOrder[glyphID] + + if flags & VarComponentFlags.HAVE_CONDITION: + self.conditionIndex, i = _read_uint32var(data, i) + + if flags & VarComponentFlags.HAVE_AXES: + self.axisIndicesIndex, i = _read_uint32var(data, i) + else: + self.axisIndicesIndex = None + + if self.axisIndicesIndex is None: + numAxes = 0 + else: + axisIndices = localState["AxisIndicesList"].Item[self.axisIndicesIndex] + numAxes = len(axisIndices) + + if flags & VarComponentFlags.HAVE_AXES: + axisValues, i = TupleVariation.decompileDeltas_(numAxes, data, i) + self.axisValues = tuple(fi2fl(v, 14) for v in axisValues) + else: + self.axisValues = () + assert len(self.axisValues) == numAxes + + if flags & VarComponentFlags.AXIS_VALUES_HAVE_VARIATION: + self.axisValuesVarIndex, i = _read_uint32var(data, i) + else: + self.axisValuesVarIndex = NO_VARIATION_INDEX + if flags & VarComponentFlags.TRANSFORM_HAS_VARIATION: + self.transformVarIndex, i = _read_uint32var(data, i) + else: + self.transformVarIndex = NO_VARIATION_INDEX + + self.transform = DecomposedTransform() + + def read_transform_component(values): + nonlocal i + if flags & values.flag: + v = ( + fi2fl( + struct.unpack(">h", data[i : i + 2])[0], values.fractionalBits + ) + * values.scale + ) + i += 2 + return v + else: + return values.defaultValue + + for attr_name, mapping_values in VAR_TRANSFORM_MAPPING.items(): + value = read_transform_component(mapping_values) + setattr(self.transform, attr_name, value) + + if not (flags & VarComponentFlags.HAVE_SCALE_Y): + self.transform.scaleY = self.transform.scaleX + + n = flags & VarComponentFlags.RESERVED_MASK + while n: + _, i = _read_uint32var(data, i) + n &= n - 1 + + return data[i:] + + def compile(self, font): + optimizeSpeed = font.cfg[OPTIMIZE_FONT_SPEED] + + data = [] + + flags = self.flags + + glyphID = font.getGlyphID(self.glyphName) + if glyphID > 65535: + flags |= VarComponentFlags.GID_IS_24BIT + data.append(_packer[3](glyphID)) + else: + flags &= ~VarComponentFlags.GID_IS_24BIT + data.append(_packer[2](glyphID)) + + if self.conditionIndex is not None: + flags |= VarComponentFlags.HAVE_CONDITION + data.append(_write_uint32var(self.conditionIndex)) + + numAxes = len(self.axisValues) + + if numAxes: + flags |= VarComponentFlags.HAVE_AXES + data.append(_write_uint32var(self.axisIndicesIndex)) + data.append( + TupleVariation.compileDeltaValues_( + [fl2fi(v, 14) for v in self.axisValues], + optimizeSize=not optimizeSpeed, + ) + ) + else: + flags &= ~VarComponentFlags.HAVE_AXES + + if self.axisValuesVarIndex != NO_VARIATION_INDEX: + flags |= VarComponentFlags.AXIS_VALUES_HAVE_VARIATION + data.append(_write_uint32var(self.axisValuesVarIndex)) + else: + flags &= ~VarComponentFlags.AXIS_VALUES_HAVE_VARIATION + if self.transformVarIndex != NO_VARIATION_INDEX: + flags |= VarComponentFlags.TRANSFORM_HAS_VARIATION + data.append(_write_uint32var(self.transformVarIndex)) + else: + flags &= ~VarComponentFlags.TRANSFORM_HAS_VARIATION + + def write_transform_component(value, values): + if flags & values.flag: + return struct.pack( + ">h", fl2fi(value / values.scale, values.fractionalBits) + ) + else: + return b"" + + for attr_name, mapping_values in VAR_TRANSFORM_MAPPING.items(): + value = getattr(self.transform, attr_name) + data.append(write_transform_component(value, mapping_values)) + + return _write_uint32var(flags) + bytesjoin(data) + + def toXML(self, writer, ttFont, attrs): + writer.begintag("VarComponent", attrs) + writer.newline() + + def write(name, value, attrs=()): + if value is not None: + writer.simpletag(name, (("value", value),) + attrs) + writer.newline() + + write("glyphName", self.glyphName) + + if self.conditionIndex is not None: + write("conditionIndex", self.conditionIndex) + if self.axisIndicesIndex is not None: + write("axisIndicesIndex", self.axisIndicesIndex) + if ( + self.axisIndicesIndex is not None + or self.flags & VarComponentFlags.RESET_UNSPECIFIED_AXES + ): + if self.flags & VarComponentFlags.RESET_UNSPECIFIED_AXES: + attrs = (("resetUnspecifiedAxes", 1),) + else: + attrs = () + write("axisValues", [float(fl2str(v, 14)) for v in self.axisValues], attrs) + + if self.axisValuesVarIndex != NO_VARIATION_INDEX: + write("axisValuesVarIndex", self.axisValuesVarIndex) + if self.transformVarIndex != NO_VARIATION_INDEX: + write("transformVarIndex", self.transformVarIndex) + + # Only write transform components that are specified in the + # flags, even if they are the default value. + for attr_name, mapping in VAR_TRANSFORM_MAPPING.items(): + if not (self.flags & mapping.flag): + continue + v = getattr(self.transform, attr_name) + write(attr_name, fl2str(v, mapping.fractionalBits)) + + writer.endtag("VarComponent") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont): + content = [c for c in content if isinstance(c, tuple)] + + self.populateDefaults() + + for name, attrs, content in content: + assert not content + v = attrs["value"] + + if name == "glyphName": + self.glyphName = v + elif name == "conditionIndex": + self.conditionIndex = safeEval(v) + elif name == "axisIndicesIndex": + self.axisIndicesIndex = safeEval(v) + elif name == "axisValues": + self.axisValues = tuple(str2fl(v, 14) for v in safeEval(v)) + if safeEval(attrs.get("resetUnspecifiedAxes", "0")): + self.flags |= VarComponentFlags.RESET_UNSPECIFIED_AXES + elif name == "axisValuesVarIndex": + self.axisValuesVarIndex = safeEval(v) + elif name == "transformVarIndex": + self.transformVarIndex = safeEval(v) + elif name in VAR_TRANSFORM_MAPPING: + setattr( + self.transform, + name, + safeEval(v), + ) + self.flags |= VAR_TRANSFORM_MAPPING[name].flag + else: + assert False, name + + def applyTransformDeltas(self, deltas): + i = 0 + + def read_transform_component_delta(values): + nonlocal i + if self.flags & values.flag: + v = fi2fl(deltas[i], values.fractionalBits) * values.scale + i += 1 + return v + else: + return 0 + + for attr_name, mapping_values in VAR_TRANSFORM_MAPPING.items(): + value = read_transform_component_delta(mapping_values) + setattr( + self.transform, attr_name, getattr(self.transform, attr_name) + value + ) + + if not (self.flags & VarComponentFlags.HAVE_SCALE_Y): + self.transform.scaleY = self.transform.scaleX + + assert i == len(deltas), (i, len(deltas)) + + def __eq__(self, other): + if type(self) != type(other): + return NotImplemented + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + result = self.__eq__(other) + return result if result is NotImplemented else not result + + +class VarCompositeGlyph: + def __init__(self, components=None): + self.components = components if components is not None else [] + + def decompile(self, data, font, localState): + self.components = [] + while data: + component = VarComponent() + data = component.decompile(data, font, localState) + self.components.append(component) + + def compile(self, font): + data = [] + for component in self.components: + data.append(component.compile(font)) + return bytesjoin(data) + + def toXML(self, xmlWriter, font, attrs, name): + xmlWriter.begintag("VarCompositeGlyph", attrs) + xmlWriter.newline() + for i, component in enumerate(self.components): + component.toXML(xmlWriter, font, [("index", i)]) + xmlWriter.endtag("VarCompositeGlyph") + xmlWriter.newline() + + def fromXML(self, name, attrs, content, font): + content = [c for c in content if isinstance(c, tuple)] + for name, attrs, content in content: + assert name == "VarComponent" + component = VarComponent() + component.fromXML(name, attrs, content, font) + self.components.append(component) + + +class AATStateTable(object): + def __init__(self): + self.GlyphClasses = {} # GlyphID --> GlyphClass + self.States = [] # List of AATState, indexed by state number + self.PerGlyphLookups = [] # [{GlyphID:GlyphID}, ...] + + +class AATState(object): + def __init__(self): + self.Transitions = {} # GlyphClass --> AATAction + + +class AATAction(object): + _FLAGS = None + + @staticmethod + def compileActions(font, states): + return (None, None) + + def _writeFlagsToXML(self, xmlWriter): + flags = [f for f in self._FLAGS if self.__dict__[f]] + if flags: + xmlWriter.simpletag("Flags", value=",".join(flags)) + xmlWriter.newline() + if self.ReservedFlags != 0: + xmlWriter.simpletag("ReservedFlags", value="0x%04X" % self.ReservedFlags) + xmlWriter.newline() + + def _setFlag(self, flag): + assert flag in self._FLAGS, "unsupported flag %s" % flag + self.__dict__[flag] = True + + +class RearrangementMorphAction(AATAction): + staticSize = 4 + actionHeaderSize = 0 + _FLAGS = ["MarkFirst", "DontAdvance", "MarkLast"] + + _VERBS = { + 0: "no change", + 1: "Ax ⇒ xA", + 2: "xD ⇒ Dx", + 3: "AxD ⇒ DxA", + 4: "ABx ⇒ xAB", + 5: "ABx ⇒ xBA", + 6: "xCD ⇒ CDx", + 7: "xCD ⇒ DCx", + 8: "AxCD ⇒ CDxA", + 9: "AxCD ⇒ DCxA", + 10: "ABxD ⇒ DxAB", + 11: "ABxD ⇒ DxBA", + 12: "ABxCD ⇒ CDxAB", + 13: "ABxCD ⇒ CDxBA", + 14: "ABxCD ⇒ DCxAB", + 15: "ABxCD ⇒ DCxBA", + } + + def __init__(self): + self.NewState = 0 + self.Verb = 0 + self.MarkFirst = False + self.DontAdvance = False + self.MarkLast = False + self.ReservedFlags = 0 + + def compile(self, writer, font, actionIndex): + assert actionIndex is None + writer.writeUShort(self.NewState) + assert self.Verb >= 0 and self.Verb <= 15, self.Verb + flags = self.Verb | self.ReservedFlags + if self.MarkFirst: + flags |= 0x8000 + if self.DontAdvance: + flags |= 0x4000 + if self.MarkLast: + flags |= 0x2000 + writer.writeUShort(flags) + + def decompile(self, reader, font, actionReader): + assert actionReader is None + self.NewState = reader.readUShort() + flags = reader.readUShort() + self.Verb = flags & 0xF + self.MarkFirst = bool(flags & 0x8000) + self.DontAdvance = bool(flags & 0x4000) + self.MarkLast = bool(flags & 0x2000) + self.ReservedFlags = flags & 0x1FF0 + + def toXML(self, xmlWriter, font, attrs, name): + xmlWriter.begintag(name, **attrs) + xmlWriter.newline() + xmlWriter.simpletag("NewState", value=self.NewState) + xmlWriter.newline() + self._writeFlagsToXML(xmlWriter) + xmlWriter.simpletag("Verb", value=self.Verb) + verbComment = self._VERBS.get(self.Verb) + if verbComment is not None: + xmlWriter.comment(verbComment) + xmlWriter.newline() + xmlWriter.endtag(name) + xmlWriter.newline() + + def fromXML(self, name, attrs, content, font): + self.NewState = self.Verb = self.ReservedFlags = 0 + self.MarkFirst = self.DontAdvance = self.MarkLast = False + content = [t for t in content if isinstance(t, tuple)] + for eltName, eltAttrs, eltContent in content: + if eltName == "NewState": + self.NewState = safeEval(eltAttrs["value"]) + elif eltName == "Verb": + self.Verb = safeEval(eltAttrs["value"]) + elif eltName == "ReservedFlags": + self.ReservedFlags = safeEval(eltAttrs["value"]) + elif eltName == "Flags": + for flag in eltAttrs["value"].split(","): + self._setFlag(flag.strip()) + + +class ContextualMorphAction(AATAction): + staticSize = 8 + actionHeaderSize = 0 + _FLAGS = ["SetMark", "DontAdvance"] + + def __init__(self): + self.NewState = 0 + self.SetMark, self.DontAdvance = False, False + self.ReservedFlags = 0 + self.MarkIndex, self.CurrentIndex = 0xFFFF, 0xFFFF + + def compile(self, writer, font, actionIndex): + assert actionIndex is None + writer.writeUShort(self.NewState) + flags = self.ReservedFlags + if self.SetMark: + flags |= 0x8000 + if self.DontAdvance: + flags |= 0x4000 + writer.writeUShort(flags) + writer.writeUShort(self.MarkIndex) + writer.writeUShort(self.CurrentIndex) + + def decompile(self, reader, font, actionReader): + assert actionReader is None + self.NewState = reader.readUShort() + flags = reader.readUShort() + self.SetMark = bool(flags & 0x8000) + self.DontAdvance = bool(flags & 0x4000) + self.ReservedFlags = flags & 0x3FFF + self.MarkIndex = reader.readUShort() + self.CurrentIndex = reader.readUShort() + + def toXML(self, xmlWriter, font, attrs, name): + xmlWriter.begintag(name, **attrs) + xmlWriter.newline() + xmlWriter.simpletag("NewState", value=self.NewState) + xmlWriter.newline() + self._writeFlagsToXML(xmlWriter) + xmlWriter.simpletag("MarkIndex", value=self.MarkIndex) + xmlWriter.newline() + xmlWriter.simpletag("CurrentIndex", value=self.CurrentIndex) + xmlWriter.newline() + xmlWriter.endtag(name) + xmlWriter.newline() + + def fromXML(self, name, attrs, content, font): + self.NewState = self.ReservedFlags = 0 + self.SetMark = self.DontAdvance = False + self.MarkIndex, self.CurrentIndex = 0xFFFF, 0xFFFF + content = [t for t in content if isinstance(t, tuple)] + for eltName, eltAttrs, eltContent in content: + if eltName == "NewState": + self.NewState = safeEval(eltAttrs["value"]) + elif eltName == "Flags": + for flag in eltAttrs["value"].split(","): + self._setFlag(flag.strip()) + elif eltName == "ReservedFlags": + self.ReservedFlags = safeEval(eltAttrs["value"]) + elif eltName == "MarkIndex": + self.MarkIndex = safeEval(eltAttrs["value"]) + elif eltName == "CurrentIndex": + self.CurrentIndex = safeEval(eltAttrs["value"]) + + +class LigAction(object): + def __init__(self): + self.Store = False + # GlyphIndexDelta is a (possibly negative) delta that gets + # added to the glyph ID at the top of the AAT runtime + # execution stack. It is *not* a byte offset into the + # morx table. The result of the addition, which is performed + # at run time by the shaping engine, is an index into + # the ligature components table. See 'morx' specification. + # In the AAT specification, this field is called Offset; + # but its meaning is quite different from other offsets + # in either AAT or OpenType, so we use a different name. + self.GlyphIndexDelta = 0 + + +class LigatureMorphAction(AATAction): + staticSize = 6 + + # 4 bytes for each of {action,ligComponents,ligatures}Offset + actionHeaderSize = 12 + + _FLAGS = ["SetComponent", "DontAdvance"] + + def __init__(self): + self.NewState = 0 + self.SetComponent, self.DontAdvance = False, False + self.ReservedFlags = 0 + self.Actions = [] + + def compile(self, writer, font, actionIndex): + assert actionIndex is not None + writer.writeUShort(self.NewState) + flags = self.ReservedFlags + if self.SetComponent: + flags |= 0x8000 + if self.DontAdvance: + flags |= 0x4000 + if len(self.Actions) > 0: + flags |= 0x2000 + writer.writeUShort(flags) + if len(self.Actions) > 0: + actions = self.compileLigActions() + writer.writeUShort(actionIndex[actions]) + else: + writer.writeUShort(0) + + def decompile(self, reader, font, actionReader): + assert actionReader is not None + self.NewState = reader.readUShort() + flags = reader.readUShort() + self.SetComponent = bool(flags & 0x8000) + self.DontAdvance = bool(flags & 0x4000) + performAction = bool(flags & 0x2000) + # As of 2017-09-12, the 'morx' specification says that + # the reserved bitmask in ligature subtables is 0x3FFF. + # However, the specification also defines a flag 0x2000, + # so the reserved value should actually be 0x1FFF. + # TODO: Report this specification bug to Apple. + self.ReservedFlags = flags & 0x1FFF + actionIndex = reader.readUShort() + if performAction: + self.Actions = self._decompileLigActions(actionReader, actionIndex) + else: + self.Actions = [] + + @staticmethod + def compileActions(font, states): + result, actions, actionIndex = b"", set(), {} + for state in states: + for _glyphClass, trans in state.Transitions.items(): + actions.add(trans.compileLigActions()) + # Sort the compiled actions in decreasing order of + # length, so that the longer sequence come before the + # shorter ones. For each compiled action ABCD, its + # suffixes BCD, CD, and D do not be encoded separately + # (in case they occur); instead, we can just store an + # index that points into the middle of the longer + # sequence. Every compiled AAT ligature sequence is + # terminated with an end-of-sequence flag, which can + # only be set on the last element of the sequence. + # Therefore, it is sufficient to consider just the + # suffixes. + for a in sorted(actions, key=lambda x: (-len(x), x)): + if a not in actionIndex: + for i in range(0, len(a), 4): + suffix = a[i:] + suffixIndex = (len(result) + i) // 4 + actionIndex.setdefault(suffix, suffixIndex) + result += a + result = pad(result, 4) + return (result, actionIndex) + + def compileLigActions(self): + result = [] + for i, action in enumerate(self.Actions): + last = i == len(self.Actions) - 1 + value = action.GlyphIndexDelta & 0x3FFFFFFF + value |= 0x80000000 if last else 0 + value |= 0x40000000 if action.Store else 0 + result.append(struct.pack(">L", value)) + return bytesjoin(result) + + def _decompileLigActions(self, actionReader, actionIndex): + actions = [] + last = False + reader = actionReader.getSubReader(actionReader.pos + actionIndex * 4) + while not last: + value = reader.readULong() + last = bool(value & 0x80000000) + action = LigAction() + actions.append(action) + action.Store = bool(value & 0x40000000) + delta = value & 0x3FFFFFFF + if delta >= 0x20000000: # sign-extend 30-bit value + delta = -0x40000000 + delta + action.GlyphIndexDelta = delta + return actions + + def fromXML(self, name, attrs, content, font): + self.NewState = self.ReservedFlags = 0 + self.SetComponent = self.DontAdvance = False + self.ReservedFlags = 0 + self.Actions = [] + content = [t for t in content if isinstance(t, tuple)] + for eltName, eltAttrs, eltContent in content: + if eltName == "NewState": + self.NewState = safeEval(eltAttrs["value"]) + elif eltName == "Flags": + for flag in eltAttrs["value"].split(","): + self._setFlag(flag.strip()) + elif eltName == "ReservedFlags": + self.ReservedFlags = safeEval(eltAttrs["value"]) + elif eltName == "Action": + action = LigAction() + flags = eltAttrs.get("Flags", "").split(",") + flags = [f.strip() for f in flags] + action.Store = "Store" in flags + action.GlyphIndexDelta = safeEval(eltAttrs["GlyphIndexDelta"]) + self.Actions.append(action) + + def toXML(self, xmlWriter, font, attrs, name): + xmlWriter.begintag(name, **attrs) + xmlWriter.newline() + xmlWriter.simpletag("NewState", value=self.NewState) + xmlWriter.newline() + self._writeFlagsToXML(xmlWriter) + for action in self.Actions: + attribs = [("GlyphIndexDelta", action.GlyphIndexDelta)] + if action.Store: + attribs.append(("Flags", "Store")) + xmlWriter.simpletag("Action", attribs) + xmlWriter.newline() + xmlWriter.endtag(name) + xmlWriter.newline() + + +class InsertionMorphAction(AATAction): + staticSize = 8 + actionHeaderSize = 4 # 4 bytes for actionOffset + _FLAGS = [ + "SetMark", + "DontAdvance", + "CurrentIsKashidaLike", + "MarkedIsKashidaLike", + "CurrentInsertBefore", + "MarkedInsertBefore", + ] + + def __init__(self): + self.NewState = 0 + for flag in self._FLAGS: + setattr(self, flag, False) + self.ReservedFlags = 0 + self.CurrentInsertionAction, self.MarkedInsertionAction = [], [] + + def compile(self, writer, font, actionIndex): + assert actionIndex is not None + writer.writeUShort(self.NewState) + flags = self.ReservedFlags + if self.SetMark: + flags |= 0x8000 + if self.DontAdvance: + flags |= 0x4000 + if self.CurrentIsKashidaLike: + flags |= 0x2000 + if self.MarkedIsKashidaLike: + flags |= 0x1000 + if self.CurrentInsertBefore: + flags |= 0x0800 + if self.MarkedInsertBefore: + flags |= 0x0400 + flags |= len(self.CurrentInsertionAction) << 5 + flags |= len(self.MarkedInsertionAction) + writer.writeUShort(flags) + if len(self.CurrentInsertionAction) > 0: + currentIndex = actionIndex[tuple(self.CurrentInsertionAction)] + else: + currentIndex = 0xFFFF + writer.writeUShort(currentIndex) + if len(self.MarkedInsertionAction) > 0: + markedIndex = actionIndex[tuple(self.MarkedInsertionAction)] + else: + markedIndex = 0xFFFF + writer.writeUShort(markedIndex) + + def decompile(self, reader, font, actionReader): + assert actionReader is not None + self.NewState = reader.readUShort() + flags = reader.readUShort() + self.SetMark = bool(flags & 0x8000) + self.DontAdvance = bool(flags & 0x4000) + self.CurrentIsKashidaLike = bool(flags & 0x2000) + self.MarkedIsKashidaLike = bool(flags & 0x1000) + self.CurrentInsertBefore = bool(flags & 0x0800) + self.MarkedInsertBefore = bool(flags & 0x0400) + self.CurrentInsertionAction = self._decompileInsertionAction( + actionReader, font, index=reader.readUShort(), count=((flags & 0x03E0) >> 5) + ) + self.MarkedInsertionAction = self._decompileInsertionAction( + actionReader, font, index=reader.readUShort(), count=(flags & 0x001F) + ) + + def _decompileInsertionAction(self, actionReader, font, index, count): + if index == 0xFFFF or count == 0: + return [] + reader = actionReader.getSubReader(actionReader.pos + index * 2) + return font.getGlyphNameMany(reader.readUShortArray(count)) + + def toXML(self, xmlWriter, font, attrs, name): + xmlWriter.begintag(name, **attrs) + xmlWriter.newline() + xmlWriter.simpletag("NewState", value=self.NewState) + xmlWriter.newline() + self._writeFlagsToXML(xmlWriter) + for g in self.CurrentInsertionAction: + xmlWriter.simpletag("CurrentInsertionAction", glyph=g) + xmlWriter.newline() + for g in self.MarkedInsertionAction: + xmlWriter.simpletag("MarkedInsertionAction", glyph=g) + xmlWriter.newline() + xmlWriter.endtag(name) + xmlWriter.newline() + + def fromXML(self, name, attrs, content, font): + self.__init__() + content = [t for t in content if isinstance(t, tuple)] + for eltName, eltAttrs, eltContent in content: + if eltName == "NewState": + self.NewState = safeEval(eltAttrs["value"]) + elif eltName == "Flags": + for flag in eltAttrs["value"].split(","): + self._setFlag(flag.strip()) + elif eltName == "CurrentInsertionAction": + self.CurrentInsertionAction.append(eltAttrs["glyph"]) + elif eltName == "MarkedInsertionAction": + self.MarkedInsertionAction.append(eltAttrs["glyph"]) + else: + assert False, eltName + + @staticmethod + def compileActions(font, states): + actions, actionIndex, result = set(), {}, b"" + for state in states: + for _glyphClass, trans in state.Transitions.items(): + if trans.CurrentInsertionAction is not None: + actions.add(tuple(trans.CurrentInsertionAction)) + if trans.MarkedInsertionAction is not None: + actions.add(tuple(trans.MarkedInsertionAction)) + # Sort the compiled actions in decreasing order of + # length, so that the longer sequence come before the + # shorter ones. + for action in sorted(actions, key=lambda x: (-len(x), x)): + # We insert all sub-sequences of the action glyph sequence + # into actionIndex. For example, if one action triggers on + # glyph sequence [A, B, C, D, E] and another action triggers + # on [C, D], we return result=[A, B, C, D, E] (as list of + # encoded glyph IDs), and actionIndex={('A','B','C','D','E'): 0, + # ('C','D'): 2}. + if action in actionIndex: + continue + for start in range(0, len(action)): + startIndex = (len(result) // 2) + start + for limit in range(start, len(action)): + glyphs = action[start : limit + 1] + actionIndex.setdefault(glyphs, startIndex) + for glyph in action: + glyphID = font.getGlyphID(glyph) + result += struct.pack(">H", glyphID) + return result, actionIndex + + +class FeatureParams(BaseTable): + def compile(self, writer, font): + assert ( + featureParamTypes.get(writer["FeatureTag"]) == self.__class__ + ), "Wrong FeatureParams type for feature '%s': %s" % ( + writer["FeatureTag"], + self.__class__.__name__, + ) + BaseTable.compile(self, writer, font) + + def toXML(self, xmlWriter, font, attrs=None, name=None): + BaseTable.toXML(self, xmlWriter, font, attrs, name=self.__class__.__name__) + + +class FeatureParamsSize(FeatureParams): + pass + + +class FeatureParamsStylisticSet(FeatureParams): + pass + + +class FeatureParamsCharacterVariants(FeatureParams): + pass + + +class Coverage(FormatSwitchingBaseTable): + # manual implementation to get rid of glyphID dependencies + + def populateDefaults(self, propagator=None): + if not hasattr(self, "glyphs"): + self.glyphs = [] + + def postRead(self, rawTable, font): + if self.Format == 1: + self.glyphs = rawTable["GlyphArray"] + elif self.Format == 2: + glyphs = self.glyphs = [] + ranges = rawTable["RangeRecord"] + # Some SIL fonts have coverage entries that don't have sorted + # StartCoverageIndex. If it is so, fixup and warn. We undo + # this when writing font out. + sorted_ranges = sorted(ranges, key=lambda a: a.StartCoverageIndex) + if ranges != sorted_ranges: + log.warning("GSUB/GPOS Coverage is not sorted by glyph ids.") + ranges = sorted_ranges + del sorted_ranges + for r in ranges: + start = r.Start + end = r.End + startID = font.getGlyphID(start) + endID = font.getGlyphID(end) + 1 + glyphs.extend(font.getGlyphNameMany(range(startID, endID))) + else: + self.glyphs = [] + log.warning("Unknown Coverage format: %s", self.Format) + del self.Format # Don't need this anymore + + def preWrite(self, font): + glyphs = getattr(self, "glyphs", None) + if glyphs is None: + glyphs = self.glyphs = [] + format = 1 + rawTable = {"GlyphArray": glyphs} + if glyphs: + # find out whether Format 2 is more compact or not + glyphIDs = font.getGlyphIDMany(glyphs) + brokenOrder = sorted(glyphIDs) != glyphIDs + + last = glyphIDs[0] + ranges = [[last]] + for glyphID in glyphIDs[1:]: + if glyphID != last + 1: + ranges[-1].append(last) + ranges.append([glyphID]) + last = glyphID + ranges[-1].append(last) + + if brokenOrder or len(ranges) * 3 < len(glyphs): # 3 words vs. 1 word + # Format 2 is more compact + index = 0 + for i, (start, end) in enumerate(ranges): + r = RangeRecord() + r.StartID = start + r.Start = font.getGlyphName(start) + r.End = font.getGlyphName(end) + r.StartCoverageIndex = index + ranges[i] = r + index = index + end - start + 1 + if brokenOrder: + log.warning("GSUB/GPOS Coverage is not sorted by glyph ids.") + ranges.sort(key=lambda a: a.StartID) + for r in ranges: + del r.StartID + format = 2 + rawTable = {"RangeRecord": ranges} + # else: + # fallthrough; Format 1 is more compact + self.Format = format + return rawTable + + def toXML2(self, xmlWriter, font): + for glyphName in getattr(self, "glyphs", []): + xmlWriter.simpletag("Glyph", value=glyphName) + xmlWriter.newline() + + def fromXML(self, name, attrs, content, font): + glyphs = getattr(self, "glyphs", None) + if glyphs is None: + glyphs = [] + self.glyphs = glyphs + glyphs.append(attrs["value"]) + + +# The special 0xFFFFFFFF delta-set index is used to indicate that there +# is no variation data in the ItemVariationStore for a given variable field +NO_VARIATION_INDEX = 0xFFFFFFFF + + +class DeltaSetIndexMap(getFormatSwitchingBaseTableClass("uint8")): + def populateDefaults(self, propagator=None): + if not hasattr(self, "mapping"): + self.mapping = [] + + def postRead(self, rawTable, font): + assert (rawTable["EntryFormat"] & 0xFFC0) == 0 + self.mapping = rawTable["mapping"] + + @staticmethod + def getEntryFormat(mapping): + ored = 0 + for idx in mapping: + ored |= idx + + inner = ored & 0xFFFF + innerBits = 0 + while inner: + innerBits += 1 + inner >>= 1 + innerBits = max(innerBits, 1) + assert innerBits <= 16 + + ored = (ored >> (16 - innerBits)) | (ored & ((1 << innerBits) - 1)) + if ored <= 0x000000FF: + entrySize = 1 + elif ored <= 0x0000FFFF: + entrySize = 2 + elif ored <= 0x00FFFFFF: + entrySize = 3 + else: + entrySize = 4 + + return ((entrySize - 1) << 4) | (innerBits - 1) + + def preWrite(self, font): + mapping = getattr(self, "mapping", None) + if mapping is None: + mapping = self.mapping = [] + self.Format = 1 if len(mapping) > 0xFFFF else 0 + rawTable = self.__dict__.copy() + rawTable["MappingCount"] = len(mapping) + rawTable["EntryFormat"] = self.getEntryFormat(mapping) + return rawTable + + def toXML2(self, xmlWriter, font): + # Make xml dump less verbose, by omitting no-op entries like: + # <Map index="..." outer="65535" inner="65535"/> + xmlWriter.comment("Omitted values default to 0xFFFF/0xFFFF (no variations)") + xmlWriter.newline() + for i, value in enumerate(getattr(self, "mapping", [])): + attrs = [("index", i)] + if value != NO_VARIATION_INDEX: + attrs.extend( + [ + ("outer", value >> 16), + ("inner", value & 0xFFFF), + ] + ) + xmlWriter.simpletag("Map", attrs) + xmlWriter.newline() + + def fromXML(self, name, attrs, content, font): + mapping = getattr(self, "mapping", None) + if mapping is None: + self.mapping = mapping = [] + index = safeEval(attrs["index"]) + outer = safeEval(attrs.get("outer", "0xFFFF")) + inner = safeEval(attrs.get("inner", "0xFFFF")) + assert inner <= 0xFFFF + mapping.insert(index, (outer << 16) | inner) + + def __getitem__(self, i): + return self.mapping[i] if i < len(self.mapping) else NO_VARIATION_INDEX + + +class VarIdxMap(BaseTable): + def populateDefaults(self, propagator=None): + if not hasattr(self, "mapping"): + self.mapping = {} + + def postRead(self, rawTable, font): + assert (rawTable["EntryFormat"] & 0xFFC0) == 0 + glyphOrder = font.getGlyphOrder() + mapList = rawTable["mapping"] + mapList.extend([mapList[-1]] * (len(glyphOrder) - len(mapList))) + self.mapping = dict(zip(glyphOrder, mapList)) + + def preWrite(self, font): + mapping = getattr(self, "mapping", None) + if mapping is None: + mapping = self.mapping = {} + + glyphOrder = font.getGlyphOrder() + mapping = [mapping[g] for g in glyphOrder] + while len(mapping) > 1 and mapping[-2] == mapping[-1]: + del mapping[-1] + + rawTable = {"mapping": mapping} + rawTable["MappingCount"] = len(mapping) + rawTable["EntryFormat"] = DeltaSetIndexMap.getEntryFormat(mapping) + return rawTable + + def toXML2(self, xmlWriter, font): + for glyph, value in sorted(getattr(self, "mapping", {}).items()): + attrs = ( + ("glyph", glyph), + ("outer", value >> 16), + ("inner", value & 0xFFFF), + ) + xmlWriter.simpletag("Map", attrs) + xmlWriter.newline() + + def fromXML(self, name, attrs, content, font): + mapping = getattr(self, "mapping", None) + if mapping is None: + mapping = {} + self.mapping = mapping + try: + glyph = attrs["glyph"] + except: # https://github.com/fonttools/fonttools/commit/21cbab8ce9ded3356fef3745122da64dcaf314e9#commitcomment-27649836 + glyph = font.getGlyphOrder()[attrs["index"]] + outer = safeEval(attrs["outer"]) + inner = safeEval(attrs["inner"]) + assert inner <= 0xFFFF + mapping[glyph] = (outer << 16) | inner + + def __getitem__(self, glyphName): + return self.mapping.get(glyphName, NO_VARIATION_INDEX) + + +class VarRegionList(BaseTable): + def preWrite(self, font): + # The OT spec says VarStore.VarRegionList.RegionAxisCount should always + # be equal to the fvar.axisCount, and OTS < v8.0.0 enforces this rule + # even when the VarRegionList is empty. We can't treat RegionAxisCount + # like a normal propagated count (== len(Region[i].VarRegionAxis)), + # otherwise it would default to 0 if VarRegionList is empty. + # Thus, we force it to always be equal to fvar.axisCount. + # https://github.com/khaledhosny/ots/pull/192 + fvarTable = font.get("fvar") + if fvarTable: + self.RegionAxisCount = len(fvarTable.axes) + return { + **self.__dict__, + "RegionAxisCount": CountReference(self.__dict__, "RegionAxisCount"), + } + + +class SingleSubst(FormatSwitchingBaseTable): + def populateDefaults(self, propagator=None): + if not hasattr(self, "mapping"): + self.mapping = {} + + def postRead(self, rawTable, font): + mapping = {} + input = _getGlyphsFromCoverageTable(rawTable["Coverage"]) + if self.Format == 1: + delta = rawTable["DeltaGlyphID"] + inputGIDS = font.getGlyphIDMany(input) + outGIDS = [(glyphID + delta) % 65536 for glyphID in inputGIDS] + outNames = font.getGlyphNameMany(outGIDS) + for inp, out in zip(input, outNames): + mapping[inp] = out + elif self.Format == 2: + assert ( + len(input) == rawTable["GlyphCount"] + ), "invalid SingleSubstFormat2 table" + subst = rawTable["Substitute"] + for inp, sub in zip(input, subst): + mapping[inp] = sub + else: + assert 0, "unknown format: %s" % self.Format + self.mapping = mapping + del self.Format # Don't need this anymore + + def preWrite(self, font): + mapping = getattr(self, "mapping", None) + if mapping is None: + mapping = self.mapping = {} + items = list(mapping.items()) + getGlyphID = font.getGlyphID + gidItems = [(getGlyphID(a), getGlyphID(b)) for a, b in items] + sortableItems = sorted(zip(gidItems, items)) + + # figure out format + format = 2 + delta = None + for inID, outID in gidItems: + if delta is None: + delta = (outID - inID) % 65536 + + if (inID + delta) % 65536 != outID: + break + else: + if delta is None: + # the mapping is empty, better use format 2 + format = 2 + else: + format = 1 + + rawTable = {} + self.Format = format + cov = Coverage() + input = [item[1][0] for item in sortableItems] + subst = [item[1][1] for item in sortableItems] + cov.glyphs = input + rawTable["Coverage"] = cov + if format == 1: + assert delta is not None + rawTable["DeltaGlyphID"] = delta + else: + rawTable["Substitute"] = subst + return rawTable + + def toXML2(self, xmlWriter, font): + items = sorted(self.mapping.items()) + for inGlyph, outGlyph in items: + xmlWriter.simpletag("Substitution", [("in", inGlyph), ("out", outGlyph)]) + xmlWriter.newline() + + def fromXML(self, name, attrs, content, font): + mapping = getattr(self, "mapping", None) + if mapping is None: + mapping = {} + self.mapping = mapping + mapping[attrs["in"]] = attrs["out"] + + +class MultipleSubst(FormatSwitchingBaseTable): + def populateDefaults(self, propagator=None): + if not hasattr(self, "mapping"): + self.mapping = {} + + def postRead(self, rawTable, font): + mapping = {} + if self.Format == 1: + glyphs = _getGlyphsFromCoverageTable(rawTable["Coverage"]) + subst = [s.Substitute for s in rawTable["Sequence"]] + mapping = dict(zip(glyphs, subst)) + else: + assert 0, "unknown format: %s" % self.Format + self.mapping = mapping + del self.Format # Don't need this anymore + + def preWrite(self, font): + mapping = getattr(self, "mapping", None) + if mapping is None: + mapping = self.mapping = {} + cov = Coverage() + cov.glyphs = sorted(list(mapping.keys()), key=font.getGlyphID) + self.Format = 1 + rawTable = { + "Coverage": cov, + "Sequence": [self.makeSequence_(mapping[glyph]) for glyph in cov.glyphs], + } + return rawTable + + def toXML2(self, xmlWriter, font): + items = sorted(self.mapping.items()) + for inGlyph, outGlyphs in items: + out = ",".join(outGlyphs) + xmlWriter.simpletag("Substitution", [("in", inGlyph), ("out", out)]) + xmlWriter.newline() + + def fromXML(self, name, attrs, content, font): + mapping = getattr(self, "mapping", None) + if mapping is None: + mapping = {} + self.mapping = mapping + + # TTX v3.0 and earlier. + if name == "Coverage": + self.old_coverage_ = [] + for element in content: + if not isinstance(element, tuple): + continue + element_name, element_attrs, _ = element + if element_name == "Glyph": + self.old_coverage_.append(element_attrs["value"]) + return + if name == "Sequence": + index = int(attrs.get("index", len(mapping))) + glyph = self.old_coverage_[index] + glyph_mapping = mapping[glyph] = [] + for element in content: + if not isinstance(element, tuple): + continue + element_name, element_attrs, _ = element + if element_name == "Substitute": + glyph_mapping.append(element_attrs["value"]) + return + + # TTX v3.1 and later. + outGlyphs = attrs["out"].split(",") if attrs["out"] else [] + mapping[attrs["in"]] = [g.strip() for g in outGlyphs] + + @staticmethod + def makeSequence_(g): + seq = Sequence() + seq.Substitute = g + return seq + + +class ClassDef(FormatSwitchingBaseTable): + def populateDefaults(self, propagator=None): + if not hasattr(self, "classDefs"): + self.classDefs = {} + + def postRead(self, rawTable, font): + classDefs = {} + + if self.Format == 1: + start = rawTable["StartGlyph"] + classList = rawTable["ClassValueArray"] + startID = font.getGlyphID(start) + endID = startID + len(classList) + glyphNames = font.getGlyphNameMany(range(startID, endID)) + for glyphName, cls in zip(glyphNames, classList): + if cls: + classDefs[glyphName] = cls + + elif self.Format == 2: + records = rawTable["ClassRangeRecord"] + for rec in records: + cls = rec.Class + if not cls: + continue + start = rec.Start + end = rec.End + startID = font.getGlyphID(start) + endID = font.getGlyphID(end) + 1 + glyphNames = font.getGlyphNameMany(range(startID, endID)) + for glyphName in glyphNames: + classDefs[glyphName] = cls + else: + log.warning("Unknown ClassDef format: %s", self.Format) + self.classDefs = classDefs + del self.Format # Don't need this anymore + + def _getClassRanges(self, font): + classDefs = getattr(self, "classDefs", None) + if classDefs is None: + self.classDefs = {} + return + getGlyphID = font.getGlyphID + items = [] + for glyphName, cls in classDefs.items(): + if not cls: + continue + items.append((getGlyphID(glyphName), glyphName, cls)) + if items: + items.sort() + last, lastName, lastCls = items[0] + ranges = [[lastCls, last, lastName]] + for glyphID, glyphName, cls in items[1:]: + if glyphID != last + 1 or cls != lastCls: + ranges[-1].extend([last, lastName]) + ranges.append([cls, glyphID, glyphName]) + last = glyphID + lastName = glyphName + lastCls = cls + ranges[-1].extend([last, lastName]) + return ranges + + def preWrite(self, font): + format = 2 + rawTable = {"ClassRangeRecord": []} + ranges = self._getClassRanges(font) + if ranges: + startGlyph = ranges[0][1] + endGlyph = ranges[-1][3] + glyphCount = endGlyph - startGlyph + 1 + if len(ranges) * 3 < glyphCount + 1: + # Format 2 is more compact + for i, (cls, start, startName, end, endName) in enumerate(ranges): + rec = ClassRangeRecord() + rec.Start = startName + rec.End = endName + rec.Class = cls + ranges[i] = rec + format = 2 + rawTable = {"ClassRangeRecord": ranges} + else: + # Format 1 is more compact + startGlyphName = ranges[0][2] + classes = [0] * glyphCount + for cls, start, startName, end, endName in ranges: + for g in range(start - startGlyph, end - startGlyph + 1): + classes[g] = cls + format = 1 + rawTable = {"StartGlyph": startGlyphName, "ClassValueArray": classes} + self.Format = format + return rawTable + + def toXML2(self, xmlWriter, font): + items = sorted(self.classDefs.items()) + for glyphName, cls in items: + xmlWriter.simpletag("ClassDef", [("glyph", glyphName), ("class", cls)]) + xmlWriter.newline() + + def fromXML(self, name, attrs, content, font): + classDefs = getattr(self, "classDefs", None) + if classDefs is None: + classDefs = {} + self.classDefs = classDefs + classDefs[attrs["glyph"]] = int(attrs["class"]) + + +class AlternateSubst(FormatSwitchingBaseTable): + def populateDefaults(self, propagator=None): + if not hasattr(self, "alternates"): + self.alternates = {} + + def postRead(self, rawTable, font): + alternates = {} + if self.Format == 1: + input = _getGlyphsFromCoverageTable(rawTable["Coverage"]) + alts = rawTable["AlternateSet"] + assert len(input) == len(alts) + for inp, alt in zip(input, alts): + alternates[inp] = alt.Alternate + else: + assert 0, "unknown format: %s" % self.Format + self.alternates = alternates + del self.Format # Don't need this anymore + + def preWrite(self, font): + self.Format = 1 + alternates = getattr(self, "alternates", None) + if alternates is None: + alternates = self.alternates = {} + items = list(alternates.items()) + for i, (glyphName, set) in enumerate(items): + items[i] = font.getGlyphID(glyphName), glyphName, set + items.sort() + cov = Coverage() + cov.glyphs = [item[1] for item in items] + alternates = [] + setList = [item[-1] for item in items] + for set in setList: + alts = AlternateSet() + alts.Alternate = set + alternates.append(alts) + # a special case to deal with the fact that several hundred Adobe Japan1-5 + # CJK fonts will overflow an offset if the coverage table isn't pushed to the end. + # Also useful in that when splitting a sub-table because of an offset overflow + # I don't need to calculate the change in the subtable offset due to the change in the coverage table size. + # Allows packing more rules in subtable. + self.sortCoverageLast = 1 + return {"Coverage": cov, "AlternateSet": alternates} + + def toXML2(self, xmlWriter, font): + items = sorted(self.alternates.items()) + for glyphName, alternates in items: + xmlWriter.begintag("AlternateSet", glyph=glyphName) + xmlWriter.newline() + for alt in alternates: + xmlWriter.simpletag("Alternate", glyph=alt) + xmlWriter.newline() + xmlWriter.endtag("AlternateSet") + xmlWriter.newline() + + def fromXML(self, name, attrs, content, font): + alternates = getattr(self, "alternates", None) + if alternates is None: + alternates = {} + self.alternates = alternates + glyphName = attrs["glyph"] + set = [] + alternates[glyphName] = set + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + set.append(attrs["glyph"]) + + +class LigatureSubst(FormatSwitchingBaseTable): + def populateDefaults(self, propagator=None): + if not hasattr(self, "ligatures"): + self.ligatures = {} + + def postRead(self, rawTable, font): + ligatures = {} + if self.Format == 1: + input = _getGlyphsFromCoverageTable(rawTable["Coverage"]) + ligSets = rawTable["LigatureSet"] + assert len(input) == len(ligSets) + for i, inp in enumerate(input): + ligatures[inp] = ligSets[i].Ligature + else: + assert 0, "unknown format: %s" % self.Format + self.ligatures = ligatures + del self.Format # Don't need this anymore + + @staticmethod + def _getLigatureSortKey(components): + # Computes a key for ordering ligatures in a GSUB Type-4 lookup. + + # When building the OpenType lookup, we need to make sure that + # the longest sequence of components is listed first, so we + # use the negative length as the key for sorting. + # Note, we no longer need to worry about deterministic order because the + # ligature mapping `dict` remembers the insertion order, and this in + # turn depends on the order in which the ligatures are written in the FEA. + # Since python sort algorithm is stable, the ligatures of equal length + # will keep the relative order in which they appear in the feature file. + # For example, given the following ligatures (all starting with 'f' and + # thus belonging to the same LigatureSet): + # + # feature liga { + # sub f i by f_i; + # sub f f f by f_f_f; + # sub f f by f_f; + # sub f f i by f_f_i; + # } liga; + # + # this should sort to: f_f_f, f_f_i, f_i, f_f + # This is also what fea-rs does, see: + # https://github.com/adobe-type-tools/afdko/issues/1727 + # https://github.com/fonttools/fonttools/issues/3428 + # https://github.com/googlefonts/fontc/pull/680 + return -len(components) + + def preWrite(self, font): + self.Format = 1 + ligatures = getattr(self, "ligatures", None) + if ligatures is None: + ligatures = self.ligatures = {} + + if ligatures and isinstance(next(iter(ligatures)), tuple): + # New high-level API in v3.1 and later. Note that we just support compiling this + # for now. We don't load to this API, and don't do XML with it. + + # ligatures is map from components-sequence to lig-glyph + newLigatures = dict() + for comps in sorted(ligatures.keys(), key=self._getLigatureSortKey): + ligature = Ligature() + ligature.Component = comps[1:] + ligature.CompCount = len(comps) + ligature.LigGlyph = ligatures[comps] + newLigatures.setdefault(comps[0], []).append(ligature) + ligatures = newLigatures + + items = list(ligatures.items()) + for i, (glyphName, set) in enumerate(items): + items[i] = font.getGlyphID(glyphName), glyphName, set + items.sort() + cov = Coverage() + cov.glyphs = [item[1] for item in items] + + ligSets = [] + setList = [item[-1] for item in items] + for set in setList: + ligSet = LigatureSet() + ligs = ligSet.Ligature = [] + for lig in set: + ligs.append(lig) + ligSets.append(ligSet) + # Useful in that when splitting a sub-table because of an offset overflow + # I don't need to calculate the change in subtabl offset due to the coverage table size. + # Allows packing more rules in subtable. + self.sortCoverageLast = 1 + return {"Coverage": cov, "LigatureSet": ligSets} + + def toXML2(self, xmlWriter, font): + items = sorted(self.ligatures.items()) + for glyphName, ligSets in items: + xmlWriter.begintag("LigatureSet", glyph=glyphName) + xmlWriter.newline() + for lig in ligSets: + xmlWriter.simpletag( + "Ligature", glyph=lig.LigGlyph, components=",".join(lig.Component) + ) + xmlWriter.newline() + xmlWriter.endtag("LigatureSet") + xmlWriter.newline() + + def fromXML(self, name, attrs, content, font): + ligatures = getattr(self, "ligatures", None) + if ligatures is None: + ligatures = {} + self.ligatures = ligatures + glyphName = attrs["glyph"] + ligs = [] + ligatures[glyphName] = ligs + for element in content: + if not isinstance(element, tuple): + continue + name, attrs, content = element + lig = Ligature() + lig.LigGlyph = attrs["glyph"] + components = attrs["components"] + lig.Component = components.split(",") if components else [] + lig.CompCount = len(lig.Component) + ligs.append(lig) + + +class COLR(BaseTable): + def decompile(self, reader, font): + # COLRv0 is exceptional in that LayerRecordCount appears *after* the + # LayerRecordArray it counts, but the parser logic expects Count fields + # to always precede the arrays. Here we work around this by parsing the + # LayerRecordCount before the rest of the table, and storing it in + # the reader's local state. + subReader = reader.getSubReader(offset=0) + for conv in self.getConverters(): + if conv.name != "LayerRecordCount": + subReader.advance(conv.staticSize) + continue + reader[conv.name] = conv.read(subReader, font, tableDict={}) + break + else: + raise AssertionError("LayerRecordCount converter not found") + return BaseTable.decompile(self, reader, font) + + def preWrite(self, font): + # The writer similarly assumes Count values precede the things counted, + # thus here we pre-initialize a CountReference; the actual count value + # will be set to the lenght of the array by the time this is assembled. + self.LayerRecordCount = None + return { + **self.__dict__, + "LayerRecordCount": CountReference(self.__dict__, "LayerRecordCount"), + } + + def computeClipBoxes(self, glyphSet: "_TTGlyphSet", quantization: int = 1): + if self.Version == 0: + return + + clips = {} + for rec in self.BaseGlyphList.BaseGlyphPaintRecord: + try: + clipBox = rec.Paint.computeClipBox(self, glyphSet, quantization) + except Exception as e: + from fontTools.ttLib import TTLibError + + raise TTLibError( + f"Failed to compute COLR ClipBox for {rec.BaseGlyph!r}" + ) from e + + if clipBox is not None: + clips[rec.BaseGlyph] = clipBox + + hasClipList = hasattr(self, "ClipList") and self.ClipList is not None + if not clips: + if hasClipList: + self.ClipList = None + else: + if not hasClipList: + self.ClipList = ClipList() + self.ClipList.Format = 1 + self.ClipList.clips = clips + + +class LookupList(BaseTable): + @property + def table(self): + for l in self.Lookup: + for st in l.SubTable: + if type(st).__name__.endswith("Subst"): + return "GSUB" + if type(st).__name__.endswith("Pos"): + return "GPOS" + raise ValueError + + def toXML2(self, xmlWriter, font): + if ( + not font + or "Debg" not in font + or LOOKUP_DEBUG_INFO_KEY not in font["Debg"].data + ): + return super().toXML2(xmlWriter, font) + debugData = font["Debg"].data[LOOKUP_DEBUG_INFO_KEY][self.table] + for conv in self.getConverters(): + if conv.repeat: + value = getattr(self, conv.name, []) + for lookupIndex, item in enumerate(value): + if str(lookupIndex) in debugData: + info = LookupDebugInfo(*debugData[str(lookupIndex)]) + tag = info.location + if info.name: + tag = f"{info.name}: {tag}" + if info.feature: + script, language, feature = info.feature + tag = f"{tag} in {feature} ({script}/{language})" + xmlWriter.comment(tag) + xmlWriter.newline() + + conv.xmlWrite( + xmlWriter, font, item, conv.name, [("index", lookupIndex)] + ) + else: + if conv.aux and not eval(conv.aux, None, vars(self)): + continue + value = getattr( + self, conv.name, None + ) # TODO Handle defaults instead of defaulting to None! + conv.xmlWrite(xmlWriter, font, value, conv.name, []) + + +class BaseGlyphRecordArray(BaseTable): + def preWrite(self, font): + self.BaseGlyphRecord = sorted( + self.BaseGlyphRecord, key=lambda rec: font.getGlyphID(rec.BaseGlyph) + ) + return self.__dict__.copy() + + +class BaseGlyphList(BaseTable): + def preWrite(self, font): + self.BaseGlyphPaintRecord = sorted( + self.BaseGlyphPaintRecord, key=lambda rec: font.getGlyphID(rec.BaseGlyph) + ) + return self.__dict__.copy() + + +class ClipBoxFormat(IntEnum): + Static = 1 + Variable = 2 + + def is_variable(self): + return self is self.Variable + + def as_variable(self): + return self.Variable + + +class ClipBox(getFormatSwitchingBaseTableClass("uint8")): + formatEnum = ClipBoxFormat + + def as_tuple(self): + return tuple(getattr(self, conv.name) for conv in self.getConverters()) + + def __repr__(self): + return f"{self.__class__.__name__}{self.as_tuple()}" + + +class ClipList(getFormatSwitchingBaseTableClass("uint8")): + def populateDefaults(self, propagator=None): + if not hasattr(self, "clips"): + self.clips = {} + + def postRead(self, rawTable, font): + clips = {} + glyphOrder = font.getGlyphOrder() + for i, rec in enumerate(rawTable["ClipRecord"]): + if rec.StartGlyphID > rec.EndGlyphID: + log.warning( + "invalid ClipRecord[%i].StartGlyphID (%i) > " + "EndGlyphID (%i); skipped", + i, + rec.StartGlyphID, + rec.EndGlyphID, + ) + continue + redefinedGlyphs = [] + missingGlyphs = [] + for glyphID in range(rec.StartGlyphID, rec.EndGlyphID + 1): + try: + glyph = glyphOrder[glyphID] + except IndexError: + missingGlyphs.append(glyphID) + continue + if glyph not in clips: + clips[glyph] = copy.copy(rec.ClipBox) + else: + redefinedGlyphs.append(glyphID) + if redefinedGlyphs: + log.warning( + "ClipRecord[%i] overlaps previous records; " + "ignoring redefined clip boxes for the " + "following glyph ID range: [%i-%i]", + i, + min(redefinedGlyphs), + max(redefinedGlyphs), + ) + if missingGlyphs: + log.warning( + "ClipRecord[%i] range references missing " "glyph IDs: [%i-%i]", + i, + min(missingGlyphs), + max(missingGlyphs), + ) + self.clips = clips + + def groups(self): + glyphsByClip = defaultdict(list) + uniqueClips = {} + for glyphName, clipBox in self.clips.items(): + key = clipBox.as_tuple() + glyphsByClip[key].append(glyphName) + if key not in uniqueClips: + uniqueClips[key] = clipBox + return { + frozenset(glyphs): uniqueClips[key] for key, glyphs in glyphsByClip.items() + } + + def preWrite(self, font): + if not hasattr(self, "clips"): + self.clips = {} + clipBoxRanges = {} + glyphMap = font.getReverseGlyphMap() + for glyphs, clipBox in self.groups().items(): + glyphIDs = sorted( + glyphMap[glyphName] for glyphName in glyphs if glyphName in glyphMap + ) + if not glyphIDs: + continue + last = glyphIDs[0] + ranges = [[last]] + for glyphID in glyphIDs[1:]: + if glyphID != last + 1: + ranges[-1].append(last) + ranges.append([glyphID]) + last = glyphID + ranges[-1].append(last) + for start, end in ranges: + assert (start, end) not in clipBoxRanges + clipBoxRanges[(start, end)] = clipBox + + clipRecords = [] + for (start, end), clipBox in sorted(clipBoxRanges.items()): + record = ClipRecord() + record.StartGlyphID = start + record.EndGlyphID = end + record.ClipBox = clipBox + clipRecords.append(record) + rawTable = { + "ClipCount": len(clipRecords), + "ClipRecord": clipRecords, + } + return rawTable + + def toXML(self, xmlWriter, font, attrs=None, name=None): + tableName = name if name else self.__class__.__name__ + if attrs is None: + attrs = [] + if hasattr(self, "Format"): + attrs.append(("Format", self.Format)) + xmlWriter.begintag(tableName, attrs) + xmlWriter.newline() + # sort clips alphabetically to ensure deterministic XML dump + for glyphs, clipBox in sorted( + self.groups().items(), key=lambda item: min(item[0]) + ): + xmlWriter.begintag("Clip") + xmlWriter.newline() + for glyphName in sorted(glyphs): + xmlWriter.simpletag("Glyph", value=glyphName) + xmlWriter.newline() + xmlWriter.begintag("ClipBox", [("Format", clipBox.Format)]) + xmlWriter.newline() + clipBox.toXML2(xmlWriter, font) + xmlWriter.endtag("ClipBox") + xmlWriter.newline() + xmlWriter.endtag("Clip") + xmlWriter.newline() + xmlWriter.endtag(tableName) + xmlWriter.newline() + + def fromXML(self, name, attrs, content, font): + clips = getattr(self, "clips", None) + if clips is None: + self.clips = clips = {} + assert name == "Clip" + glyphs = [] + clipBox = None + for elem in content: + if not isinstance(elem, tuple): + continue + name, attrs, content = elem + if name == "Glyph": + glyphs.append(attrs["value"]) + elif name == "ClipBox": + clipBox = ClipBox() + clipBox.Format = safeEval(attrs["Format"]) + for elem in content: + if not isinstance(elem, tuple): + continue + name, attrs, content = elem + clipBox.fromXML(name, attrs, content, font) + if clipBox: + for glyphName in glyphs: + clips[glyphName] = clipBox + + +class ExtendMode(IntEnum): + PAD = 0 + REPEAT = 1 + REFLECT = 2 + + +# Porter-Duff modes for COLRv1 PaintComposite: +# https://github.com/googlefonts/colr-gradients-spec/tree/off_sub_1#compositemode-enumeration +class CompositeMode(IntEnum): + CLEAR = 0 + SRC = 1 + DEST = 2 + SRC_OVER = 3 + DEST_OVER = 4 + SRC_IN = 5 + DEST_IN = 6 + SRC_OUT = 7 + DEST_OUT = 8 + SRC_ATOP = 9 + DEST_ATOP = 10 + XOR = 11 + PLUS = 12 + SCREEN = 13 + OVERLAY = 14 + DARKEN = 15 + LIGHTEN = 16 + COLOR_DODGE = 17 + COLOR_BURN = 18 + HARD_LIGHT = 19 + SOFT_LIGHT = 20 + DIFFERENCE = 21 + EXCLUSION = 22 + MULTIPLY = 23 + HSL_HUE = 24 + HSL_SATURATION = 25 + HSL_COLOR = 26 + HSL_LUMINOSITY = 27 + + +class PaintFormat(IntEnum): + PaintColrLayers = 1 + PaintSolid = 2 + PaintVarSolid = 3 + PaintLinearGradient = 4 + PaintVarLinearGradient = 5 + PaintRadialGradient = 6 + PaintVarRadialGradient = 7 + PaintSweepGradient = 8 + PaintVarSweepGradient = 9 + PaintGlyph = 10 + PaintColrGlyph = 11 + PaintTransform = 12 + PaintVarTransform = 13 + PaintTranslate = 14 + PaintVarTranslate = 15 + PaintScale = 16 + PaintVarScale = 17 + PaintScaleAroundCenter = 18 + PaintVarScaleAroundCenter = 19 + PaintScaleUniform = 20 + PaintVarScaleUniform = 21 + PaintScaleUniformAroundCenter = 22 + PaintVarScaleUniformAroundCenter = 23 + PaintRotate = 24 + PaintVarRotate = 25 + PaintRotateAroundCenter = 26 + PaintVarRotateAroundCenter = 27 + PaintSkew = 28 + PaintVarSkew = 29 + PaintSkewAroundCenter = 30 + PaintVarSkewAroundCenter = 31 + PaintComposite = 32 + + def is_variable(self): + return self.name.startswith("PaintVar") + + def as_variable(self): + if self.is_variable(): + return self + try: + return PaintFormat.__members__[f"PaintVar{self.name[5:]}"] + except KeyError: + return None + + +class Paint(getFormatSwitchingBaseTableClass("uint8")): + formatEnum = PaintFormat + + def getFormatName(self): + try: + return self.formatEnum(self.Format).name + except ValueError: + raise NotImplementedError(f"Unknown Paint format: {self.Format}") + + def toXML(self, xmlWriter, font, attrs=None, name=None): + tableName = name if name else self.__class__.__name__ + if attrs is None: + attrs = [] + attrs.append(("Format", self.Format)) + xmlWriter.begintag(tableName, attrs) + xmlWriter.comment(self.getFormatName()) + xmlWriter.newline() + self.toXML2(xmlWriter, font) + xmlWriter.endtag(tableName) + xmlWriter.newline() + + def iterPaintSubTables(self, colr: COLR) -> Iterator[BaseTable.SubTableEntry]: + if self.Format == PaintFormat.PaintColrLayers: + # https://github.com/fonttools/fonttools/issues/2438: don't die when no LayerList exists + layers = [] + if colr.LayerList is not None: + layers = colr.LayerList.Paint + yield from ( + BaseTable.SubTableEntry(name="Layers", value=v, index=i) + for i, v in enumerate( + layers[self.FirstLayerIndex : self.FirstLayerIndex + self.NumLayers] + ) + ) + return + + if self.Format == PaintFormat.PaintColrGlyph: + for record in colr.BaseGlyphList.BaseGlyphPaintRecord: + if record.BaseGlyph == self.Glyph: + yield BaseTable.SubTableEntry(name="BaseGlyph", value=record.Paint) + return + else: + raise KeyError(f"{self.Glyph!r} not in colr.BaseGlyphList") + + for conv in self.getConverters(): + if conv.tableClass is not None and issubclass(conv.tableClass, type(self)): + value = getattr(self, conv.name) + yield BaseTable.SubTableEntry(name=conv.name, value=value) + + def getChildren(self, colr) -> List["Paint"]: + # this is kept for backward compatibility (e.g. it's used by the subsetter) + return [p.value for p in self.iterPaintSubTables(colr)] + + def traverse(self, colr: COLR, callback): + """Depth-first traversal of graph rooted at self, callback on each node.""" + if not callable(callback): + raise TypeError("callback must be callable") + + for path in dfs_base_table( + self, iter_subtables_fn=lambda paint: paint.iterPaintSubTables(colr) + ): + paint = path[-1].value + callback(paint) + + def getTransform(self) -> Transform: + if self.Format == PaintFormat.PaintTransform: + t = self.Transform + return Transform(t.xx, t.yx, t.xy, t.yy, t.dx, t.dy) + elif self.Format == PaintFormat.PaintTranslate: + return Identity.translate(self.dx, self.dy) + elif self.Format == PaintFormat.PaintScale: + return Identity.scale(self.scaleX, self.scaleY) + elif self.Format == PaintFormat.PaintScaleAroundCenter: + return ( + Identity.translate(self.centerX, self.centerY) + .scale(self.scaleX, self.scaleY) + .translate(-self.centerX, -self.centerY) + ) + elif self.Format == PaintFormat.PaintScaleUniform: + return Identity.scale(self.scale) + elif self.Format == PaintFormat.PaintScaleUniformAroundCenter: + return ( + Identity.translate(self.centerX, self.centerY) + .scale(self.scale) + .translate(-self.centerX, -self.centerY) + ) + elif self.Format == PaintFormat.PaintRotate: + return Identity.rotate(radians(self.angle)) + elif self.Format == PaintFormat.PaintRotateAroundCenter: + return ( + Identity.translate(self.centerX, self.centerY) + .rotate(radians(self.angle)) + .translate(-self.centerX, -self.centerY) + ) + elif self.Format == PaintFormat.PaintSkew: + return Identity.skew(radians(-self.xSkewAngle), radians(self.ySkewAngle)) + elif self.Format == PaintFormat.PaintSkewAroundCenter: + return ( + Identity.translate(self.centerX, self.centerY) + .skew(radians(-self.xSkewAngle), radians(self.ySkewAngle)) + .translate(-self.centerX, -self.centerY) + ) + if PaintFormat(self.Format).is_variable(): + raise NotImplementedError(f"Variable Paints not supported: {self.Format}") + + return Identity + + def computeClipBox( + self, colr: COLR, glyphSet: "_TTGlyphSet", quantization: int = 1 + ) -> Optional[ClipBox]: + pen = ControlBoundsPen(glyphSet) + for path in dfs_base_table( + self, iter_subtables_fn=lambda paint: paint.iterPaintSubTables(colr) + ): + paint = path[-1].value + if paint.Format == PaintFormat.PaintGlyph: + transformation = reduce( + Transform.transform, + (st.value.getTransform() for st in path), + Identity, + ) + glyphSet[paint.Glyph].draw(TransformPen(pen, transformation)) + + if pen.bounds is None: + return None + + cb = ClipBox() + cb.Format = int(ClipBoxFormat.Static) + cb.xMin, cb.yMin, cb.xMax, cb.yMax = quantizeRect(pen.bounds, quantization) + return cb + + +# For each subtable format there is a class. However, we don't really distinguish +# between "field name" and "format name": often these are the same. Yet there's +# a whole bunch of fields with different names. The following dict is a mapping +# from "format name" to "field name". _buildClasses() uses this to create a +# subclass for each alternate field name. +# +_equivalents = { + "MarkArray": ("Mark1Array",), + "LangSys": ("DefaultLangSys",), + "Coverage": ( + "MarkCoverage", + "BaseCoverage", + "LigatureCoverage", + "Mark1Coverage", + "Mark2Coverage", + "BacktrackCoverage", + "InputCoverage", + "LookAheadCoverage", + "VertGlyphCoverage", + "HorizGlyphCoverage", + "TopAccentCoverage", + "ExtendedShapeCoverage", + "MathKernCoverage", + ), + "ClassDef": ( + "ClassDef1", + "ClassDef2", + "BacktrackClassDef", + "InputClassDef", + "LookAheadClassDef", + "GlyphClassDef", + "MarkAttachClassDef", + ), + "Anchor": ( + "EntryAnchor", + "ExitAnchor", + "BaseAnchor", + "LigatureAnchor", + "Mark2Anchor", + "MarkAnchor", + ), + "Device": ( + "XPlaDevice", + "YPlaDevice", + "XAdvDevice", + "YAdvDevice", + "XDeviceTable", + "YDeviceTable", + "DeviceTable", + ), + "Axis": ( + "HorizAxis", + "VertAxis", + ), + "MinMax": ("DefaultMinMax",), + "BaseCoord": ( + "MinCoord", + "MaxCoord", + ), + "JstfLangSys": ("DefJstfLangSys",), + "JstfGSUBModList": ( + "ShrinkageEnableGSUB", + "ShrinkageDisableGSUB", + "ExtensionEnableGSUB", + "ExtensionDisableGSUB", + ), + "JstfGPOSModList": ( + "ShrinkageEnableGPOS", + "ShrinkageDisableGPOS", + "ExtensionEnableGPOS", + "ExtensionDisableGPOS", + ), + "JstfMax": ( + "ShrinkageJstfMax", + "ExtensionJstfMax", + ), + "MathKern": ( + "TopRightMathKern", + "TopLeftMathKern", + "BottomRightMathKern", + "BottomLeftMathKern", + ), + "MathGlyphConstruction": ("VertGlyphConstruction", "HorizGlyphConstruction"), +} + +# +# OverFlow logic, to automatically create ExtensionLookups +# XXX This should probably move to otBase.py +# + + +def fixLookupOverFlows(ttf, overflowRecord): + """Either the offset from the LookupList to a lookup overflowed, or + an offset from a lookup to a subtable overflowed. + + The table layout is:: + + GPSO/GUSB + Script List + Feature List + LookUpList + Lookup[0] and contents + SubTable offset list + SubTable[0] and contents + ... + SubTable[n] and contents + ... + Lookup[n] and contents + SubTable offset list + SubTable[0] and contents + ... + SubTable[n] and contents + + If the offset to a lookup overflowed (SubTableIndex is None) + we must promote the *previous* lookup to an Extension type. + + If the offset from a lookup to subtable overflowed, then we must promote it + to an Extension Lookup type. + """ + ok = 0 + lookupIndex = overflowRecord.LookupListIndex + if overflowRecord.SubTableIndex is None: + lookupIndex = lookupIndex - 1 + if lookupIndex < 0: + return ok + if overflowRecord.tableType == "GSUB": + extType = 7 + elif overflowRecord.tableType == "GPOS": + extType = 9 + + lookups = ttf[overflowRecord.tableType].table.LookupList.Lookup + lookup = lookups[lookupIndex] + # If the previous lookup is an extType, look further back. Very unlikely, but possible. + while lookup.SubTable[0].__class__.LookupType == extType: + lookupIndex = lookupIndex - 1 + if lookupIndex < 0: + return ok + lookup = lookups[lookupIndex] + + for lookupIndex in range(lookupIndex, len(lookups)): + lookup = lookups[lookupIndex] + if lookup.LookupType != extType: + lookup.LookupType = extType + for si, subTable in enumerate(lookup.SubTable): + extSubTableClass = lookupTypes[overflowRecord.tableType][extType] + extSubTable = extSubTableClass() + extSubTable.Format = 1 + extSubTable.ExtSubTable = subTable + lookup.SubTable[si] = extSubTable + ok = 1 + return ok + + +def splitMultipleSubst(oldSubTable, newSubTable, overflowRecord): + ok = 1 + oldMapping = sorted(oldSubTable.mapping.items()) + oldLen = len(oldMapping) + + if overflowRecord.itemName in ["Coverage", "RangeRecord"]: + # Coverage table is written last. Overflow is to or within the + # the coverage table. We will just cut the subtable in half. + newLen = oldLen // 2 + + elif overflowRecord.itemName == "Sequence": + # We just need to back up by two items from the overflowed + # Sequence index to make sure the offset to the Coverage table + # doesn't overflow. + newLen = overflowRecord.itemIndex - 1 + + newSubTable.mapping = {} + for i in range(newLen, oldLen): + item = oldMapping[i] + key = item[0] + newSubTable.mapping[key] = item[1] + del oldSubTable.mapping[key] + + return ok + + +def splitAlternateSubst(oldSubTable, newSubTable, overflowRecord): + ok = 1 + if hasattr(oldSubTable, "sortCoverageLast"): + newSubTable.sortCoverageLast = oldSubTable.sortCoverageLast + + oldAlts = sorted(oldSubTable.alternates.items()) + oldLen = len(oldAlts) + + if overflowRecord.itemName in ["Coverage", "RangeRecord"]: + # Coverage table is written last. overflow is to or within the + # the coverage table. We will just cut the subtable in half. + newLen = oldLen // 2 + + elif overflowRecord.itemName == "AlternateSet": + # We just need to back up by two items + # from the overflowed AlternateSet index to make sure the offset + # to the Coverage table doesn't overflow. + newLen = overflowRecord.itemIndex - 1 + + newSubTable.alternates = {} + for i in range(newLen, oldLen): + item = oldAlts[i] + key = item[0] + newSubTable.alternates[key] = item[1] + del oldSubTable.alternates[key] + + return ok + + +def splitLigatureSubst(oldSubTable, newSubTable, overflowRecord): + ok = 1 + oldLigs = sorted(oldSubTable.ligatures.items()) + oldLen = len(oldLigs) + + if overflowRecord.itemName in ["Coverage", "RangeRecord"]: + # Coverage table is written last. overflow is to or within the + # the coverage table. We will just cut the subtable in half. + newLen = oldLen // 2 + + elif overflowRecord.itemName == "LigatureSet": + # We just need to back up by two items + # from the overflowed AlternateSet index to make sure the offset + # to the Coverage table doesn't overflow. + newLen = overflowRecord.itemIndex - 1 + + newSubTable.ligatures = {} + for i in range(newLen, oldLen): + item = oldLigs[i] + key = item[0] + newSubTable.ligatures[key] = item[1] + del oldSubTable.ligatures[key] + + return ok + + +def splitPairPos(oldSubTable, newSubTable, overflowRecord): + st = oldSubTable + ok = False + newSubTable.Format = oldSubTable.Format + if oldSubTable.Format == 1 and len(oldSubTable.PairSet) > 1: + for name in "ValueFormat1", "ValueFormat2": + setattr(newSubTable, name, getattr(oldSubTable, name)) + + # Move top half of coverage to new subtable + + newSubTable.Coverage = oldSubTable.Coverage.__class__() + + coverage = oldSubTable.Coverage.glyphs + records = oldSubTable.PairSet + + oldCount = len(oldSubTable.PairSet) // 2 + + oldSubTable.Coverage.glyphs = coverage[:oldCount] + oldSubTable.PairSet = records[:oldCount] + + newSubTable.Coverage.glyphs = coverage[oldCount:] + newSubTable.PairSet = records[oldCount:] + + oldSubTable.PairSetCount = len(oldSubTable.PairSet) + newSubTable.PairSetCount = len(newSubTable.PairSet) + + ok = True + + elif oldSubTable.Format == 2 and len(oldSubTable.Class1Record) > 1: + if not hasattr(oldSubTable, "Class2Count"): + oldSubTable.Class2Count = len(oldSubTable.Class1Record[0].Class2Record) + for name in "Class2Count", "ClassDef2", "ValueFormat1", "ValueFormat2": + setattr(newSubTable, name, getattr(oldSubTable, name)) + + # The two subtables will still have the same ClassDef2 and the table + # sharing will still cause the sharing to overflow. As such, disable + # sharing on the one that is serialized second (that's oldSubTable). + oldSubTable.DontShare = True + + # Move top half of class numbers to new subtable + + newSubTable.Coverage = oldSubTable.Coverage.__class__() + newSubTable.ClassDef1 = oldSubTable.ClassDef1.__class__() + + coverage = oldSubTable.Coverage.glyphs + classDefs = oldSubTable.ClassDef1.classDefs + records = oldSubTable.Class1Record + + oldCount = len(oldSubTable.Class1Record) // 2 + newGlyphs = set(k for k, v in classDefs.items() if v >= oldCount) + + oldSubTable.Coverage.glyphs = [g for g in coverage if g not in newGlyphs] + oldSubTable.ClassDef1.classDefs = { + k: v for k, v in classDefs.items() if v < oldCount + } + oldSubTable.Class1Record = records[:oldCount] + + newSubTable.Coverage.glyphs = [g for g in coverage if g in newGlyphs] + newSubTable.ClassDef1.classDefs = { + k: (v - oldCount) for k, v in classDefs.items() if v > oldCount + } + newSubTable.Class1Record = records[oldCount:] + + oldSubTable.Class1Count = len(oldSubTable.Class1Record) + newSubTable.Class1Count = len(newSubTable.Class1Record) + + ok = True + + return ok + + +def splitMarkBasePos(oldSubTable, newSubTable, overflowRecord): + # split half of the mark classes to the new subtable + classCount = oldSubTable.ClassCount + if classCount < 2: + # oh well, not much left to split... + return False + + oldClassCount = classCount // 2 + newClassCount = classCount - oldClassCount + + oldMarkCoverage, oldMarkRecords = [], [] + newMarkCoverage, newMarkRecords = [], [] + for glyphName, markRecord in zip( + oldSubTable.MarkCoverage.glyphs, oldSubTable.MarkArray.MarkRecord + ): + if markRecord.Class < oldClassCount: + oldMarkCoverage.append(glyphName) + oldMarkRecords.append(markRecord) + else: + markRecord.Class -= oldClassCount + newMarkCoverage.append(glyphName) + newMarkRecords.append(markRecord) + + oldBaseRecords, newBaseRecords = [], [] + for rec in oldSubTable.BaseArray.BaseRecord: + oldBaseRecord, newBaseRecord = rec.__class__(), rec.__class__() + oldBaseRecord.BaseAnchor = rec.BaseAnchor[:oldClassCount] + newBaseRecord.BaseAnchor = rec.BaseAnchor[oldClassCount:] + oldBaseRecords.append(oldBaseRecord) + newBaseRecords.append(newBaseRecord) + + newSubTable.Format = oldSubTable.Format + + oldSubTable.MarkCoverage.glyphs = oldMarkCoverage + newSubTable.MarkCoverage = oldSubTable.MarkCoverage.__class__() + newSubTable.MarkCoverage.glyphs = newMarkCoverage + + # share the same BaseCoverage in both halves + newSubTable.BaseCoverage = oldSubTable.BaseCoverage + + oldSubTable.ClassCount = oldClassCount + newSubTable.ClassCount = newClassCount + + oldSubTable.MarkArray.MarkRecord = oldMarkRecords + newSubTable.MarkArray = oldSubTable.MarkArray.__class__() + newSubTable.MarkArray.MarkRecord = newMarkRecords + + oldSubTable.MarkArray.MarkCount = len(oldMarkRecords) + newSubTable.MarkArray.MarkCount = len(newMarkRecords) + + oldSubTable.BaseArray.BaseRecord = oldBaseRecords + newSubTable.BaseArray = oldSubTable.BaseArray.__class__() + newSubTable.BaseArray.BaseRecord = newBaseRecords + + oldSubTable.BaseArray.BaseCount = len(oldBaseRecords) + newSubTable.BaseArray.BaseCount = len(newBaseRecords) + + return True + + +splitTable = { + "GSUB": { + # 1: splitSingleSubst, + 2: splitMultipleSubst, + 3: splitAlternateSubst, + 4: splitLigatureSubst, + # 5: splitContextSubst, + # 6: splitChainContextSubst, + # 7: splitExtensionSubst, + # 8: splitReverseChainSingleSubst, + }, + "GPOS": { + # 1: splitSinglePos, + 2: splitPairPos, + # 3: splitCursivePos, + 4: splitMarkBasePos, + # 5: splitMarkLigPos, + # 6: splitMarkMarkPos, + # 7: splitContextPos, + # 8: splitChainContextPos, + # 9: splitExtensionPos, + }, +} + + +def fixSubTableOverFlows(ttf, overflowRecord): + """ + An offset has overflowed within a sub-table. We need to divide this subtable into smaller parts. + """ + table = ttf[overflowRecord.tableType].table + lookup = table.LookupList.Lookup[overflowRecord.LookupListIndex] + subIndex = overflowRecord.SubTableIndex + subtable = lookup.SubTable[subIndex] + + # First, try not sharing anything for this subtable... + if not hasattr(subtable, "DontShare"): + subtable.DontShare = True + return True + + if hasattr(subtable, "ExtSubTable"): + # We split the subtable of the Extension table, and add a new Extension table + # to contain the new subtable. + + subTableType = subtable.ExtSubTable.__class__.LookupType + extSubTable = subtable + subtable = extSubTable.ExtSubTable + newExtSubTableClass = lookupTypes[overflowRecord.tableType][ + extSubTable.__class__.LookupType + ] + newExtSubTable = newExtSubTableClass() + newExtSubTable.Format = extSubTable.Format + toInsert = newExtSubTable + + newSubTableClass = lookupTypes[overflowRecord.tableType][subTableType] + newSubTable = newSubTableClass() + newExtSubTable.ExtSubTable = newSubTable + else: + subTableType = subtable.__class__.LookupType + newSubTableClass = lookupTypes[overflowRecord.tableType][subTableType] + newSubTable = newSubTableClass() + toInsert = newSubTable + + if hasattr(lookup, "SubTableCount"): # may not be defined yet. + lookup.SubTableCount = lookup.SubTableCount + 1 + + try: + splitFunc = splitTable[overflowRecord.tableType][subTableType] + except KeyError: + log.error( + "Don't know how to split %s lookup type %s", + overflowRecord.tableType, + subTableType, + ) + return False + + ok = splitFunc(subtable, newSubTable, overflowRecord) + if ok: + lookup.SubTable.insert(subIndex + 1, toInsert) + return ok + + +# End of OverFlow logic + + +def _buildClasses(): + import re + from .otData import otData + + formatPat = re.compile(r"([A-Za-z0-9]+)Format(\d+)$") + namespace = globals() + + # populate module with classes + for name, table in otData: + baseClass = BaseTable + m = formatPat.match(name) + if m: + # XxxFormatN subtable, we only add the "base" table + name = m.group(1) + # the first row of a format-switching otData table describes the Format; + # the first column defines the type of the Format field. + # Currently this can be either 'uint16' or 'uint8'. + formatType = table[0][0] + baseClass = getFormatSwitchingBaseTableClass(formatType) + if name not in namespace: + # the class doesn't exist yet, so the base implementation is used. + cls = type(name, (baseClass,), {}) + if name in ("GSUB", "GPOS"): + cls.DontShare = True + namespace[name] = cls + + # link Var{Table} <-> {Table} (e.g. ColorStop <-> VarColorStop, etc.) + for name, _ in otData: + if name.startswith("Var") and len(name) > 3 and name[3:] in namespace: + varType = namespace[name] + noVarType = namespace[name[3:]] + varType.NoVarType = noVarType + noVarType.VarType = varType + + for base, alts in _equivalents.items(): + base = namespace[base] + for alt in alts: + namespace[alt] = base + + global lookupTypes + lookupTypes = { + "GSUB": { + 1: SingleSubst, + 2: MultipleSubst, + 3: AlternateSubst, + 4: LigatureSubst, + 5: ContextSubst, + 6: ChainContextSubst, + 7: ExtensionSubst, + 8: ReverseChainSingleSubst, + }, + "GPOS": { + 1: SinglePos, + 2: PairPos, + 3: CursivePos, + 4: MarkBasePos, + 5: MarkLigPos, + 6: MarkMarkPos, + 7: ContextPos, + 8: ChainContextPos, + 9: ExtensionPos, + }, + "mort": { + 4: NoncontextualMorph, + }, + "morx": { + 0: RearrangementMorph, + 1: ContextualMorph, + 2: LigatureMorph, + # 3: Reserved, + 4: NoncontextualMorph, + 5: InsertionMorph, + }, + } + lookupTypes["JSTF"] = lookupTypes["GPOS"] # JSTF contains GPOS + for lookupEnum in lookupTypes.values(): + for enum, cls in lookupEnum.items(): + cls.LookupType = enum + + global featureParamTypes + featureParamTypes = { + "size": FeatureParamsSize, + } + for i in range(1, 20 + 1): + featureParamTypes["ss%02d" % i] = FeatureParamsStylisticSet + for i in range(1, 99 + 1): + featureParamTypes["cv%02d" % i] = FeatureParamsCharacterVariants + + # add converters to classes + from .otConverters import buildConverters + + for name, table in otData: + m = formatPat.match(name) + if m: + # XxxFormatN subtable, add converter to "base" table + name, format = m.groups() + format = int(format) + cls = namespace[name] + if not hasattr(cls, "converters"): + cls.converters = {} + cls.convertersByName = {} + converters, convertersByName = buildConverters(table[1:], namespace) + cls.converters[format] = converters + cls.convertersByName[format] = convertersByName + # XXX Add staticSize? + else: + cls = namespace[name] + cls.converters, cls.convertersByName = buildConverters(table, namespace) + # XXX Add staticSize? + + +_buildClasses() + + +def _getGlyphsFromCoverageTable(coverage): + if coverage is None: + # empty coverage table + return [] + else: + return coverage.glyphs diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/otTraverse.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/otTraverse.py new file mode 100644 index 0000000000000000000000000000000000000000..9b624533f150cf16079b3acb8d5ae439236ef10a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/otTraverse.py @@ -0,0 +1,163 @@ +"""Methods for traversing trees of otData-driven OpenType tables.""" + +from collections import deque +from typing import Callable, Deque, Iterable, List, Optional, Tuple +from .otBase import BaseTable + + +__all__ = [ + "bfs_base_table", + "dfs_base_table", + "SubTablePath", +] + + +class SubTablePath(Tuple[BaseTable.SubTableEntry, ...]): + def __str__(self) -> str: + path_parts = [] + for entry in self: + path_part = entry.name + if entry.index is not None: + path_part += f"[{entry.index}]" + path_parts.append(path_part) + return ".".join(path_parts) + + +# Given f(current frontier, new entries) add new entries to frontier +AddToFrontierFn = Callable[[Deque[SubTablePath], List[SubTablePath]], None] + + +def dfs_base_table( + root: BaseTable, + root_accessor: Optional[str] = None, + skip_root: bool = False, + predicate: Optional[Callable[[SubTablePath], bool]] = None, + iter_subtables_fn: Optional[ + Callable[[BaseTable], Iterable[BaseTable.SubTableEntry]] + ] = None, +) -> Iterable[SubTablePath]: + """Depth-first search tree of BaseTables. + + Args: + root (BaseTable): the root of the tree. + root_accessor (Optional[str]): attribute name for the root table, if any (mostly + useful for debugging). + skip_root (Optional[bool]): if True, the root itself is not visited, only its + children. + predicate (Optional[Callable[[SubTablePath], bool]]): function to filter out + paths. If True, the path is yielded and its subtables are added to the + queue. If False, the path is skipped and its subtables are not traversed. + iter_subtables_fn (Optional[Callable[[BaseTable], Iterable[BaseTable.SubTableEntry]]]): + function to iterate over subtables of a table. If None, the default + BaseTable.iterSubTables() is used. + + Yields: + SubTablePath: tuples of BaseTable.SubTableEntry(name, table, index) namedtuples + for each of the nodes in the tree. The last entry in a path is the current + subtable, whereas preceding ones refer to its parent tables all the way up to + the root. + """ + yield from _traverse_ot_data( + root, + root_accessor, + skip_root, + predicate, + lambda frontier, new: frontier.extendleft(reversed(new)), + iter_subtables_fn, + ) + + +def bfs_base_table( + root: BaseTable, + root_accessor: Optional[str] = None, + skip_root: bool = False, + predicate: Optional[Callable[[SubTablePath], bool]] = None, + iter_subtables_fn: Optional[ + Callable[[BaseTable], Iterable[BaseTable.SubTableEntry]] + ] = None, +) -> Iterable[SubTablePath]: + """Breadth-first search tree of BaseTables. + + Args: + root + the root of the tree. + root_accessor (Optional[str]): attribute name for the root table, if any (mostly + useful for debugging). + skip_root (Optional[bool]): if True, the root itself is not visited, only its + children. + predicate (Optional[Callable[[SubTablePath], bool]]): function to filter out + paths. If True, the path is yielded and its subtables are added to the + queue. If False, the path is skipped and its subtables are not traversed. + iter_subtables_fn (Optional[Callable[[BaseTable], Iterable[BaseTable.SubTableEntry]]]): + function to iterate over subtables of a table. If None, the default + BaseTable.iterSubTables() is used. + + Yields: + SubTablePath: tuples of BaseTable.SubTableEntry(name, table, index) namedtuples + for each of the nodes in the tree. The last entry in a path is the current + subtable, whereas preceding ones refer to its parent tables all the way up to + the root. + """ + yield from _traverse_ot_data( + root, + root_accessor, + skip_root, + predicate, + lambda frontier, new: frontier.extend(new), + iter_subtables_fn, + ) + + +def _traverse_ot_data( + root: BaseTable, + root_accessor: Optional[str], + skip_root: bool, + predicate: Optional[Callable[[SubTablePath], bool]], + add_to_frontier_fn: AddToFrontierFn, + iter_subtables_fn: Optional[ + Callable[[BaseTable], Iterable[BaseTable.SubTableEntry]] + ] = None, +) -> Iterable[SubTablePath]: + # no visited because general otData cannot cycle (forward-offset only) + if root_accessor is None: + root_accessor = type(root).__name__ + + if predicate is None: + + def predicate(path): + return True + + if iter_subtables_fn is None: + + def iter_subtables_fn(table): + return table.iterSubTables() + + frontier: Deque[SubTablePath] = deque() + + root_entry = BaseTable.SubTableEntry(root_accessor, root) + if not skip_root: + frontier.append((root_entry,)) + else: + add_to_frontier_fn( + frontier, + [ + (root_entry, subtable_entry) + for subtable_entry in iter_subtables_fn(root) + ], + ) + + while frontier: + # path is (value, attr_name) tuples. attr_name is attr of parent to get value + path = frontier.popleft() + current = path[-1].value + + if not predicate(path): + continue + + yield SubTablePath(path) + + new_entries = [ + path + (subtable_entry,) for subtable_entry in iter_subtables_fn(current) + ] + + add_to_frontier_fn(frontier, new_entries) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/sbixGlyph.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/sbixGlyph.py new file mode 100644 index 0000000000000000000000000000000000000000..b744a2a3bc88907ef027ad7670b1b04f164dd44a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/sbixGlyph.py @@ -0,0 +1,149 @@ +from fontTools.misc import sstruct +from fontTools.misc.textTools import readHex, safeEval +import struct + + +sbixGlyphHeaderFormat = """ + > + originOffsetX: h # The x-value of the point in the glyph relative to its + # lower-left corner which corresponds to the origin of + # the glyph on the screen, that is the point on the + # baseline at the left edge of the glyph. + originOffsetY: h # The y-value of the point in the glyph relative to its + # lower-left corner which corresponds to the origin of + # the glyph on the screen, that is the point on the + # baseline at the left edge of the glyph. + graphicType: 4s # e.g. "png " +""" + +sbixGlyphHeaderFormatSize = sstruct.calcsize(sbixGlyphHeaderFormat) + + +class Glyph(object): + def __init__( + self, + glyphName=None, + referenceGlyphName=None, + originOffsetX=0, + originOffsetY=0, + graphicType=None, + imageData=None, + rawdata=None, + gid=0, + ): + self.gid = gid + self.glyphName = glyphName + self.referenceGlyphName = referenceGlyphName + self.originOffsetX = originOffsetX + self.originOffsetY = originOffsetY + self.rawdata = rawdata + self.graphicType = graphicType + self.imageData = imageData + + # fix self.graphicType if it is null terminated or too short + if self.graphicType is not None: + if self.graphicType[-1] == "\0": + self.graphicType = self.graphicType[:-1] + if len(self.graphicType) > 4: + from fontTools import ttLib + + raise ttLib.TTLibError( + "Glyph.graphicType must not be longer than 4 characters." + ) + elif len(self.graphicType) < 4: + # pad with spaces + self.graphicType += " "[: (4 - len(self.graphicType))] + + def is_reference_type(self): + """Returns True if this glyph is a reference to another glyph's image data.""" + return self.graphicType == "dupe" or self.graphicType == "flip" + + def decompile(self, ttFont): + self.glyphName = ttFont.getGlyphName(self.gid) + if self.rawdata is None: + from fontTools import ttLib + + raise ttLib.TTLibError("No table data to decompile") + if len(self.rawdata) > 0: + if len(self.rawdata) < sbixGlyphHeaderFormatSize: + from fontTools import ttLib + + # print "Glyph %i header too short: Expected %x, got %x." % (self.gid, sbixGlyphHeaderFormatSize, len(self.rawdata)) + raise ttLib.TTLibError("Glyph header too short.") + + sstruct.unpack( + sbixGlyphHeaderFormat, self.rawdata[:sbixGlyphHeaderFormatSize], self + ) + + if self.is_reference_type(): + # this glyph is a reference to another glyph's image data + (gid,) = struct.unpack(">H", self.rawdata[sbixGlyphHeaderFormatSize:]) + self.referenceGlyphName = ttFont.getGlyphName(gid) + else: + self.imageData = self.rawdata[sbixGlyphHeaderFormatSize:] + self.referenceGlyphName = None + # clean up + del self.rawdata + del self.gid + + def compile(self, ttFont): + if self.glyphName is None: + from fontTools import ttLib + + raise ttLib.TTLibError("Can't compile Glyph without glyph name") + # TODO: if ttFont has no maxp, cmap etc., ignore glyph names and compile by index? + # (needed if you just want to compile the sbix table on its own) + self.gid = struct.pack(">H", ttFont.getGlyphID(self.glyphName)) + if self.graphicType is None: + rawdata = b"" + else: + rawdata = sstruct.pack(sbixGlyphHeaderFormat, self) + if self.is_reference_type(): + rawdata += struct.pack(">H", ttFont.getGlyphID(self.referenceGlyphName)) + else: + assert self.imageData is not None + rawdata += self.imageData + self.rawdata = rawdata + + def toXML(self, xmlWriter, ttFont): + if self.graphicType is None: + # TODO: ignore empty glyphs? + # a glyph data entry is required for each glyph, + # but empty ones can be calculated at compile time + xmlWriter.simpletag("glyph", name=self.glyphName) + xmlWriter.newline() + return + xmlWriter.begintag( + "glyph", + graphicType=self.graphicType, + name=self.glyphName, + originOffsetX=self.originOffsetX, + originOffsetY=self.originOffsetY, + ) + xmlWriter.newline() + if self.is_reference_type(): + # this glyph is a reference to another glyph id. + xmlWriter.simpletag("ref", glyphname=self.referenceGlyphName) + else: + xmlWriter.begintag("hexdata") + xmlWriter.newline() + xmlWriter.dumphex(self.imageData) + xmlWriter.endtag("hexdata") + xmlWriter.newline() + xmlWriter.endtag("glyph") + xmlWriter.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name == "ref": + # this glyph i.e. a reference to another glyph's image data. + # in this case imageData contains the glyph id of the reference glyph + # get glyph id from glyphname + glyphname = safeEval("'''" + attrs["glyphname"] + "'''") + self.imageData = struct.pack(">H", ttFont.getGlyphID(glyphname)) + self.referenceGlyphName = glyphname + elif name == "hexdata": + self.imageData = readHex(content) + else: + from fontTools import ttLib + + raise ttLib.TTLibError("can't handle '%s' element" % name) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/sbixStrike.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/sbixStrike.py new file mode 100644 index 0000000000000000000000000000000000000000..4dfba2e76e899a55b9fa88e2aaba0f5b8c5b142d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/sbixStrike.py @@ -0,0 +1,177 @@ +from fontTools.misc import sstruct +from fontTools.misc.textTools import safeEval +from .sbixGlyph import Glyph +import struct + +sbixStrikeHeaderFormat = """ + > + ppem: H # The PPEM for which this strike was designed (e.g., 9, + # 12, 24) + resolution: H # The screen resolution (in dpi) for which this strike + # was designed (e.g., 72) +""" + +sbixGlyphDataOffsetFormat = """ + > + glyphDataOffset: L # Offset from the beginning of the strike data record + # to data for the individual glyph +""" + +sbixStrikeHeaderFormatSize = sstruct.calcsize(sbixStrikeHeaderFormat) +sbixGlyphDataOffsetFormatSize = sstruct.calcsize(sbixGlyphDataOffsetFormat) + + +class Strike(object): + def __init__(self, rawdata=None, ppem=0, resolution=72): + self.data = rawdata + self.ppem = ppem + self.resolution = resolution + self.glyphs = {} + + def decompile(self, ttFont): + if self.data is None: + from fontTools import ttLib + + raise ttLib.TTLibError + if len(self.data) < sbixStrikeHeaderFormatSize: + from fontTools import ttLib + + raise ( + ttLib.TTLibError, + "Strike header too short: Expected %x, got %x.", + ) % (sbixStrikeHeaderFormatSize, len(self.data)) + + # read Strike header from raw data + sstruct.unpack( + sbixStrikeHeaderFormat, self.data[:sbixStrikeHeaderFormatSize], self + ) + + # calculate number of glyphs + (firstGlyphDataOffset,) = struct.unpack( + ">L", + self.data[ + sbixStrikeHeaderFormatSize : sbixStrikeHeaderFormatSize + + sbixGlyphDataOffsetFormatSize + ], + ) + self.numGlyphs = ( + firstGlyphDataOffset - sbixStrikeHeaderFormatSize + ) // sbixGlyphDataOffsetFormatSize - 1 + # ^ -1 because there's one more offset than glyphs + + # build offset list for single glyph data offsets + self.glyphDataOffsets = [] + for i in range( + self.numGlyphs + 1 + ): # + 1 because there's one more offset than glyphs + start = i * sbixGlyphDataOffsetFormatSize + sbixStrikeHeaderFormatSize + (current_offset,) = struct.unpack( + ">L", self.data[start : start + sbixGlyphDataOffsetFormatSize] + ) + self.glyphDataOffsets.append(current_offset) + + # iterate through offset list and slice raw data into glyph data records + for i in range(self.numGlyphs): + current_glyph = Glyph( + rawdata=self.data[ + self.glyphDataOffsets[i] : self.glyphDataOffsets[i + 1] + ], + gid=i, + ) + current_glyph.decompile(ttFont) + self.glyphs[current_glyph.glyphName] = current_glyph + del self.glyphDataOffsets + del self.numGlyphs + del self.data + + def compile(self, ttFont): + self.glyphDataOffsets = b"" + self.bitmapData = b"" + + glyphOrder = ttFont.getGlyphOrder() + + # first glyph starts right after the header + currentGlyphDataOffset = ( + sbixStrikeHeaderFormatSize + + sbixGlyphDataOffsetFormatSize * (len(glyphOrder) + 1) + ) + for glyphName in glyphOrder: + if glyphName in self.glyphs: + # we have glyph data for this glyph + current_glyph = self.glyphs[glyphName] + else: + # must add empty glyph data record for this glyph + current_glyph = Glyph(glyphName=glyphName) + current_glyph.compile(ttFont) + current_glyph.glyphDataOffset = currentGlyphDataOffset + self.bitmapData += current_glyph.rawdata + currentGlyphDataOffset += len(current_glyph.rawdata) + self.glyphDataOffsets += sstruct.pack( + sbixGlyphDataOffsetFormat, current_glyph + ) + + # add last "offset", really the end address of the last glyph data record + dummy = Glyph() + dummy.glyphDataOffset = currentGlyphDataOffset + self.glyphDataOffsets += sstruct.pack(sbixGlyphDataOffsetFormat, dummy) + + # pack header + self.data = sstruct.pack(sbixStrikeHeaderFormat, self) + # add offsets and image data after header + self.data += self.glyphDataOffsets + self.bitmapData + + def toXML(self, xmlWriter, ttFont): + xmlWriter.begintag("strike") + xmlWriter.newline() + xmlWriter.simpletag("ppem", value=self.ppem) + xmlWriter.newline() + xmlWriter.simpletag("resolution", value=self.resolution) + xmlWriter.newline() + glyphOrder = ttFont.getGlyphOrder() + for glyphName in glyphOrder: + if glyphName in self.glyphs: + self.glyphs[glyphName].toXML(xmlWriter, ttFont) + # TODO: what if there are more glyph data records than (glyf table) glyphs? + xmlWriter.endtag("strike") + xmlWriter.newline() + + def fromXML(self, name, attrs, content, ttFont): + if name in ["ppem", "resolution"]: + setattr(self, name, safeEval(attrs["value"])) + elif name == "glyph": + if "graphicType" in attrs: + myFormat = safeEval("'''" + attrs["graphicType"] + "'''") + else: + myFormat = None + if "glyphname" in attrs: + myGlyphName = safeEval("'''" + attrs["glyphname"] + "'''") + elif "name" in attrs: + myGlyphName = safeEval("'''" + attrs["name"] + "'''") + else: + from fontTools import ttLib + + raise ttLib.TTLibError("Glyph must have a glyph name.") + if "originOffsetX" in attrs: + myOffsetX = safeEval(attrs["originOffsetX"]) + else: + myOffsetX = 0 + if "originOffsetY" in attrs: + myOffsetY = safeEval(attrs["originOffsetY"]) + else: + myOffsetY = 0 + current_glyph = Glyph( + glyphName=myGlyphName, + graphicType=myFormat, + originOffsetX=myOffsetX, + originOffsetY=myOffsetY, + ) + for element in content: + if isinstance(element, tuple): + name, attrs, content = element + current_glyph.fromXML(name, attrs, content, ttFont) + current_glyph.compile(ttFont) + self.glyphs[current_glyph.glyphName] = current_glyph + else: + from fontTools import ttLib + + raise ttLib.TTLibError("can't handle '%s' element" % name) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/table_API_readme.txt b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/table_API_readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..7719201a0ea2d4b8f28a3012ad63c1de8bbf10ef --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/table_API_readme.txt @@ -0,0 +1,91 @@ +This folder is a subpackage of ttLib. Each module here is a +specialized TT/OT table converter: they can convert raw data +to Python objects and vice versa. Usually you don't need to +use the modules directly: they are imported and used +automatically when needed by ttLib. + +If you are writing you own table converter the following is +important. + +The modules here have pretty strange names: this is due to the +fact that we need to map TT table tags (which are case sensitive) +to filenames (which on Mac and Win aren't case sensitive) as well +as to Python identifiers. The latter means it can only contain +[A-Za-z0-9_] and cannot start with a number. + +ttLib provides functions to expand a tag into the format used here: + +>>> from fontTools import ttLib +>>> ttLib.tagToIdentifier("FOO ") +'F_O_O_' +>>> ttLib.tagToIdentifier("cvt ") +'_c_v_t' +>>> ttLib.tagToIdentifier("OS/2") +'O_S_2f_2' +>>> ttLib.tagToIdentifier("glyf") +'_g_l_y_f' +>>> + +And vice versa: + +>>> ttLib.identifierToTag("F_O_O_") +'FOO ' +>>> ttLib.identifierToTag("_c_v_t") +'cvt ' +>>> ttLib.identifierToTag("O_S_2f_2") +'OS/2' +>>> ttLib.identifierToTag("_g_l_y_f") +'glyf' +>>> + +Eg. the 'glyf' table converter lives in a Python file called: + + _g_l_y_f.py + +The converter itself is a class, named "table_" + expandedtag. Eg: + + class table__g_l_y_f: + etc. + +Note that if you _do_ need to use such modules or classes manually, +there are two convenient API functions that let you find them by tag: + +>>> ttLib.getTableModule('glyf') +<module 'ttLib.tables._g_l_y_f'> +>>> ttLib.getTableClass('glyf') +<class ttLib.tables._g_l_y_f.table__g_l_y_f at 645f400> +>>> + +You must subclass from DefaultTable.DefaultTable. It provides some default +behavior, as well as a constructor method (__init__) that you don't need to +override. + +Your converter should minimally provide two methods: + +class table_F_O_O_(DefaultTable.DefaultTable): # converter for table 'FOO ' + + def decompile(self, data, ttFont): + # 'data' is the raw table data. Unpack it into a + # Python data structure. + # 'ttFont' is a ttLib.TTfile instance, enabling you to + # refer to other tables. Do ***not*** keep a reference to + # it: it will cause a circular reference (ttFont saves + # a reference to us), and that means we'll be leaking + # memory. If you need to use it in other methods, just + # pass it around as a method argument. + + def compile(self, ttFont): + # Return the raw data, as converted from the Python + # data structure. + # Again, 'ttFont' is there so you can access other tables. + # Same warning applies. + +If you want to support TTX import/export as well, you need to provide two +additional methods: + + def toXML(self, writer, ttFont): + # XXX + + def fromXML(self, (name, attrs, content), ttFont): + # XXX + diff --git a/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/ttProgram.py b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/ttProgram.py new file mode 100644 index 0000000000000000000000000000000000000000..32a4ec8b20ff8b4c20be33efebea7273af98931b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ttLib/tables/ttProgram.py @@ -0,0 +1,594 @@ +"""ttLib.tables.ttProgram.py -- Assembler/disassembler for TrueType bytecode programs.""" + +from __future__ import annotations + +from fontTools.misc.textTools import num2binary, binary2num, readHex, strjoin +import array +from io import StringIO +from typing import List +import re +import logging + + +log = logging.getLogger(__name__) + +# fmt: off + +# first, the list of instructions that eat bytes or words from the instruction stream + +streamInstructions = [ +# +# opcode mnemonic argBits descriptive name pops pushes eats from instruction stream pushes +# + (0x40, 'NPUSHB', 0, 'PushNBytes', 0, -1), # n, b1, b2,...bn b1,b2...bn + (0x41, 'NPUSHW', 0, 'PushNWords', 0, -1), # n, w1, w2,...w w1,w2...wn + (0xb0, 'PUSHB', 3, 'PushBytes', 0, -1), # b0, b1,..bn b0, b1, ...,bn + (0xb8, 'PUSHW', 3, 'PushWords', 0, -1), # w0,w1,..wn w0 ,w1, ...wn +] + + +# next, the list of "normal" instructions + +instructions = [ +# +# opcode mnemonic argBits descriptive name pops pushes eats from instruction stream pushes +# + (0x7f, 'AA', 0, 'AdjustAngle', 1, 0), # p - + (0x64, 'ABS', 0, 'Absolute', 1, 1), # n |n| + (0x60, 'ADD', 0, 'Add', 2, 1), # n2, n1 (n1 + n2) + (0x27, 'ALIGNPTS', 0, 'AlignPts', 2, 0), # p2, p1 - + (0x3c, 'ALIGNRP', 0, 'AlignRelativePt', -1, 0), # p1, p2, ... , ploopvalue - + (0x5a, 'AND', 0, 'LogicalAnd', 2, 1), # e2, e1 b + (0x2b, 'CALL', 0, 'CallFunction', 1, 0), # f - + (0x67, 'CEILING', 0, 'Ceiling', 1, 1), # n ceil(n) + (0x25, 'CINDEX', 0, 'CopyXToTopStack', 1, 1), # k ek + (0x22, 'CLEAR', 0, 'ClearStack', -1, 0), # all items on the stack - + (0x4f, 'DEBUG', 0, 'DebugCall', 1, 0), # n - + (0x73, 'DELTAC1', 0, 'DeltaExceptionC1', -1, 0), # argn, cn, argn-1,cn-1, , arg1, c1 - + (0x74, 'DELTAC2', 0, 'DeltaExceptionC2', -1, 0), # argn, cn, argn-1,cn-1, , arg1, c1 - + (0x75, 'DELTAC3', 0, 'DeltaExceptionC3', -1, 0), # argn, cn, argn-1,cn-1, , arg1, c1 - + (0x5d, 'DELTAP1', 0, 'DeltaExceptionP1', -1, 0), # argn, pn, argn-1, pn-1, , arg1, p1 - + (0x71, 'DELTAP2', 0, 'DeltaExceptionP2', -1, 0), # argn, pn, argn-1, pn-1, , arg1, p1 - + (0x72, 'DELTAP3', 0, 'DeltaExceptionP3', -1, 0), # argn, pn, argn-1, pn-1, , arg1, p1 - + (0x24, 'DEPTH', 0, 'GetDepthStack', 0, 1), # - n + (0x62, 'DIV', 0, 'Divide', 2, 1), # n2, n1 (n1 * 64)/ n2 + (0x20, 'DUP', 0, 'DuplicateTopStack', 1, 2), # e e, e + (0x59, 'EIF', 0, 'EndIf', 0, 0), # - - + (0x1b, 'ELSE', 0, 'Else', 0, 0), # - - + (0x2d, 'ENDF', 0, 'EndFunctionDefinition', 0, 0), # - - + (0x54, 'EQ', 0, 'Equal', 2, 1), # e2, e1 b + (0x57, 'EVEN', 0, 'Even', 1, 1), # e b + (0x2c, 'FDEF', 0, 'FunctionDefinition', 1, 0), # f - + (0x4e, 'FLIPOFF', 0, 'SetAutoFlipOff', 0, 0), # - - + (0x4d, 'FLIPON', 0, 'SetAutoFlipOn', 0, 0), # - - + (0x80, 'FLIPPT', 0, 'FlipPoint', -1, 0), # p1, p2, ..., ploopvalue - + (0x82, 'FLIPRGOFF', 0, 'FlipRangeOff', 2, 0), # h, l - + (0x81, 'FLIPRGON', 0, 'FlipRangeOn', 2, 0), # h, l - + (0x66, 'FLOOR', 0, 'Floor', 1, 1), # n floor(n) + (0x46, 'GC', 1, 'GetCoordOnPVector', 1, 1), # p c + (0x88, 'GETINFO', 0, 'GetInfo', 1, 1), # selector result + (0x91, 'GETVARIATION', 0, 'GetVariation', 0, -1), # - a1,..,an + (0x0d, 'GFV', 0, 'GetFVector', 0, 2), # - px, py + (0x0c, 'GPV', 0, 'GetPVector', 0, 2), # - px, py + (0x52, 'GT', 0, 'GreaterThan', 2, 1), # e2, e1 b + (0x53, 'GTEQ', 0, 'GreaterThanOrEqual', 2, 1), # e2, e1 b + (0x89, 'IDEF', 0, 'InstructionDefinition', 1, 0), # f - + (0x58, 'IF', 0, 'If', 1, 0), # e - + (0x8e, 'INSTCTRL', 0, 'SetInstrExecControl', 2, 0), # s, v - + (0x39, 'IP', 0, 'InterpolatePts', -1, 0), # p1, p2, ... , ploopvalue - + (0x0f, 'ISECT', 0, 'MovePtToIntersect', 5, 0), # a1, a0, b1, b0, p - + (0x30, 'IUP', 1, 'InterpolateUntPts', 0, 0), # - - + (0x1c, 'JMPR', 0, 'Jump', 1, 0), # offset - + (0x79, 'JROF', 0, 'JumpRelativeOnFalse', 2, 0), # e, offset - + (0x78, 'JROT', 0, 'JumpRelativeOnTrue', 2, 0), # e, offset - + (0x2a, 'LOOPCALL', 0, 'LoopAndCallFunction', 2, 0), # f, count - + (0x50, 'LT', 0, 'LessThan', 2, 1), # e2, e1 b + (0x51, 'LTEQ', 0, 'LessThenOrEqual', 2, 1), # e2, e1 b + (0x8b, 'MAX', 0, 'Maximum', 2, 1), # e2, e1 max(e1, e2) + (0x49, 'MD', 1, 'MeasureDistance', 2, 1), # p2,p1 d + (0x2e, 'MDAP', 1, 'MoveDirectAbsPt', 1, 0), # p - + (0xc0, 'MDRP', 5, 'MoveDirectRelPt', 1, 0), # p - + (0x3e, 'MIAP', 1, 'MoveIndirectAbsPt', 2, 0), # n, p - + (0x8c, 'MIN', 0, 'Minimum', 2, 1), # e2, e1 min(e1, e2) + (0x26, 'MINDEX', 0, 'MoveXToTopStack', 1, 1), # k ek + (0xe0, 'MIRP', 5, 'MoveIndirectRelPt', 2, 0), # n, p - + (0x4b, 'MPPEM', 0, 'MeasurePixelPerEm', 0, 1), # - ppem + (0x4c, 'MPS', 0, 'MeasurePointSize', 0, 1), # - pointSize + (0x3a, 'MSIRP', 1, 'MoveStackIndirRelPt', 2, 0), # d, p - + (0x63, 'MUL', 0, 'Multiply', 2, 1), # n2, n1 (n1 * n2)/64 + (0x65, 'NEG', 0, 'Negate', 1, 1), # n -n + (0x55, 'NEQ', 0, 'NotEqual', 2, 1), # e2, e1 b + (0x5c, 'NOT', 0, 'LogicalNot', 1, 1), # e ( not e ) + (0x6c, 'NROUND', 2, 'NoRound', 1, 1), # n1 n2 + (0x56, 'ODD', 0, 'Odd', 1, 1), # e b + (0x5b, 'OR', 0, 'LogicalOr', 2, 1), # e2, e1 b + (0x21, 'POP', 0, 'PopTopStack', 1, 0), # e - + (0x45, 'RCVT', 0, 'ReadCVT', 1, 1), # location value + (0x7d, 'RDTG', 0, 'RoundDownToGrid', 0, 0), # - - + (0x7a, 'ROFF', 0, 'RoundOff', 0, 0), # - - + (0x8a, 'ROLL', 0, 'RollTopThreeStack', 3, 3), # a,b,c b,a,c + (0x68, 'ROUND', 2, 'Round', 1, 1), # n1 n2 + (0x43, 'RS', 0, 'ReadStore', 1, 1), # n v + (0x3d, 'RTDG', 0, 'RoundToDoubleGrid', 0, 0), # - - + (0x18, 'RTG', 0, 'RoundToGrid', 0, 0), # - - + (0x19, 'RTHG', 0, 'RoundToHalfGrid', 0, 0), # - - + (0x7c, 'RUTG', 0, 'RoundUpToGrid', 0, 0), # - - + (0x77, 'S45ROUND', 0, 'SuperRound45Degrees', 1, 0), # n - + (0x7e, 'SANGW', 0, 'SetAngleWeight', 1, 0), # weight - + (0x85, 'SCANCTRL', 0, 'ScanConversionControl', 1, 0), # n - + (0x8d, 'SCANTYPE', 0, 'ScanType', 1, 0), # n - + (0x48, 'SCFS', 0, 'SetCoordFromStackFP', 2, 0), # c, p - + (0x1d, 'SCVTCI', 0, 'SetCVTCutIn', 1, 0), # n - + (0x5e, 'SDB', 0, 'SetDeltaBaseInGState', 1, 0), # n - + (0x86, 'SDPVTL', 1, 'SetDualPVectorToLine', 2, 0), # p2, p1 - + (0x5f, 'SDS', 0, 'SetDeltaShiftInGState', 1, 0), # n - + (0x0b, 'SFVFS', 0, 'SetFVectorFromStack', 2, 0), # y, x - + (0x04, 'SFVTCA', 1, 'SetFVectorToAxis', 0, 0), # - - + (0x08, 'SFVTL', 1, 'SetFVectorToLine', 2, 0), # p2, p1 - + (0x0e, 'SFVTPV', 0, 'SetFVectorToPVector', 0, 0), # - - + (0x34, 'SHC', 1, 'ShiftContourByLastPt', 1, 0), # c - + (0x32, 'SHP', 1, 'ShiftPointByLastPoint', -1, 0), # p1, p2, ..., ploopvalue - + (0x38, 'SHPIX', 0, 'ShiftZoneByPixel', -1, 0), # d, p1, p2, ..., ploopvalue - + (0x36, 'SHZ', 1, 'ShiftZoneByLastPoint', 1, 0), # e - + (0x17, 'SLOOP', 0, 'SetLoopVariable', 1, 0), # n - + (0x1a, 'SMD', 0, 'SetMinimumDistance', 1, 0), # distance - + (0x0a, 'SPVFS', 0, 'SetPVectorFromStack', 2, 0), # y, x - + (0x02, 'SPVTCA', 1, 'SetPVectorToAxis', 0, 0), # - - + (0x06, 'SPVTL', 1, 'SetPVectorToLine', 2, 0), # p2, p1 - + (0x76, 'SROUND', 0, 'SuperRound', 1, 0), # n - + (0x10, 'SRP0', 0, 'SetRefPoint0', 1, 0), # p - + (0x11, 'SRP1', 0, 'SetRefPoint1', 1, 0), # p - + (0x12, 'SRP2', 0, 'SetRefPoint2', 1, 0), # p - + (0x1f, 'SSW', 0, 'SetSingleWidth', 1, 0), # n - + (0x1e, 'SSWCI', 0, 'SetSingleWidthCutIn', 1, 0), # n - + (0x61, 'SUB', 0, 'Subtract', 2, 1), # n2, n1 (n1 - n2) + (0x00, 'SVTCA', 1, 'SetFPVectorToAxis', 0, 0), # - - + (0x23, 'SWAP', 0, 'SwapTopStack', 2, 2), # e2, e1 e1, e2 + (0x13, 'SZP0', 0, 'SetZonePointer0', 1, 0), # n - + (0x14, 'SZP1', 0, 'SetZonePointer1', 1, 0), # n - + (0x15, 'SZP2', 0, 'SetZonePointer2', 1, 0), # n - + (0x16, 'SZPS', 0, 'SetZonePointerS', 1, 0), # n - + (0x29, 'UTP', 0, 'UnTouchPt', 1, 0), # p - + (0x70, 'WCVTF', 0, 'WriteCVTInFUnits', 2, 0), # n, l - + (0x44, 'WCVTP', 0, 'WriteCVTInPixels', 2, 0), # v, l - + (0x42, 'WS', 0, 'WriteStore', 2, 0), # v, l - +] + +# fmt: on + + +def bitRepr(value, bits): + s = "" + for i in range(bits): + s = "01"[value & 0x1] + s + value = value >> 1 + return s + + +_mnemonicPat = re.compile(r"[A-Z][A-Z0-9]*$") + + +def _makeDict(instructionList): + opcodeDict = {} + mnemonicDict = {} + for op, mnemonic, argBits, name, pops, pushes in instructionList: + assert _mnemonicPat.match(mnemonic) + mnemonicDict[mnemonic] = op, argBits, name + if argBits: + argoffset = op + for i in range(1 << argBits): + opcodeDict[op + i] = mnemonic, argBits, argoffset, name + else: + opcodeDict[op] = mnemonic, 0, 0, name + return opcodeDict, mnemonicDict + + +streamOpcodeDict, streamMnemonicDict = _makeDict(streamInstructions) +opcodeDict, mnemonicDict = _makeDict(instructions) + + +class tt_instructions_error(Exception): + def __init__(self, error): + self.error = error + + def __str__(self): + return "TT instructions error: %s" % repr(self.error) + + +_comment = r"/\*.*?\*/" +_instruction = r"([A-Z][A-Z0-9]*)\s*\[(.*?)\]" +_number = r"-?[0-9]+" +_token = "(%s)|(%s)|(%s)" % (_instruction, _number, _comment) + +_tokenRE = re.compile(_token) +_whiteRE = re.compile(r"\s*") + +_pushCountPat = re.compile(r"[A-Z][A-Z0-9]*\s*\[.*?\]\s*/\* ([0-9]+).*?\*/") + +_indentRE = re.compile(r"^FDEF|IF|ELSE\[ \]\t.+") +_unindentRE = re.compile(r"^ELSE|ENDF|EIF\[ \]\t.+") + + +def _skipWhite(data, pos): + m = _whiteRE.match(data, pos) + newPos = m.regs[0][1] + assert newPos >= pos + return newPos + + +class Program(object): + def __init__(self) -> None: + pass + + def fromBytecode(self, bytecode: bytes) -> None: + self.bytecode = array.array("B", bytecode) + if hasattr(self, "assembly"): + del self.assembly + + def fromAssembly(self, assembly: List[str] | str) -> None: + if isinstance(assembly, list): + self.assembly = assembly + elif isinstance(assembly, str): + self.assembly = assembly.splitlines() + else: + raise TypeError(f"expected str or List[str], got {type(assembly).__name__}") + if hasattr(self, "bytecode"): + del self.bytecode + + def getBytecode(self) -> bytes: + if not hasattr(self, "bytecode"): + self._assemble() + return self.bytecode.tobytes() + + def getAssembly(self, preserve=True) -> List[str]: + if not hasattr(self, "assembly"): + self._disassemble(preserve=preserve) + return self.assembly + + def toXML(self, writer, ttFont) -> None: + if ( + not hasattr(ttFont, "disassembleInstructions") + or ttFont.disassembleInstructions + ): + try: + assembly = self.getAssembly() + except: + import traceback + + tmp = StringIO() + traceback.print_exc(file=tmp) + msg = "An exception occurred during the decompilation of glyph program:\n\n" + msg += tmp.getvalue() + log.error(msg) + writer.begintag("bytecode") + writer.newline() + writer.comment(msg.strip()) + writer.newline() + writer.dumphex(self.getBytecode()) + writer.endtag("bytecode") + writer.newline() + else: + if not assembly: + return + writer.begintag("assembly") + writer.newline() + i = 0 + indent = 0 + nInstr = len(assembly) + while i < nInstr: + instr = assembly[i] + if _unindentRE.match(instr): + indent -= 1 + writer.write(writer.indentwhite * indent) + writer.write(instr) + writer.newline() + m = _pushCountPat.match(instr) + i = i + 1 + if m: + nValues = int(m.group(1)) + line: List[str] = [] + j = 0 + for j in range(nValues): + if j and not (j % 25): + writer.write(writer.indentwhite * indent) + writer.write(" ".join(line)) + writer.newline() + line = [] + line.append(assembly[i + j]) + writer.write(writer.indentwhite * indent) + writer.write(" ".join(line)) + writer.newline() + i = i + j + 1 + if _indentRE.match(instr): + indent += 1 + writer.endtag("assembly") + writer.newline() + else: + bytecode = self.getBytecode() + if not bytecode: + return + writer.begintag("bytecode") + writer.newline() + writer.dumphex(bytecode) + writer.endtag("bytecode") + writer.newline() + + def fromXML(self, name, attrs, content, ttFont) -> None: + if name == "assembly": + self.fromAssembly(strjoin(content)) + self._assemble() + del self.assembly + else: + assert name == "bytecode" + self.fromBytecode(readHex(content)) + + def _assemble(self) -> None: + assembly = " ".join(getattr(self, "assembly", [])) + bytecode: List[int] = [] + push = bytecode.append + lenAssembly = len(assembly) + pos = _skipWhite(assembly, 0) + while pos < lenAssembly: + m = _tokenRE.match(assembly, pos) + if m is None: + raise tt_instructions_error( + "Syntax error in TT program (%s)" % assembly[pos - 5 : pos + 15] + ) + dummy, mnemonic, arg, number, comment = m.groups() + pos = m.regs[0][1] + if comment: + pos = _skipWhite(assembly, pos) + continue + + arg = arg.strip() + if mnemonic.startswith("INSTR"): + # Unknown instruction + op = int(mnemonic[5:]) + push(op) + elif mnemonic not in ("PUSH", "NPUSHB", "NPUSHW", "PUSHB", "PUSHW"): + op, argBits, name = mnemonicDict[mnemonic] + if len(arg) != argBits: + raise tt_instructions_error( + "Incorrect number of argument bits (%s[%s])" % (mnemonic, arg) + ) + if arg: + arg = binary2num(arg) + push(op + arg) + else: + push(op) + else: + args = [] + pos = _skipWhite(assembly, pos) + while pos < lenAssembly: + m = _tokenRE.match(assembly, pos) + if m is None: + raise tt_instructions_error( + "Syntax error in TT program (%s)" % assembly[pos : pos + 15] + ) + dummy, _mnemonic, arg, number, comment = m.groups() + if number is None and comment is None: + break + pos = m.regs[0][1] + pos = _skipWhite(assembly, pos) + if comment is not None: + continue + args.append(int(number)) + nArgs = len(args) + if mnemonic == "PUSH": + # Automatically choose the most compact representation + nWords = 0 + while nArgs: + while ( + nWords < nArgs + and nWords < 255 + and not (0 <= args[nWords] <= 255) + ): + nWords += 1 + nBytes = 0 + while ( + nWords + nBytes < nArgs + and nBytes < 255 + and 0 <= args[nWords + nBytes] <= 255 + ): + nBytes += 1 + if ( + nBytes < 2 + and nWords + nBytes < 255 + and nWords + nBytes != nArgs + ): + # Will write bytes as words + nWords += nBytes + continue + + # Write words + if nWords: + if nWords <= 8: + op, argBits, name = streamMnemonicDict["PUSHW"] + op = op + nWords - 1 + push(op) + else: + op, argBits, name = streamMnemonicDict["NPUSHW"] + push(op) + push(nWords) + for value in args[:nWords]: + assert -32768 <= value < 32768, ( + "PUSH value out of range %d" % value + ) + push((value >> 8) & 0xFF) + push(value & 0xFF) + + # Write bytes + if nBytes: + pass + if nBytes <= 8: + op, argBits, name = streamMnemonicDict["PUSHB"] + op = op + nBytes - 1 + push(op) + else: + op, argBits, name = streamMnemonicDict["NPUSHB"] + push(op) + push(nBytes) + for value in args[nWords : nWords + nBytes]: + push(value) + + nTotal = nWords + nBytes + args = args[nTotal:] + nArgs -= nTotal + nWords = 0 + else: + # Write exactly what we've been asked to + words = mnemonic[-1] == "W" + op, argBits, name = streamMnemonicDict[mnemonic] + if mnemonic[0] != "N": + assert nArgs <= 8, nArgs + op = op + nArgs - 1 + push(op) + else: + assert nArgs < 256 + push(op) + push(nArgs) + if words: + for value in args: + assert -32768 <= value < 32768, ( + "PUSHW value out of range %d" % value + ) + push((value >> 8) & 0xFF) + push(value & 0xFF) + else: + for value in args: + assert 0 <= value < 256, ( + "PUSHB value out of range %d" % value + ) + push(value) + + pos = _skipWhite(assembly, pos) + + if bytecode: + assert max(bytecode) < 256 and min(bytecode) >= 0 + self.bytecode = array.array("B", bytecode) + + def _disassemble(self, preserve=False) -> None: + assembly = [] + i = 0 + bytecode = getattr(self, "bytecode", []) + numBytecode = len(bytecode) + while i < numBytecode: + op = bytecode[i] + try: + mnemonic, argBits, argoffset, name = opcodeDict[op] + except KeyError: + if op in streamOpcodeDict: + values = [] + + # Merge consecutive PUSH operations + while bytecode[i] in streamOpcodeDict: + op = bytecode[i] + mnemonic, argBits, argoffset, name = streamOpcodeDict[op] + words = mnemonic[-1] == "W" + if argBits: + nValues = op - argoffset + 1 + else: + i = i + 1 + nValues = bytecode[i] + i = i + 1 + assert nValues > 0 + if not words: + for j in range(nValues): + value = bytecode[i] + values.append(repr(value)) + i = i + 1 + else: + for j in range(nValues): + # cast to signed int16 + value = (bytecode[i] << 8) | bytecode[i + 1] + if value >= 0x8000: + value = value - 0x10000 + values.append(repr(value)) + i = i + 2 + if preserve: + break + + if not preserve: + mnemonic = "PUSH" + nValues = len(values) + if nValues == 1: + assembly.append("%s[ ] /* 1 value pushed */" % mnemonic) + else: + assembly.append( + "%s[ ] /* %s values pushed */" % (mnemonic, nValues) + ) + assembly.extend(values) + else: + assembly.append("INSTR%d[ ]" % op) + i = i + 1 + else: + if argBits: + assembly.append( + mnemonic + + "[%s] /* %s */" % (num2binary(op - argoffset, argBits), name) + ) + else: + assembly.append(mnemonic + "[ ] /* %s */" % name) + i = i + 1 + self.assembly = assembly + + def __bool__(self) -> bool: + """ + >>> p = Program() + >>> bool(p) + False + >>> bc = array.array("B", [0]) + >>> p.fromBytecode(bc) + >>> bool(p) + True + >>> p.bytecode.pop() + 0 + >>> bool(p) + False + + >>> p = Program() + >>> asm = ['SVTCA[0]'] + >>> p.fromAssembly(asm) + >>> bool(p) + True + >>> p.assembly.pop() + 'SVTCA[0]' + >>> bool(p) + False + """ + return (hasattr(self, "assembly") and len(self.assembly) > 0) or ( + hasattr(self, "bytecode") and len(self.bytecode) > 0 + ) + + __nonzero__ = __bool__ + + def __eq__(self, other) -> bool: + if type(self) != type(other): + return NotImplemented + return self.__dict__ == other.__dict__ + + def __ne__(self, other) -> bool: + result = self.__eq__(other) + return result if result is NotImplemented else not result + + +def _test(): + """ + >>> _test() + True + """ + + bc = b"""@;:9876543210/.-,+*)(\'&%$#"! \037\036\035\034\033\032\031\030\027\026\025\024\023\022\021\020\017\016\015\014\013\012\011\010\007\006\005\004\003\002\001\000,\001\260\030CXEj\260\031C`\260F#D#\020 \260FN\360M/\260\000\022\033!#\0213Y-,\001\260\030CX\260\005+\260\000\023K\260\024PX\261\000@8Y\260\006+\033!#\0213Y-,\001\260\030CXN\260\003%\020\362!\260\000\022M\033 E\260\004%\260\004%#Jad\260(RX!#\020\326\033\260\003%\020\362!\260\000\022YY-,\260\032CX!!\033\260\002%\260\002%I\260\003%\260\003%Ja d\260\020PX!!!\033\260\003%\260\003%I\260\000PX\260\000PX\270\377\3428!\033\260\0208!Y\033\260\000RX\260\0368!\033\270\377\3608!YYYY-,\001\260\030CX\260\005+\260\000\023K\260\024PX\271\000\000\377\3008Y\260\006+\033!#\0213Y-,N\001\212\020\261F\031CD\260\000\024\261\000F\342\260\000\025\271\000\000\377\3608\000\260\000<\260(+\260\002%\020\260\000<-,\001\030\260\000/\260\001\024\362\260\001\023\260\001\025M\260\000\022-,\001\260\030CX\260\005+\260\000\023\271\000\000\377\3408\260\006+\033!#\0213Y-,\001\260\030CXEdj#Edi\260\031Cd``\260F#D#\020 \260F\360/\260\000\022\033!! \212 \212RX\0213\033!!YY-,\001\261\013\012C#Ce\012-,\000\261\012\013C#C\013-,\000\260F#p\261\001F>\001\260F#p\261\002FE:\261\002\000\010\015-,\260\022+\260\002%E\260\002%Ej\260@\213`\260\002%#D!!!-,\260\023+\260\002%E\260\002%Ej\270\377\300\214`\260\002%#D!!!-,\260\000\260\022+!!!-,\260\000\260\023+!!!-,\001\260\006C\260\007Ce\012-, i\260@a\260\000\213 \261,\300\212\214\270\020\000b`+\014d#da\\X\260\003aY-,\261\000\003%EhT\260\034KPZX\260\003%E\260\003%E`h \260\004%#D\260\004%#D\033\260\003% Eh \212#D\260\003%Eh`\260\003%#DY-,\260\003% Eh \212#D\260\003%Edhe`\260\004%\260\001`#D-,\260\011CX\207!\300\033\260\022CX\207E\260\021+\260G#D\260Gz\344\033\003\212E\030i \260G#D\212\212\207 \260\240QX\260\021+\260G#D\260Gz\344\033!\260Gz\344YYY\030-, \212E#Eh`D-,EjB-,\001\030/-,\001\260\030CX\260\004%\260\004%Id#Edi\260@\213a \260\200bj\260\002%\260\002%a\214\260\031C`\260F#D!\212\020\260F\366!\033!!!!Y-,\001\260\030CX\260\002%E\260\002%Ed`j\260\003%Eja \260\004%Ej \212\213e\260\004%#D\214\260\003%#D!!\033 EjD EjDY-,\001 E\260\000U\260\030CZXEh#Ei\260@\213a \260\200bj \212#a \260\003%\213e\260\004%#D\214\260\003%#D!!\033!!\260\031+Y-,\001\212\212Ed#EdadB-,\260\004%\260\004%\260\031+\260\030CX\260\004%\260\004%\260\003%\260\033+\001\260\002%C\260@T\260\002%C\260\000TZX\260\003% E\260@aDY\260\002%C\260\000T\260\002%C\260@TZX\260\004% E\260@`DYY!!!!-,\001KRXC\260\002%E#aD\033!!Y-,\001KRXC\260\002%E#`D\033!!Y-,KRXED\033!!Y-,\001 \260\003%#I\260@`\260 c \260\000RX#\260\002%8#\260\002%e8\000\212c8\033!!!!!Y\001-,KPXED\033!!Y-,\001\260\005%\020# \212\365\000\260\001`#\355\354-,\001\260\005%\020# \212\365\000\260\001a#\355\354-,\001\260\006%\020\365\000\355\354-,F#F`\212\212F# F\212`\212a\270\377\200b# \020#\212\261KK\212pE` \260\000PX\260\001a\270\377\272\213\033\260F\214Y\260\020`h\001:-, E\260\003%FRX\260\002%F ha\260\003%\260\003%?#!8\033!\021Y-, E\260\003%FPX\260\002%F ha\260\003%\260\003%?#!8\033!\021Y-,\000\260\007C\260\006C\013-,\212\020\354-,\260\014CX!\033 F\260\000RX\270\377\3608\033\260\0208YY-, \260\000UX\270\020\000c\260\003%Ed\260\003%Eda\260\000SX\260\002\033\260@a\260\003Y%EiSXED\033!!Y\033!\260\002%E\260\002%Ead\260(QXED\033!!YY-,!!\014d#d\213\270@\000b-,!\260\200QX\014d#d\213\270 \000b\033\262\000@/+Y\260\002`-,!\260\300QX\014d#d\213\270\025Ub\033\262\000\200/+Y\260\002`-,\014d#d\213\270@\000b`#!-,KSX\260\004%\260\004%Id#Edi\260@\213a \260\200bj\260\002%\260\002%a\214\260F#D!\212\020\260F\366!\033!\212\021#\022 9/Y-,\260\002%\260\002%Id\260\300TX\270\377\3708\260\0108\033!!Y-,\260\023CX\003\033\002Y-,\260\023CX\002\033\003Y-,\260\012+#\020 <\260\027+-,\260\002%\270\377\3608\260(+\212\020# \320#\260\020+\260\005CX\300\033<Y \020\021\260\000\022\001-,KS#KQZX8\033!!Y-,\001\260\002%\020\320#\311\001\260\001\023\260\000\024\020\260\001<\260\001\026-,\001\260\000\023\260\001\260\003%I\260\003\0278\260\001\023-,KS#KQZX E\212`D\033!!Y-, 9/-""" + + p = Program() + p.fromBytecode(bc) + asm = p.getAssembly(preserve=True) + p.fromAssembly(asm) + print(bc == p.getBytecode()) + + +if __name__ == "__main__": + import sys + import doctest + + sys.exit(doctest.testmod().failed) diff --git a/.venv/lib/python3.13/site-packages/fontTools/ufoLib/__init__.py b/.venv/lib/python3.13/site-packages/fontTools/ufoLib/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ca409bdd5671238545175ed168609b9e67762dd8 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ufoLib/__init__.py @@ -0,0 +1,2575 @@ +""" +A library for importing .ufo files and their descendants. +Refer to http://unifiedfontobject.org for the UFO specification. + +The main interfaces are the :class:`.UFOReader` and :class:`.UFOWriter` +classes, which support versions 1, 2, and 3 of the UFO specification. + +Set variables are available for external use that list the font +info attribute names for the `fontinfo.plist` formats. These are: + +- :obj:`.fontInfoAttributesVersion1` +- :obj:`.fontInfoAttributesVersion2` +- :obj:`.fontInfoAttributesVersion3` + +A set listing the `fontinfo.plist` attributes that were deprecated +in version 2 is available for external use: + +- :obj:`.deprecatedFontInfoAttributesVersion2` + +Functions that do basic validation on values for `fontinfo.plist` +are available for external use. These are + +- :func:`.validateFontInfoVersion2ValueForAttribute` +- :func:`.validateFontInfoVersion3ValueForAttribute` + +Value conversion functions are available for converting +`fontinfo.plist` values between the possible format versions. + +- :func:`.convertFontInfoValueForAttributeFromVersion1ToVersion2` +- :func:`.convertFontInfoValueForAttributeFromVersion2ToVersion1` +- :func:`.convertFontInfoValueForAttributeFromVersion2ToVersion3` +- :func:`.convertFontInfoValueForAttributeFromVersion3ToVersion2` +""" + +from __future__ import annotations + +import enum +import logging +import os +import zipfile +from collections import OrderedDict +from copy import deepcopy +from os import fsdecode +from typing import IO, TYPE_CHECKING, Any, Optional, Union, cast + +from fontTools.misc import filesystem as fs +from fontTools.misc import plistlib +from fontTools.ufoLib.converters import convertUFO1OrUFO2KerningToUFO3Kerning +from fontTools.ufoLib.errors import UFOLibError +from fontTools.ufoLib.filenames import userNameToFileName +from fontTools.ufoLib.utils import ( + BaseFormatVersion, + normalizeFormatVersion, + numberTypes, +) +from fontTools.ufoLib.validators import * + +if TYPE_CHECKING: + from logging import Logger + + from fontTools.annotations import ( + GlyphNameToFileNameFunc, + K, + KerningDict, + KerningGroups, + KerningNested, + PathOrFS, + PathStr, + UFOFormatVersionInput, + V, + ) + from fontTools.misc.filesystem._base import FS + from fontTools.ufoLib.glifLib import GlyphSet + +KerningGroupRenameMaps = dict[str, dict[str, str]] +LibDict = dict[str, Any] +LayerOrderList = Optional[list[Optional[str]]] +AttributeDataDict = dict[str, Any] +FontInfoAttributes = dict[str, AttributeDataDict] + +# client code can check this to see if the upstream `fs` package is being used +haveFS = fs._haveFS + +__all__: list[str] = [ + "haveFS", + "makeUFOPath", + "UFOLibError", + "UFOReader", + "UFOWriter", + "UFOReaderWriter", + "UFOFileStructure", + "fontInfoAttributesVersion1", + "fontInfoAttributesVersion2", + "fontInfoAttributesVersion3", + "deprecatedFontInfoAttributesVersion2", + "validateFontInfoVersion2ValueForAttribute", + "validateFontInfoVersion3ValueForAttribute", + "convertFontInfoValueForAttributeFromVersion1ToVersion2", + "convertFontInfoValueForAttributeFromVersion2ToVersion1", +] + +__version__: str = "3.0.0" + + +logger: Logger = logging.getLogger(__name__) + + +# --------- +# Constants +# --------- + +DEFAULT_GLYPHS_DIRNAME: str = "glyphs" +DATA_DIRNAME: str = "data" +IMAGES_DIRNAME: str = "images" +METAINFO_FILENAME: str = "metainfo.plist" +FONTINFO_FILENAME: str = "fontinfo.plist" +LIB_FILENAME: str = "lib.plist" +GROUPS_FILENAME: str = "groups.plist" +KERNING_FILENAME: str = "kerning.plist" +FEATURES_FILENAME: str = "features.fea" +LAYERCONTENTS_FILENAME: str = "layercontents.plist" +LAYERINFO_FILENAME: str = "layerinfo.plist" + +DEFAULT_LAYER_NAME: str = "public.default" + + +class UFOFormatVersion(BaseFormatVersion): + FORMAT_1_0 = (1, 0) + FORMAT_2_0 = (2, 0) + FORMAT_3_0 = (3, 0) + + +class UFOFileStructure(enum.Enum): + ZIP = "zip" + PACKAGE = "package" + + +# -------------- +# Shared Methods +# -------------- + + +class _UFOBaseIO: + if TYPE_CHECKING: + fs: FS + _havePreviousFile: bool + + def getFileModificationTime(self, path: PathStr) -> Optional[float]: + """ + Returns the modification time for the file at the given path, as a + floating point number giving the number of seconds since the epoch. + The path must be relative to the UFO path. + Returns None if the file does not exist. + """ + try: + dt = self.fs.getinfo(fsdecode(path), namespaces=["details"]).modified + except (fs.errors.MissingInfoNamespace, fs.errors.ResourceNotFound): + return None + else: + if dt is not None: + return dt.timestamp() + return None + + def _getPlist(self, fileName: str, default: Optional[Any] = None) -> Any: + """ + Read a property list relative to the UFO filesystem's root. + Raises UFOLibError if the file is missing and default is None, + otherwise default is returned. + + The errors that could be raised during the reading of a plist are + unpredictable and/or too large to list, so, a blind try: except: + is done. If an exception occurs, a UFOLibError will be raised. + """ + try: + with self.fs.open(fileName, "rb") as f: + return plistlib.load(f) + except fs.errors.ResourceNotFound: + if default is None: + raise UFOLibError( + "'%s' is missing on %s. This file is required" % (fileName, self.fs) + ) + else: + return default + except Exception as e: + # TODO(anthrotype): try to narrow this down a little + raise UFOLibError(f"'{fileName}' could not be read on {self.fs}: {e}") + + def _writePlist(self, fileName: str, obj: Any) -> None: + """ + Write a property list to a file relative to the UFO filesystem's root. + + Do this sort of atomically, making it harder to corrupt existing files, + for example when plistlib encounters an error halfway during write. + This also checks to see if text matches the text that is already in the + file at path. If so, the file is not rewritten so that the modification + date is preserved. + + The errors that could be raised during the writing of a plist are + unpredictable and/or too large to list, so, a blind try: except: is done. + If an exception occurs, a UFOLibError will be raised. + """ + if self._havePreviousFile: + try: + data = plistlib.dumps(obj) + except Exception as e: + raise UFOLibError( + "'%s' could not be written on %s because " + "the data is not properly formatted: %s" % (fileName, self.fs, e) + ) + if self.fs.exists(fileName) and data == self.fs.readbytes(fileName): + return + self.fs.writebytes(fileName, data) + else: + with self.fs.open(fileName, mode="wb") as fp: + try: + plistlib.dump(obj, fp) + except Exception as e: + raise UFOLibError( + "'%s' could not be written on %s because " + "the data is not properly formatted: %s" + % (fileName, self.fs, e) + ) + + +# ---------- +# UFO Reader +# ---------- + + +class UFOReader(_UFOBaseIO): + """Read the various components of a .ufo. + + Attributes: + path: An :class:`os.PathLike` object pointing to the .ufo. + validate: A boolean indicating if the data read should be + validated. Defaults to `True`. + + By default read data is validated. Set ``validate`` to + ``False`` to not validate the data. + """ + + def __init__(self, path: PathOrFS, validate: bool = True) -> None: + # Only call __fspath__ if path is not already a str or FS object + if not isinstance(path, (str, fs.base.FS)) and hasattr(path, "__fspath__"): + path = path.__fspath__() + + if isinstance(path, str): + structure = _sniffFileStructure(path) + parentFS: FS + try: + if structure is UFOFileStructure.ZIP: + parentFS = fs.zipfs.ZipFS(path, write=False, encoding="utf-8") # type: ignore[abstract] + else: + parentFS = fs.osfs.OSFS(path) + except fs.errors.CreateFailed as e: + raise UFOLibError(f"unable to open '{path}': {e}") + + if structure is UFOFileStructure.ZIP: + # .ufoz zip files must contain a single root directory, with arbitrary + # name, containing all the UFO files + rootDirs = [ + p.name + for p in parentFS.scandir("/") + # exclude macOS metadata contained in zip file + if p.is_dir and p.name != "__MACOSX" + ] + if len(rootDirs) == 1: + # 'ClosingSubFS' ensures that the parent zip file is closed when + # its root subdirectory is closed + self.fs: FS = parentFS.opendir( + rootDirs[0], factory=fs.subfs.ClosingSubFS + ) + else: + raise UFOLibError( + "Expected exactly 1 root directory, found %d" % len(rootDirs) + ) + else: + # normal UFO 'packages' are just a single folder + self.fs = parentFS + # when passed a path string, we make sure we close the newly opened fs + # upon calling UFOReader.close method or context manager's __exit__ + self._shouldClose: bool = True + self._fileStructure = structure + elif isinstance(path, fs.base.FS): + filesystem: FS = path + try: + filesystem.check() + except fs.errors.FilesystemClosed: + raise UFOLibError("the filesystem '%s' is closed" % path) + else: + self.fs = filesystem + try: + path = filesystem.getsyspath("/") + except fs.errors.NoSysPath: + # network or in-memory FS may not map to the local one + path = str(filesystem) + # when user passed an already initialized fs instance, it is her + # responsibility to close it, thus UFOReader.close/__exit__ are no-op + self._shouldClose = False + # default to a 'package' structure + self._fileStructure = UFOFileStructure.PACKAGE + else: + raise TypeError( + "Expected a path string or fs.base.FS object, found '%s'" + % type(path).__name__ + ) + self._path: str = fsdecode(path) + self._validate: bool = validate + self._upConvertedKerningData: Optional[dict[str, Any]] = None + + try: + self.readMetaInfo(validate=validate) + except UFOLibError: + self.close() + raise + + # properties + + def _get_path(self) -> str: + import warnings + + warnings.warn( + "The 'path' attribute is deprecated; use the 'fs' attribute instead", + DeprecationWarning, + stacklevel=2, + ) + return self._path + + path: property = property(_get_path, doc="The path of the UFO (DEPRECATED).") + + def _get_formatVersion(self) -> int: + import warnings + + warnings.warn( + "The 'formatVersion' attribute is deprecated; use the 'formatVersionTuple'", + DeprecationWarning, + stacklevel=2, + ) + return self._formatVersion.major + + formatVersion = property( + _get_formatVersion, + doc="The (major) format version of the UFO. DEPRECATED: Use formatVersionTuple", + ) + + @property + def formatVersionTuple(self) -> tuple[int, int]: + """The (major, minor) format version of the UFO. + This is determined by reading metainfo.plist during __init__. + """ + return self._formatVersion + + def _get_fileStructure(self) -> Any: + return self._fileStructure + + fileStructure: property = property( + _get_fileStructure, + doc=( + "The file structure of the UFO: " + "either UFOFileStructure.ZIP or UFOFileStructure.PACKAGE" + ), + ) + + # up conversion + + def _upConvertKerning(self, validate: bool) -> None: + """ + Up convert kerning and groups in UFO 1 and 2. + The data will be held internally until each bit of data + has been retrieved. The conversion of both must be done + at once, so the raw data is cached and an error is raised + if one bit of data becomes obsolete before it is called. + + ``validate`` will validate the data. + """ + if self._upConvertedKerningData: + testKerning = self._readKerning() + if testKerning != self._upConvertedKerningData["originalKerning"]: + raise UFOLibError( + "The data in kerning.plist has been modified since it was converted to UFO 3 format." + ) + testGroups = self._readGroups() + if testGroups != self._upConvertedKerningData["originalGroups"]: + raise UFOLibError( + "The data in groups.plist has been modified since it was converted to UFO 3 format." + ) + else: + groups = self._readGroups() + if validate: + invalidFormatMessage = "groups.plist is not properly formatted." + if not isinstance(groups, dict): + raise UFOLibError(invalidFormatMessage) + for groupName, glyphList in groups.items(): + if not isinstance(groupName, str): + raise UFOLibError(invalidFormatMessage) + elif not isinstance(glyphList, list): + raise UFOLibError(invalidFormatMessage) + for glyphName in glyphList: + if not isinstance(glyphName, str): + raise UFOLibError(invalidFormatMessage) + self._upConvertedKerningData = dict( + kerning={}, + originalKerning=self._readKerning(), + groups={}, + originalGroups=groups, + ) + # convert kerning and groups + kerning, groups, conversionMaps = convertUFO1OrUFO2KerningToUFO3Kerning( + self._upConvertedKerningData["originalKerning"], + deepcopy(self._upConvertedKerningData["originalGroups"]), + self.getGlyphSet(), + ) + # store + self._upConvertedKerningData["kerning"] = kerning + self._upConvertedKerningData["groups"] = groups + self._upConvertedKerningData["groupRenameMaps"] = conversionMaps + + # support methods + + def readBytesFromPath(self, path: PathStr) -> Optional[bytes]: + """ + Returns the bytes in the file at the given path. + The path must be relative to the UFO's filesystem root. + Returns None if the file does not exist. + """ + try: + return self.fs.readbytes(fsdecode(path)) + except fs.errors.ResourceNotFound: + return None + + def getReadFileForPath( + self, path: PathStr, encoding: Optional[str] = None + ) -> Optional[Union[IO[bytes], IO[str]]]: + """ + Returns a file (or file-like) object for the file at the given path. + The path must be relative to the UFO path. + Returns None if the file does not exist. + By default the file is opened in binary mode (reads bytes). + If encoding is passed, the file is opened in text mode (reads str). + + Note: The caller is responsible for closing the open file. + """ + path = fsdecode(path) + try: + if encoding is None: + return self.fs.open(path, mode="rb") + else: + return self.fs.open(path, mode="r", encoding=encoding) + except fs.errors.ResourceNotFound: + return None + + # metainfo.plist + + def _readMetaInfo(self, validate: Optional[bool] = None) -> dict[str, Any]: + """ + Read metainfo.plist and return raw data. Only used for internal operations. + + ``validate`` will validate the read data, by default it is set + to the class's validate value, can be overridden. + """ + if validate is None: + validate = self._validate + data = self._getPlist(METAINFO_FILENAME) + if validate and not isinstance(data, dict): + raise UFOLibError("metainfo.plist is not properly formatted.") + try: + formatVersionMajor = data["formatVersion"] + except KeyError: + raise UFOLibError( + f"Missing required formatVersion in '{METAINFO_FILENAME}' on {self.fs}" + ) + formatVersionMinor = data.setdefault("formatVersionMinor", 0) + + try: + formatVersion = UFOFormatVersion((formatVersionMajor, formatVersionMinor)) + except ValueError as e: + unsupportedMsg = ( + f"Unsupported UFO format ({formatVersionMajor}.{formatVersionMinor}) " + f"in '{METAINFO_FILENAME}' on {self.fs}" + ) + if validate: + from fontTools.ufoLib.errors import UnsupportedUFOFormat + + raise UnsupportedUFOFormat(unsupportedMsg) from e + + formatVersion = UFOFormatVersion.default() + logger.warning( + "%s. Assuming the latest supported version (%s). " + "Some data may be skipped or parsed incorrectly", + unsupportedMsg, + formatVersion, + ) + data["formatVersionTuple"] = formatVersion + return data + + def readMetaInfo(self, validate: Optional[bool] = None) -> None: + """ + Read metainfo.plist and set formatVersion. Only used for internal operations. + + ``validate`` will validate the read data, by default it is set + to the class's validate value, can be overridden. + """ + data = self._readMetaInfo(validate=validate) + self._formatVersion = data["formatVersionTuple"] + + # groups.plist + + def _readGroups(self) -> dict[str, list[str]]: + groups = self._getPlist(GROUPS_FILENAME, {}) + # remove any duplicate glyphs in a kerning group + for groupName, glyphList in groups.items(): + if groupName.startswith(("public.kern1.", "public.kern2.")): + groups[groupName] = list(OrderedDict.fromkeys(glyphList)) + return groups + + def readGroups(self, validate: Optional[bool] = None) -> dict[str, list[str]]: + """ + Read groups.plist. Returns a dict. + ``validate`` will validate the read data, by default it is set to the + class's validate value, can be overridden. + """ + if validate is None: + validate = self._validate + # handle up conversion + if self._formatVersion < UFOFormatVersion.FORMAT_3_0: + self._upConvertKerning(validate) + groups = cast(dict, self._upConvertedKerningData)["groups"] + # normal + else: + groups = self._readGroups() + if validate: + valid, message = groupsValidator(groups) + if not valid: + raise UFOLibError(message) + return groups + + def getKerningGroupConversionRenameMaps( + self, validate: Optional[bool] = None + ) -> KerningGroupRenameMaps: + """ + Get maps defining the renaming that was done during any + needed kerning group conversion. This method returns a + dictionary of this form:: + + { + "side1" : {"old group name" : "new group name"}, + "side2" : {"old group name" : "new group name"} + } + + When no conversion has been performed, the side1 and side2 + dictionaries will be empty. + + ``validate`` will validate the groups, by default it is set to the + class's validate value, can be overridden. + """ + if validate is None: + validate = self._validate + if self._formatVersion >= UFOFormatVersion.FORMAT_3_0: + return dict(side1={}, side2={}) + # use the public group reader to force the load and + # conversion of the data if it hasn't happened yet. + self.readGroups(validate=validate) + return cast(dict, self._upConvertedKerningData)["groupRenameMaps"] + + # fontinfo.plist + + def _readInfo(self, validate: bool) -> dict[str, Any]: + data = self._getPlist(FONTINFO_FILENAME, {}) + if validate and not isinstance(data, dict): + raise UFOLibError("fontinfo.plist is not properly formatted.") + return data + + def readInfo(self, info: Any, validate: Optional[bool] = None) -> None: + """ + Read fontinfo.plist. It requires an object that allows + setting attributes with names that follow the fontinfo.plist + version 3 specification. This will write the attributes + defined in the file into the object. + + ``validate`` will validate the read data, by default it is set to the + class's validate value, can be overridden. + """ + if validate is None: + validate = self._validate + infoDict = self._readInfo(validate) + infoDataToSet = {} + # version 1 + if self._formatVersion == UFOFormatVersion.FORMAT_1_0: + for attr in fontInfoAttributesVersion1: + value = infoDict.get(attr) + if value is not None: + infoDataToSet[attr] = value + infoDataToSet = _convertFontInfoDataVersion1ToVersion2(infoDataToSet) + infoDataToSet = _convertFontInfoDataVersion2ToVersion3(infoDataToSet) + # version 2 + elif self._formatVersion == UFOFormatVersion.FORMAT_2_0: + for attr, dataValidationDict in list( + fontInfoAttributesVersion2ValueData.items() + ): + value = infoDict.get(attr) + if value is None: + continue + infoDataToSet[attr] = value + infoDataToSet = _convertFontInfoDataVersion2ToVersion3(infoDataToSet) + # version 3.x + elif self._formatVersion.major == UFOFormatVersion.FORMAT_3_0.major: + for attr, dataValidationDict in list( + fontInfoAttributesVersion3ValueData.items() + ): + value = infoDict.get(attr) + if value is None: + continue + infoDataToSet[attr] = value + # unsupported version + else: + raise NotImplementedError(self._formatVersion) + # validate data + if validate: + infoDataToSet = validateInfoVersion3Data(infoDataToSet) + # populate the object + for attr, value in list(infoDataToSet.items()): + try: + setattr(info, attr, value) + except AttributeError: + raise UFOLibError( + "The supplied info object does not support setting a necessary attribute (%s)." + % attr + ) + + # kerning.plist + + def _readKerning(self) -> KerningNested: + data = self._getPlist(KERNING_FILENAME, {}) + return data + + def readKerning(self, validate: Optional[bool] = None) -> KerningDict: + """ + Read kerning.plist. Returns a dict. + + ``validate`` will validate the kerning data, by default it is set to the + class's validate value, can be overridden. + """ + if validate is None: + validate = self._validate + # handle up conversion + if self._formatVersion < UFOFormatVersion.FORMAT_3_0: + self._upConvertKerning(validate) + kerningNested = cast(dict, self._upConvertedKerningData)["kerning"] + # normal + else: + kerningNested = self._readKerning() + if validate: + valid, message = kerningValidator(kerningNested) + if not valid: + raise UFOLibError(message) + # flatten + kerning = {} + for left in kerningNested: + for right in kerningNested[left]: + value = kerningNested[left][right] + kerning[left, right] = value + return kerning + + # lib.plist + + def readLib(self, validate: Optional[bool] = None) -> dict[str, Any]: + """ + Read lib.plist. Returns a dict. + + ``validate`` will validate the data, by default it is set to the + class's validate value, can be overridden. + """ + if validate is None: + validate = self._validate + data = self._getPlist(LIB_FILENAME, {}) + if validate: + valid, message = fontLibValidator(data) + if not valid: + raise UFOLibError(message) + return data + + # features.fea + + def readFeatures(self) -> str: + """ + Read features.fea. Return a string. + The returned string is empty if the file is missing. + """ + try: + with self.fs.open(FEATURES_FILENAME, "r", encoding="utf-8-sig") as f: + return f.read() + except fs.errors.ResourceNotFound: + return "" + + # glyph sets & layers + + def _readLayerContents(self, validate: bool) -> list[tuple[str, str]]: + """ + Rebuild the layer contents list by checking what glyphsets + are available on disk. + + ``validate`` will validate the layer contents. + """ + if self._formatVersion < UFOFormatVersion.FORMAT_3_0: + return [(DEFAULT_LAYER_NAME, DEFAULT_GLYPHS_DIRNAME)] + contents = self._getPlist(LAYERCONTENTS_FILENAME) + if validate: + valid, error = layerContentsValidator(contents, self.fs) + if not valid: + raise UFOLibError(error) + return contents + + def getLayerNames(self, validate: Optional[bool] = None) -> list[str]: + """ + Get the ordered layer names from layercontents.plist. + + ``validate`` will validate the data, by default it is set to the + class's validate value, can be overridden. + """ + if validate is None: + validate = self._validate + layerContents = self._readLayerContents(validate) + layerNames = [layerName for layerName, directoryName in layerContents] + return layerNames + + def getDefaultLayerName(self, validate: Optional[bool] = None) -> str: + """ + Get the default layer name from layercontents.plist. + + ``validate`` will validate the data, by default it is set to the + class's validate value, can be overridden. + """ + if validate is None: + validate = self._validate + layerContents = self._readLayerContents(validate) + for layerName, layerDirectory in layerContents: + if layerDirectory == DEFAULT_GLYPHS_DIRNAME: + return layerName + # this will already have been raised during __init__ + raise UFOLibError("The default layer is not defined in layercontents.plist.") + + def getGlyphSet( + self, + layerName: Optional[str] = None, + validateRead: Optional[bool] = None, + validateWrite: Optional[bool] = None, + ) -> GlyphSet: + """ + Return the GlyphSet associated with the + glyphs directory mapped to layerName + in the UFO. If layerName is not provided, + the name retrieved with getDefaultLayerName + will be used. + + ``validateRead`` will validate the read data, by default it is set to the + class's validate value, can be overridden. + ``validateWrite`` will validate the written data, by default it is set to the + class's validate value, can be overridden. + """ + from fontTools.ufoLib.glifLib import GlyphSet + + if validateRead is None: + validateRead = self._validate + if validateWrite is None: + validateWrite = self._validate + if layerName is None: + layerName = self.getDefaultLayerName(validate=validateRead) + directory = None + layerContents = self._readLayerContents(validateRead) + for storedLayerName, storedLayerDirectory in layerContents: + if layerName == storedLayerName: + directory = storedLayerDirectory + break + if directory is None: + raise UFOLibError('No glyphs directory is mapped to "%s".' % layerName) + try: + glyphSubFS = self.fs.opendir(directory) + except fs.errors.ResourceNotFound: + raise UFOLibError(f"No '{directory}' directory for layer '{layerName}'") + return GlyphSet( + glyphSubFS, + ufoFormatVersion=self._formatVersion, + validateRead=validateRead, + validateWrite=validateWrite, + expectContentsFile=True, + ) + + def getCharacterMapping( + self, layerName: Optional[str] = None, validate: Optional[bool] = None + ) -> dict[int, list[str]]: + """ + Return a dictionary that maps unicode values (ints) to + lists of glyph names. + """ + if validate is None: + validate = self._validate + glyphSet = self.getGlyphSet( + layerName, validateRead=validate, validateWrite=True + ) + allUnicodes = glyphSet.getUnicodes() + cmap: dict[int, list[str]] = {} + for glyphName, unicodes in allUnicodes.items(): + for code in unicodes: + if code in cmap: + cmap[code].append(glyphName) + else: + cmap[code] = [glyphName] + return cmap + + # /data + + def getDataDirectoryListing(self) -> list[str]: + """ + Returns a list of all files in the data directory. + The returned paths will be relative to the UFO. + This will not list directory names, only file names. + Thus, empty directories will be skipped. + """ + try: + self._dataFS = self.fs.opendir(DATA_DIRNAME) + except fs.errors.ResourceNotFound: + return [] + except fs.errors.DirectoryExpected: + raise UFOLibError('The UFO contains a "data" file instead of a directory.') + try: + # fs Walker.files method returns "absolute" paths (in terms of the + # root of the 'data' SubFS), so we strip the leading '/' to make + # them relative + return [p.lstrip("/") for p in self._dataFS.walk.files()] + except fs.errors.ResourceError: + return [] + + def getImageDirectoryListing(self, validate: Optional[bool] = None) -> list[str]: + """ + Returns a list of all image file names in + the images directory. Each of the images will + have been verified to have the PNG signature. + + ``validate`` will validate the data, by default it is set to the + class's validate value, can be overridden. + """ + if self._formatVersion < UFOFormatVersion.FORMAT_3_0: + return [] + if validate is None: + validate = self._validate + try: + self._imagesFS = imagesFS = self.fs.opendir(IMAGES_DIRNAME) + except fs.errors.ResourceNotFound: + return [] + except fs.errors.DirectoryExpected: + raise UFOLibError( + 'The UFO contains an "images" file instead of a directory.' + ) + result = [] + for path in imagesFS.scandir("/"): + if path.is_dir: + # silently skip this as version control + # systems often have hidden directories + continue + if validate: + with imagesFS.open(path.name, "rb") as fp: + valid, error = pngValidator(fileObj=fp) + if valid: + result.append(path.name) + else: + result.append(path.name) + return result + + def readData(self, fileName: PathStr) -> bytes: + """ + Return bytes for the file named 'fileName' inside the 'data/' directory. + """ + fileName = fsdecode(fileName) + try: + try: + dataFS = self._dataFS + except AttributeError: + # in case readData is called before getDataDirectoryListing + dataFS = self.fs.opendir(DATA_DIRNAME) + data = dataFS.readbytes(fileName) + except fs.errors.ResourceNotFound: + raise UFOLibError(f"No data file named '{fileName}' on {self.fs}") + return data + + def readImage(self, fileName: PathStr, validate: Optional[bool] = None) -> bytes: + """ + Return image data for the file named fileName. + + ``validate`` will validate the data, by default it is set to the + class's validate value, can be overridden. + """ + if validate is None: + validate = self._validate + if self._formatVersion < UFOFormatVersion.FORMAT_3_0: + raise UFOLibError( + f"Reading images is not allowed in UFO {self._formatVersion.major}." + ) + fileName = fsdecode(fileName) + try: + try: + imagesFS = self._imagesFS + except AttributeError: + # in case readImage is called before getImageDirectoryListing + imagesFS = self.fs.opendir(IMAGES_DIRNAME) + data = imagesFS.readbytes(fileName) + except fs.errors.ResourceNotFound: + raise UFOLibError(f"No image file named '{fileName}' on {self.fs}") + if validate: + valid, error = pngValidator(data=data) + if not valid: + raise UFOLibError(error) + return data + + def close(self) -> None: + if self._shouldClose: + self.fs.close() + + def __enter__(self) -> UFOReader: + return self + + def __exit__(self, exc_type: Any, exc_value: Any, exc_tb: Any) -> None: + self.close() + + +# ---------- +# UFO Writer +# ---------- + + +class UFOWriter(UFOReader): + """Write the various components of a .ufo. + + Attributes: + path: An :class:`os.PathLike` object pointing to the .ufo. + formatVersion: the UFO format version as a tuple of integers (major, minor), + or as a single integer for the major digit only (minor is implied to be 0). + By default, the latest formatVersion will be used; currently it is 3.0, + which is equivalent to formatVersion=(3, 0). + fileCreator: The creator of the .ufo file. Defaults to + `com.github.fonttools.ufoLib`. + structure: The internal structure of the .ufo file: either `ZIP` or `PACKAGE`. + validate: A boolean indicating if the data read should be validated. Defaults + to `True`. + + By default, the written data will be validated before writing. Set ``validate`` to + ``False`` if you do not want to validate the data. Validation can also be overriden + on a per-method level if desired. + + Raises: + UnsupportedUFOFormat: An exception indicating that the requested UFO + formatVersion is not supported. + """ + + def __init__( + self, + path: PathOrFS, + formatVersion: UFOFormatVersionInput = None, + fileCreator: str = "com.github.fonttools.ufoLib", + structure: Optional[UFOFileStructure] = None, + validate: bool = True, + ) -> None: + try: + formatVersion = normalizeFormatVersion(formatVersion, UFOFormatVersion) + except ValueError as e: + from fontTools.ufoLib.errors import UnsupportedUFOFormat + + raise UnsupportedUFOFormat( + f"Unsupported UFO format: {formatVersion!r}" + ) from e + + if hasattr(path, "__fspath__"): # support os.PathLike objects + path = path.__fspath__() + + if isinstance(path, str): + # normalize path by removing trailing or double slashes + path = os.path.normpath(path) + havePreviousFile = os.path.exists(path) + if havePreviousFile: + # ensure we use the same structure as the destination + existingStructure = _sniffFileStructure(path) + if structure is not None: + try: + structure = UFOFileStructure(structure) + except ValueError: + raise UFOLibError( + "Invalid or unsupported structure: '%s'" % structure + ) + if structure is not existingStructure: + raise UFOLibError( + "A UFO with a different structure (%s) already exists " + "at the given path: '%s'" % (existingStructure, path) + ) + else: + structure = existingStructure + else: + # if not exists, default to 'package' structure + if structure is None: + structure = UFOFileStructure.PACKAGE + dirName = os.path.dirname(path) + if dirName and not os.path.isdir(dirName): + raise UFOLibError( + "Cannot write to '%s': directory does not exist" % path + ) + if structure is UFOFileStructure.ZIP: + if havePreviousFile: + # we can't write a zip in-place, so we have to copy its + # contents to a temporary location and work from there, then + # upon closing UFOWriter we create the final zip file + parentFS: FS = fs.tempfs.TempFS() + with fs.zipfs.ZipFS(path, encoding="utf-8") as origFS: # type: ignore[abstract] + fs.copy.copy_fs(origFS, parentFS) + # if output path is an existing zip, we require that it contains + # one, and only one, root directory (with arbitrary name), in turn + # containing all the existing UFO contents + rootDirs = [ + p.name + for p in parentFS.scandir("/") + # exclude macOS metadata contained in zip file + if p.is_dir and p.name != "__MACOSX" + ] + if len(rootDirs) != 1: + raise UFOLibError( + "Expected exactly 1 root directory, found %d" + % len(rootDirs) + ) + else: + rootDir = rootDirs[0] + else: + # if the output zip file didn't exist, we create the root folder; + # we name it the same as input 'path', but with '.ufo' extension + rootDir = os.path.splitext(os.path.basename(path))[0] + ".ufo" + parentFS = fs.zipfs.ZipFS(path, write=True, encoding="utf-8") # type: ignore[abstract] + parentFS.makedir(rootDir) + # 'ClosingSubFS' ensures that the parent filesystem is closed + # when its root subdirectory is closed + self.fs = parentFS.opendir(rootDir, factory=fs.subfs.ClosingSubFS) + else: + self.fs = fs.osfs.OSFS(path, create=True) + self._fileStructure = structure + self._havePreviousFile = havePreviousFile + self._shouldClose = True + elif isinstance(path, fs.base.FS): + filesystem: FS = path + try: + filesystem.check() + except fs.errors.FilesystemClosed: + raise UFOLibError("the filesystem '%s' is closed" % path) + else: + self.fs = filesystem + try: + path = filesystem.getsyspath("/") + except fs.errors.NoSysPath: + # network or in-memory FS may not map to the local one + path = str(filesystem) + # if passed an FS object, always use 'package' structure + if structure and structure is not UFOFileStructure.PACKAGE: + import warnings + + warnings.warn( + "The 'structure' argument is not used when input is an FS object", + UserWarning, + stacklevel=2, + ) + self._fileStructure = UFOFileStructure.PACKAGE + # if FS contains a "metainfo.plist", we consider it non-empty + self._havePreviousFile = filesystem.exists(METAINFO_FILENAME) + # the user is responsible for closing the FS object + self._shouldClose = False + else: + raise TypeError( + "Expected a path string or fs object, found %s" % type(path).__name__ + ) + + # establish some basic stuff + self._path = fsdecode(path) + self._formatVersion = formatVersion + self._fileCreator = fileCreator + self._downConversionKerningData: Optional[KerningGroupRenameMaps] = None + self._validate = validate + # if the file already exists, get the format version. + # this will be needed for up and down conversion. + previousFormatVersion = None + if self._havePreviousFile: + metaInfo = self._readMetaInfo(validate=validate) + previousFormatVersion = metaInfo["formatVersionTuple"] + # catch down conversion + if previousFormatVersion > formatVersion: + from fontTools.ufoLib.errors import UnsupportedUFOFormat + + raise UnsupportedUFOFormat( + "The UFO located at this path is a higher version " + f"({previousFormatVersion}) than the version ({formatVersion}) " + "that is trying to be written. This is not supported." + ) + # handle the layer contents + self.layerContents: Union[dict[str, str], OrderedDict[str, str]] = {} + if previousFormatVersion is not None and previousFormatVersion.major >= 3: + # already exists + self.layerContents = OrderedDict(self._readLayerContents(validate)) + else: + # previous < 3 + # imply the layer contents + if self.fs.exists(DEFAULT_GLYPHS_DIRNAME): + self.layerContents = {DEFAULT_LAYER_NAME: DEFAULT_GLYPHS_DIRNAME} + # write the new metainfo + self._writeMetaInfo() + + # properties + + def _get_fileCreator(self) -> str: + return self._fileCreator + + fileCreator: property = property( + _get_fileCreator, + doc="The file creator of the UFO. This is set into metainfo.plist during __init__.", + ) + + # support methods for file system interaction + + def copyFromReader( + self, reader: UFOReader, sourcePath: PathStr, destPath: PathStr + ) -> None: + """ + Copy the sourcePath in the provided UFOReader to destPath + in this writer. The paths must be relative. This works with + both individual files and directories. + """ + if not isinstance(reader, UFOReader): + raise UFOLibError("The reader must be an instance of UFOReader.") + sourcePath = fsdecode(sourcePath) + destPath = fsdecode(destPath) + if not reader.fs.exists(sourcePath): + raise UFOLibError( + 'The reader does not have data located at "%s".' % sourcePath + ) + if self.fs.exists(destPath): + raise UFOLibError('A file named "%s" already exists.' % destPath) + # create the destination directory if it doesn't exist + self.fs.makedirs(fs.path.dirname(destPath), recreate=True) + if reader.fs.isdir(sourcePath): + fs.copy.copy_dir(reader.fs, sourcePath, self.fs, destPath) + else: + fs.copy.copy_file(reader.fs, sourcePath, self.fs, destPath) + + def writeBytesToPath(self, path: PathStr, data: bytes) -> None: + """ + Write bytes to a path relative to the UFO filesystem's root. + If writing to an existing UFO, check to see if data matches the data + that is already in the file at path; if so, the file is not rewritten + so that the modification date is preserved. + If needed, the directory tree for the given path will be built. + """ + path = fsdecode(path) + if self._havePreviousFile: + if self.fs.isfile(path) and data == self.fs.readbytes(path): + return + try: + self.fs.writebytes(path, data) + except fs.errors.FileExpected: + raise UFOLibError("A directory exists at '%s'" % path) + except fs.errors.ResourceNotFound: + self.fs.makedirs(fs.path.dirname(path), recreate=True) + self.fs.writebytes(path, data) + + def getFileObjectForPath( + self, + path: PathStr, + mode: str = "w", + encoding: Optional[str] = None, + ) -> Optional[IO[Any]]: + """ + Returns a file (or file-like) object for the + file at the given path. The path must be relative + to the UFO path. Returns None if the file does + not exist and the mode is "r" or "rb. + An encoding may be passed if the file is opened in text mode. + + Note: The caller is responsible for closing the open file. + """ + path = fsdecode(path) + try: + return self.fs.open(path, mode=mode, encoding=encoding) + except fs.errors.ResourceNotFound as e: + m = mode[0] + if m == "r": + # XXX I think we should just let it raise. The docstring, + # however, says that this returns None if mode is 'r' + return None + elif m == "w" or m == "a" or m == "x": + self.fs.makedirs(fs.path.dirname(path), recreate=True) + return self.fs.open(path, mode=mode, encoding=encoding) + except fs.errors.ResourceError as e: + raise UFOLibError(f"unable to open '{path}' on {self.fs}: {e}") + return None + + def removePath( + self, path: PathStr, force: bool = False, removeEmptyParents: bool = True + ) -> None: + """ + Remove the file (or directory) at path. The path + must be relative to the UFO. + Raises UFOLibError if the path doesn't exist. + If force=True, ignore non-existent paths. + If the directory where 'path' is located becomes empty, it will + be automatically removed, unless 'removeEmptyParents' is False. + """ + path = fsdecode(path) + try: + self.fs.remove(path) + except fs.errors.FileExpected: + self.fs.removetree(path) + except fs.errors.ResourceNotFound: + if not force: + raise UFOLibError(f"'{path}' does not exist on {self.fs}") + if removeEmptyParents: + parent = fs.path.dirname(path) + if parent: + fs.tools.remove_empty(self.fs, parent) + + # alias kept for backward compatibility with old API + removeFileForPath = removePath + + # UFO mod time + + def setModificationTime(self) -> None: + """ + Set the UFO modification time to the current time. + This is never called automatically. It is up to the + caller to call this when finished working on the UFO. + """ + path = self._path + if path is not None and os.path.exists(path): + try: + # this may fail on some filesystems (e.g. SMB servers) + os.utime(path, None) + except OSError as e: + logger.warning("Failed to set modified time: %s", e) + + # metainfo.plist + + def _writeMetaInfo(self) -> None: + metaInfo = dict( + creator=self._fileCreator, + formatVersion=self._formatVersion.major, + ) + if self._formatVersion.minor != 0: + metaInfo["formatVersionMinor"] = self._formatVersion.minor + self._writePlist(METAINFO_FILENAME, metaInfo) + + # groups.plist + + def setKerningGroupConversionRenameMaps(self, maps: KerningGroupRenameMaps) -> None: + """ + Set maps defining the renaming that should be done + when writing groups and kerning in UFO 1 and UFO 2. + This will effectively undo the conversion done when + UFOReader reads this data. The dictionary should have + this form:: + + { + "side1" : {"group name to use when writing" : "group name in data"}, + "side2" : {"group name to use when writing" : "group name in data"} + } + + This is the same form returned by UFOReader's + getKerningGroupConversionRenameMaps method. + """ + if self._formatVersion >= UFOFormatVersion.FORMAT_3_0: + return # XXX raise an error here + # flip the dictionaries + remap = {} + for side in ("side1", "side2"): + for writeName, dataName in list(maps[side].items()): + remap[dataName] = writeName + self._downConversionKerningData = dict(groupRenameMap=remap) + + def writeGroups( + self, groups: KerningGroups, validate: Optional[bool] = None + ) -> None: + """ + Write groups.plist. This method requires a + dict of glyph groups as an argument. + + ``validate`` will validate the data, by default it is set to the + class's validate value, can be overridden. + """ + if validate is None: + validate = self._validate + # validate the data structure + if validate: + valid, message = groupsValidator(groups) + if not valid: + raise UFOLibError(message) + # down convert + if ( + self._formatVersion < UFOFormatVersion.FORMAT_3_0 + and self._downConversionKerningData is not None + ): + remap = self._downConversionKerningData["groupRenameMap"] + remappedGroups = {} + # there are some edge cases here that are ignored: + # 1. if a group is being renamed to a name that + # already exists, the existing group is always + # overwritten. (this is why there are two loops + # below.) there doesn't seem to be a logical + # solution to groups mismatching and overwriting + # with the specifiecd group seems like a better + # solution than throwing an error. + # 2. if side 1 and side 2 groups are being renamed + # to the same group name there is no check to + # ensure that the contents are identical. that + # is left up to the caller. + for name, contents in list(groups.items()): + if name in remap: + continue + remappedGroups[name] = contents + for name, contents in list(groups.items()): + if name not in remap: + continue + name = remap[name] + remappedGroups[name] = contents + groups = remappedGroups + # pack and write + groupsNew = {} + for key, value in groups.items(): + groupsNew[key] = list(value) + if groupsNew: + self._writePlist(GROUPS_FILENAME, groupsNew) + elif self._havePreviousFile: + self.removePath(GROUPS_FILENAME, force=True, removeEmptyParents=False) + + # fontinfo.plist + + def writeInfo(self, info: Any, validate: Optional[bool] = None) -> None: + """ + Write info.plist. This method requires an object + that supports getting attributes that follow the + fontinfo.plist version 2 specification. Attributes + will be taken from the given object and written + into the file. + + ``validate`` will validate the data, by default it is set to the + class's validate value, can be overridden. + """ + if validate is None: + validate = self._validate + # gather version 3 data + infoData = {} + for attr in list(fontInfoAttributesVersion3ValueData.keys()): + if hasattr(info, attr): + try: + value = getattr(info, attr) + except AttributeError: + raise UFOLibError( + "The supplied info object does not support getting a necessary attribute (%s)." + % attr + ) + if value is None: + continue + infoData[attr] = value + # down convert data if necessary and validate + if self._formatVersion == UFOFormatVersion.FORMAT_3_0: + if validate: + infoData = validateInfoVersion3Data(infoData) + elif self._formatVersion == UFOFormatVersion.FORMAT_2_0: + infoData = _convertFontInfoDataVersion3ToVersion2(infoData) + if validate: + infoData = validateInfoVersion2Data(infoData) + elif self._formatVersion == UFOFormatVersion.FORMAT_1_0: + infoData = _convertFontInfoDataVersion3ToVersion2(infoData) + if validate: + infoData = validateInfoVersion2Data(infoData) + infoData = _convertFontInfoDataVersion2ToVersion1(infoData) + # write file if there is anything to write + if infoData: + self._writePlist(FONTINFO_FILENAME, infoData) + + # kerning.plist + + def writeKerning( + self, kerning: KerningDict, validate: Optional[bool] = None + ) -> None: + """ + Write kerning.plist. This method requires a + dict of kerning pairs as an argument. + + This performs basic structural validation of the kerning, + but it does not check for compliance with the spec in + regards to conflicting pairs. The assumption is that the + kerning data being passed is standards compliant. + + ``validate`` will validate the data, by default it is set to the + class's validate value, can be overridden. + """ + if validate is None: + validate = self._validate + # validate the data structure + if validate: + invalidFormatMessage = "The kerning is not properly formatted." + if not isDictEnough(kerning): + raise UFOLibError(invalidFormatMessage) + for pair, value in list(kerning.items()): + if not isinstance(pair, (list, tuple)): + raise UFOLibError(invalidFormatMessage) + if not len(pair) == 2: + raise UFOLibError(invalidFormatMessage) + if not isinstance(pair[0], str): + raise UFOLibError(invalidFormatMessage) + if not isinstance(pair[1], str): + raise UFOLibError(invalidFormatMessage) + if not isinstance(value, numberTypes): + raise UFOLibError(invalidFormatMessage) + # down convert + if ( + self._formatVersion < UFOFormatVersion.FORMAT_3_0 + and self._downConversionKerningData is not None + ): + remap = self._downConversionKerningData["groupRenameMap"] + remappedKerning = {} + for (side1, side2), value in list(kerning.items()): + side1 = remap.get(side1, side1) + side2 = remap.get(side2, side2) + remappedKerning[side1, side2] = value + kerning = remappedKerning + # pack and write + kerningDict: KerningNested = {} + for left, right in kerning.keys(): + value = kerning[left, right] + if left not in kerningDict: + kerningDict[left] = {} + kerningDict[left][right] = value + if kerningDict: + self._writePlist(KERNING_FILENAME, kerningDict) + elif self._havePreviousFile: + self.removePath(KERNING_FILENAME, force=True, removeEmptyParents=False) + + # lib.plist + + def writeLib(self, libDict: LibDict, validate: Optional[bool] = None) -> None: + """ + Write lib.plist. This method requires a + lib dict as an argument. + + ``validate`` will validate the data, by default it is set to the + class's validate value, can be overridden. + """ + if validate is None: + validate = self._validate + if validate: + valid, message = fontLibValidator(libDict) + if not valid: + raise UFOLibError(message) + if libDict: + self._writePlist(LIB_FILENAME, libDict) + elif self._havePreviousFile: + self.removePath(LIB_FILENAME, force=True, removeEmptyParents=False) + + # features.fea + + def writeFeatures(self, features: str, validate: Optional[bool] = None) -> None: + """ + Write features.fea. This method requires a + features string as an argument. + """ + if validate is None: + validate = self._validate + if self._formatVersion == UFOFormatVersion.FORMAT_1_0: + raise UFOLibError("features.fea is not allowed in UFO Format Version 1.") + if validate: + if not isinstance(features, str): + raise UFOLibError("The features are not text.") + if features: + self.writeBytesToPath(FEATURES_FILENAME, features.encode("utf8")) + elif self._havePreviousFile: + self.removePath(FEATURES_FILENAME, force=True, removeEmptyParents=False) + + # glyph sets & layers + + def writeLayerContents( + self, layerOrder: LayerOrderList = None, validate: Optional[bool] = None + ) -> None: + """ + Write the layercontents.plist file. This method *must* be called + after all glyph sets have been written. + """ + if validate is None: + validate = self._validate + if self._formatVersion < UFOFormatVersion.FORMAT_3_0: + return + if layerOrder is not None: + newOrder: list[Optional[str]] = [] + for layerName in layerOrder: + if layerName is None: + layerName = DEFAULT_LAYER_NAME + newOrder.append(layerName) + layerOrder = newOrder + else: + layerOrder = list(self.layerContents.keys()) + if validate and set(layerOrder) != set(self.layerContents.keys()): + raise UFOLibError( + "The layer order content does not match the glyph sets that have been created." + ) + layerContents = [ + (layerName, self.layerContents[layerName]) + for layerName in layerOrder + if layerName is not None + ] + self._writePlist(LAYERCONTENTS_FILENAME, layerContents) + + def _findDirectoryForLayerName(self, layerName: Optional[str]) -> str: + foundDirectory = None + for existingLayerName, directoryName in list(self.layerContents.items()): + if layerName is None and directoryName == DEFAULT_GLYPHS_DIRNAME: + foundDirectory = directoryName + break + elif existingLayerName == layerName: + foundDirectory = directoryName + break + if not foundDirectory: + raise UFOLibError( + "Could not locate a glyph set directory for the layer named %s." + % layerName + ) + return foundDirectory + + def getGlyphSet( # type: ignore[override] + self, + layerName: Optional[str] = None, + defaultLayer: bool = True, + glyphNameToFileNameFunc: GlyphNameToFileNameFunc = None, + validateRead: Optional[bool] = None, + validateWrite: Optional[bool] = None, + expectContentsFile: bool = False, + ) -> GlyphSet: + """ + Return the GlyphSet object associated with the + appropriate glyph directory in the .ufo. + If layerName is None, the default glyph set + will be used. The defaultLayer flag indictes + that the layer should be saved into the default + glyphs directory. + + ``validateRead`` will validate the read data, by default it is set to the + class's validate value, can be overridden. + ``validateWrte`` will validate the written data, by default it is set to the + class's validate value, can be overridden. + ``expectContentsFile`` will raise a GlifLibError if a contents.plist file is + not found on the glyph set file system. This should be set to ``True`` if you + are reading an existing UFO and ``False`` if you use ``getGlyphSet`` to create + a fresh glyph set. + """ + if validateRead is None: + validateRead = self._validate + if validateWrite is None: + validateWrite = self._validate + # only default can be written in < 3 + if self._formatVersion < UFOFormatVersion.FORMAT_3_0 and ( + not defaultLayer or layerName is not None + ): + raise UFOLibError( + f"Only the default layer can be writen in UFO {self._formatVersion.major}." + ) + # locate a layer name when None has been given + if layerName is None and defaultLayer: + for existingLayerName, directory in self.layerContents.items(): + if directory == DEFAULT_GLYPHS_DIRNAME: + layerName = existingLayerName + if layerName is None: + layerName = DEFAULT_LAYER_NAME + elif layerName is None and not defaultLayer: + raise UFOLibError("A layer name must be provided for non-default layers.") + # move along to format specific writing + if self._formatVersion < UFOFormatVersion.FORMAT_3_0: + return self._getDefaultGlyphSet( + validateRead, + validateWrite, + glyphNameToFileNameFunc=glyphNameToFileNameFunc, + expectContentsFile=expectContentsFile, + ) + elif self._formatVersion.major == UFOFormatVersion.FORMAT_3_0.major: + return self._getGlyphSetFormatVersion3( + validateRead, + validateWrite, + layerName=layerName, + defaultLayer=defaultLayer, + glyphNameToFileNameFunc=glyphNameToFileNameFunc, + expectContentsFile=expectContentsFile, + ) + else: + raise NotImplementedError(self._formatVersion) + + def _getDefaultGlyphSet( + self, + validateRead: bool, + validateWrite: bool, + glyphNameToFileNameFunc: GlyphNameToFileNameFunc = None, + expectContentsFile: bool = False, + ) -> GlyphSet: + from fontTools.ufoLib.glifLib import GlyphSet + + glyphSubFS = self.fs.makedir(DEFAULT_GLYPHS_DIRNAME, recreate=True) + return GlyphSet( + glyphSubFS, + glyphNameToFileNameFunc=glyphNameToFileNameFunc, + ufoFormatVersion=self._formatVersion, + validateRead=validateRead, + validateWrite=validateWrite, + expectContentsFile=expectContentsFile, + ) + + def _getGlyphSetFormatVersion3( + self, + validateRead: bool, + validateWrite: bool, + layerName: Optional[str] = None, + defaultLayer: bool = True, + glyphNameToFileNameFunc: GlyphNameToFileNameFunc = None, + expectContentsFile: bool = False, + ) -> GlyphSet: + from fontTools.ufoLib.glifLib import GlyphSet + + # if the default flag is on, make sure that the default in the file + # matches the default being written. also make sure that this layer + # name is not already linked to a non-default layer. + if defaultLayer: + for existingLayerName, directory in self.layerContents.items(): + if directory == DEFAULT_GLYPHS_DIRNAME: + if existingLayerName != layerName: + raise UFOLibError( + "Another layer ('%s') is already mapped to the default directory." + % existingLayerName + ) + elif existingLayerName == layerName: + raise UFOLibError( + "The layer name is already mapped to a non-default layer." + ) + + # handle layerName is None to avoid MyPy errors + if layerName is None: + raise TypeError("'leyerName' cannot be None.") + + # get an existing directory name + if layerName in self.layerContents: + directory = self.layerContents[layerName] + # get a new directory name + else: + if defaultLayer: + directory = DEFAULT_GLYPHS_DIRNAME + else: + # not caching this could be slightly expensive, + # but caching it will be cumbersome + existing = {d.lower() for d in self.layerContents.values()} + directory = userNameToFileName( + layerName, existing=existing, prefix="glyphs." + ) + # make the directory + glyphSubFS = self.fs.makedir(directory, recreate=True) + # store the mapping + self.layerContents[layerName] = directory + # load the glyph set + return GlyphSet( + glyphSubFS, + glyphNameToFileNameFunc=glyphNameToFileNameFunc, + ufoFormatVersion=self._formatVersion, + validateRead=validateRead, + validateWrite=validateWrite, + expectContentsFile=expectContentsFile, + ) + + def renameGlyphSet( + self, + layerName: Optional[str], + newLayerName: Optional[str], + defaultLayer: bool = False, + ) -> None: + """ + Rename a glyph set. + + Note: if a GlyphSet object has already been retrieved for + layerName, it is up to the caller to inform that object that + the directory it represents has changed. + """ + if self._formatVersion < UFOFormatVersion.FORMAT_3_0: + # ignore renaming glyph sets for UFO1 UFO2 + # just write the data from the default layer + return + # the new and old names can be the same + # as long as the default is being switched + if layerName is not None and layerName == newLayerName: + # if the default is off and the layer is already not the default, skip + if ( + self.layerContents[layerName] != DEFAULT_GLYPHS_DIRNAME + and not defaultLayer + ): + return + # if the default is on and the layer is already the default, skip + if self.layerContents[layerName] == DEFAULT_GLYPHS_DIRNAME and defaultLayer: + return + else: + # make sure the new layer name doesn't already exist + if newLayerName is None: + newLayerName = DEFAULT_LAYER_NAME + if newLayerName in self.layerContents: + raise UFOLibError("A layer named %s already exists." % newLayerName) + # make sure the default layer doesn't already exist + if defaultLayer and DEFAULT_GLYPHS_DIRNAME in self.layerContents.values(): + raise UFOLibError("A default layer already exists.") + # get the paths + oldDirectory = self._findDirectoryForLayerName(layerName) + if defaultLayer: + newDirectory = DEFAULT_GLYPHS_DIRNAME + else: + existing = {name.lower() for name in self.layerContents.values()} + newDirectory = userNameToFileName( + newLayerName, existing=existing, prefix="glyphs." + ) + # update the internal mapping + if layerName is not None: + del self.layerContents[layerName] + self.layerContents[newLayerName] = newDirectory + # do the file system copy + self.fs.movedir(oldDirectory, newDirectory, create=True) + + def deleteGlyphSet(self, layerName: Optional[str]) -> None: + """ + Remove the glyph set matching layerName. + """ + if self._formatVersion < UFOFormatVersion.FORMAT_3_0: + # ignore deleting glyph sets for UFO1 UFO2 as there are no layers + # just write the data from the default layer + return + foundDirectory = self._findDirectoryForLayerName(layerName) + self.removePath(foundDirectory, removeEmptyParents=False) + if layerName is not None: + del self.layerContents[layerName] + + def writeData(self, fileName: PathStr, data: bytes) -> None: + """ + Write data to fileName in the 'data' directory. + The data must be a bytes string. + """ + self.writeBytesToPath(f"{DATA_DIRNAME}/{fsdecode(fileName)}", data) + + def removeData(self, fileName: PathStr) -> None: + """ + Remove the file named fileName from the data directory. + """ + self.removePath(f"{DATA_DIRNAME}/{fsdecode(fileName)}") + + # /images + + def writeImage( + self, + fileName: PathStr, + data: bytes, + validate: Optional[bool] = None, + ) -> None: + """ + Write data to fileName in the images directory. + The data must be a valid PNG. + """ + if validate is None: + validate = self._validate + if self._formatVersion < UFOFormatVersion.FORMAT_3_0: + raise UFOLibError( + f"Images are not allowed in UFO {self._formatVersion.major}." + ) + fileName = fsdecode(fileName) + if validate: + valid, error = pngValidator(data=data) + if not valid: + raise UFOLibError(error) + self.writeBytesToPath(f"{IMAGES_DIRNAME}/{fileName}", data) + + def removeImage( + self, + fileName: PathStr, + validate: Optional[bool] = None, + ) -> None: # XXX remove unused 'validate'? + """ + Remove the file named fileName from the + images directory. + """ + if self._formatVersion < UFOFormatVersion.FORMAT_3_0: + raise UFOLibError( + f"Images are not allowed in UFO {self._formatVersion.major}." + ) + self.removePath(f"{IMAGES_DIRNAME}/{fsdecode(fileName)}") + + def copyImageFromReader( + self, + reader: UFOReader, + sourceFileName: PathStr, + destFileName: PathStr, + validate: Optional[bool] = None, + ) -> None: + """ + Copy the sourceFileName in the provided UFOReader to destFileName + in this writer. This uses the most memory efficient method possible + for copying the data possible. + """ + if validate is None: + validate = self._validate + if self._formatVersion < UFOFormatVersion.FORMAT_3_0: + raise UFOLibError( + f"Images are not allowed in UFO {self._formatVersion.major}." + ) + sourcePath = f"{IMAGES_DIRNAME}/{fsdecode(sourceFileName)}" + destPath = f"{IMAGES_DIRNAME}/{fsdecode(destFileName)}" + self.copyFromReader(reader, sourcePath, destPath) + + def close(self) -> None: + if self._havePreviousFile and self._fileStructure is UFOFileStructure.ZIP: + # if we are updating an existing zip file, we can now compress the + # contents of the temporary filesystem in the destination path + rootDir = os.path.splitext(os.path.basename(self._path))[0] + ".ufo" + with fs.zipfs.ZipFS(self._path, write=True, encoding="utf-8") as destFS: # type: ignore[abstract] + fs.copy.copy_fs(self.fs, destFS.makedir(rootDir)) + super().close() + + +# just an alias, makes it more explicit +UFOReaderWriter = UFOWriter + + +# ---------------- +# Helper Functions +# ---------------- + + +def _sniffFileStructure(ufo_path: PathStr) -> UFOFileStructure: + """Return UFOFileStructure.ZIP if the UFO at path 'ufo_path' (str) + is a zip file, else return UFOFileStructure.PACKAGE if 'ufo_path' is a + directory. + Raise UFOLibError if it is a file with unknown structure, or if the path + does not exist. + """ + if zipfile.is_zipfile(ufo_path): + return UFOFileStructure.ZIP + elif os.path.isdir(ufo_path): + return UFOFileStructure.PACKAGE + elif os.path.isfile(ufo_path): + raise UFOLibError( + "The specified UFO does not have a known structure: '%s'" % ufo_path + ) + else: + raise UFOLibError("No such file or directory: '%s'" % ufo_path) + + +def makeUFOPath(path: PathStr) -> str: + """ + Return a .ufo pathname. + + >>> makeUFOPath("directory/something.ext") == ( + ... os.path.join('directory', 'something.ufo')) + True + >>> makeUFOPath("directory/something.another.thing.ext") == ( + ... os.path.join('directory', 'something.another.thing.ufo')) + True + """ + dir, name = os.path.split(path) + name = ".".join([".".join(name.split(".")[:-1]), "ufo"]) + return os.path.join(dir, name) + + +# ---------------------- +# fontinfo.plist Support +# ---------------------- + +# Version Validators + +# There is no version 1 validator and there shouldn't be. +# The version 1 spec was very loose and there were numerous +# cases of invalid values. + + +def validateFontInfoVersion2ValueForAttribute(attr: str, value: Any) -> bool: + """ + This performs very basic validation of the value for attribute + following the UFO 2 fontinfo.plist specification. The results + of this should not be interpretted as *correct* for the font + that they are part of. This merely indicates that the value + is of the proper type and, where the specification defines + a set range of possible values for an attribute, that the + value is in the accepted range. + """ + dataValidationDict = fontInfoAttributesVersion2ValueData[attr] + valueType = dataValidationDict.get("type") + validator = dataValidationDict.get("valueValidator", genericTypeValidator) + valueOptions = dataValidationDict.get("valueOptions") + # have specific options for the validator + if valueOptions is not None: + isValidValue = validator(value, valueOptions) + # no specific options + else: + if validator == genericTypeValidator: + isValidValue = validator(value, valueType) + else: + isValidValue = validator(value) + return isValidValue + + +def validateInfoVersion2Data(infoData: dict[str, Any]) -> dict[str, Any]: + """ + This performs very basic validation of the value for infoData + following the UFO 2 fontinfo.plist specification. The results + of this should not be interpretted as *correct* for the font + that they are part of. This merely indicates that the values + are of the proper type and, where the specification defines + a set range of possible values for an attribute, that the + value is in the accepted range. + """ + validInfoData = {} + for attr, value in list(infoData.items()): + isValidValue = validateFontInfoVersion2ValueForAttribute(attr, value) + if not isValidValue: + raise UFOLibError(f"Invalid value for attribute {attr} ({value!r}).") + else: + validInfoData[attr] = value + return validInfoData + + +def validateFontInfoVersion3ValueForAttribute(attr: str, value: Any) -> bool: + """ + This performs very basic validation of the value for attribute + following the UFO 3 fontinfo.plist specification. The results + of this should not be interpretted as *correct* for the font + that they are part of. This merely indicates that the value + is of the proper type and, where the specification defines + a set range of possible values for an attribute, that the + value is in the accepted range. + """ + dataValidationDict = fontInfoAttributesVersion3ValueData[attr] + valueType = dataValidationDict.get("type") + validator = dataValidationDict.get("valueValidator", genericTypeValidator) + valueOptions = dataValidationDict.get("valueOptions") + # have specific options for the validator + if valueOptions is not None: + isValidValue = validator(value, valueOptions) + # no specific options + else: + if validator == genericTypeValidator: + isValidValue = validator(value, valueType) + else: + isValidValue = validator(value) + return isValidValue + + +def validateInfoVersion3Data(infoData: dict[str, Any]) -> dict[str, Any]: + """ + This performs very basic validation of the value for infoData + following the UFO 3 fontinfo.plist specification. The results + of this should not be interpretted as *correct* for the font + that they are part of. This merely indicates that the values + are of the proper type and, where the specification defines + a set range of possible values for an attribute, that the + value is in the accepted range. + """ + validInfoData = {} + for attr, value in list(infoData.items()): + isValidValue = validateFontInfoVersion3ValueForAttribute(attr, value) + if not isValidValue: + raise UFOLibError(f"Invalid value for attribute {attr} ({value!r}).") + else: + validInfoData[attr] = value + return validInfoData + + +# Value Options + +fontInfoOpenTypeHeadFlagsOptions: list[int] = list(range(0, 15)) +fontInfoOpenTypeOS2SelectionOptions: list[int] = [1, 2, 3, 4, 7, 8, 9] +fontInfoOpenTypeOS2UnicodeRangesOptions: list[int] = list(range(0, 128)) +fontInfoOpenTypeOS2CodePageRangesOptions: list[int] = list(range(0, 64)) +fontInfoOpenTypeOS2TypeOptions: list[int] = [0, 1, 2, 3, 8, 9] + +# Version Attribute Definitions +# This defines the attributes, types and, in some +# cases the possible values, that can exist is +# fontinfo.plist. + +fontInfoAttributesVersion1: set[str] = { + "familyName", + "styleName", + "fullName", + "fontName", + "menuName", + "fontStyle", + "note", + "versionMajor", + "versionMinor", + "year", + "copyright", + "notice", + "trademark", + "license", + "licenseURL", + "createdBy", + "designer", + "designerURL", + "vendorURL", + "unitsPerEm", + "ascender", + "descender", + "capHeight", + "xHeight", + "defaultWidth", + "slantAngle", + "italicAngle", + "widthName", + "weightName", + "weightValue", + "fondName", + "otFamilyName", + "otStyleName", + "otMacName", + "msCharSet", + "fondID", + "uniqueID", + "ttVendor", + "ttUniqueID", + "ttVersion", +} + +fontInfoAttributesVersion2ValueData: FontInfoAttributes = { + "familyName": dict(type=str), + "styleName": dict(type=str), + "styleMapFamilyName": dict(type=str), + "styleMapStyleName": dict( + type=str, valueValidator=fontInfoStyleMapStyleNameValidator + ), + "versionMajor": dict(type=int), + "versionMinor": dict(type=int), + "year": dict(type=int), + "copyright": dict(type=str), + "trademark": dict(type=str), + "unitsPerEm": dict(type=(int, float)), + "descender": dict(type=(int, float)), + "xHeight": dict(type=(int, float)), + "capHeight": dict(type=(int, float)), + "ascender": dict(type=(int, float)), + "italicAngle": dict(type=(float, int)), + "note": dict(type=str), + "openTypeHeadCreated": dict( + type=str, valueValidator=fontInfoOpenTypeHeadCreatedValidator + ), + "openTypeHeadLowestRecPPEM": dict(type=(int, float)), + "openTypeHeadFlags": dict( + type="integerList", + valueValidator=genericIntListValidator, + valueOptions=fontInfoOpenTypeHeadFlagsOptions, + ), + "openTypeHheaAscender": dict(type=(int, float)), + "openTypeHheaDescender": dict(type=(int, float)), + "openTypeHheaLineGap": dict(type=(int, float)), + "openTypeHheaCaretSlopeRise": dict(type=int), + "openTypeHheaCaretSlopeRun": dict(type=int), + "openTypeHheaCaretOffset": dict(type=(int, float)), + "openTypeNameDesigner": dict(type=str), + "openTypeNameDesignerURL": dict(type=str), + "openTypeNameManufacturer": dict(type=str), + "openTypeNameManufacturerURL": dict(type=str), + "openTypeNameLicense": dict(type=str), + "openTypeNameLicenseURL": dict(type=str), + "openTypeNameVersion": dict(type=str), + "openTypeNameUniqueID": dict(type=str), + "openTypeNameDescription": dict(type=str), + "openTypeNamePreferredFamilyName": dict(type=str), + "openTypeNamePreferredSubfamilyName": dict(type=str), + "openTypeNameCompatibleFullName": dict(type=str), + "openTypeNameSampleText": dict(type=str), + "openTypeNameWWSFamilyName": dict(type=str), + "openTypeNameWWSSubfamilyName": dict(type=str), + "openTypeOS2WidthClass": dict( + type=int, valueValidator=fontInfoOpenTypeOS2WidthClassValidator + ), + "openTypeOS2WeightClass": dict( + type=int, valueValidator=fontInfoOpenTypeOS2WeightClassValidator + ), + "openTypeOS2Selection": dict( + type="integerList", + valueValidator=genericIntListValidator, + valueOptions=fontInfoOpenTypeOS2SelectionOptions, + ), + "openTypeOS2VendorID": dict(type=str), + "openTypeOS2Panose": dict( + type="integerList", valueValidator=fontInfoVersion2OpenTypeOS2PanoseValidator + ), + "openTypeOS2FamilyClass": dict( + type="integerList", valueValidator=fontInfoOpenTypeOS2FamilyClassValidator + ), + "openTypeOS2UnicodeRanges": dict( + type="integerList", + valueValidator=genericIntListValidator, + valueOptions=fontInfoOpenTypeOS2UnicodeRangesOptions, + ), + "openTypeOS2CodePageRanges": dict( + type="integerList", + valueValidator=genericIntListValidator, + valueOptions=fontInfoOpenTypeOS2CodePageRangesOptions, + ), + "openTypeOS2TypoAscender": dict(type=(int, float)), + "openTypeOS2TypoDescender": dict(type=(int, float)), + "openTypeOS2TypoLineGap": dict(type=(int, float)), + "openTypeOS2WinAscent": dict(type=(int, float)), + "openTypeOS2WinDescent": dict(type=(int, float)), + "openTypeOS2Type": dict( + type="integerList", + valueValidator=genericIntListValidator, + valueOptions=fontInfoOpenTypeOS2TypeOptions, + ), + "openTypeOS2SubscriptXSize": dict(type=(int, float)), + "openTypeOS2SubscriptYSize": dict(type=(int, float)), + "openTypeOS2SubscriptXOffset": dict(type=(int, float)), + "openTypeOS2SubscriptYOffset": dict(type=(int, float)), + "openTypeOS2SuperscriptXSize": dict(type=(int, float)), + "openTypeOS2SuperscriptYSize": dict(type=(int, float)), + "openTypeOS2SuperscriptXOffset": dict(type=(int, float)), + "openTypeOS2SuperscriptYOffset": dict(type=(int, float)), + "openTypeOS2StrikeoutSize": dict(type=(int, float)), + "openTypeOS2StrikeoutPosition": dict(type=(int, float)), + "openTypeVheaVertTypoAscender": dict(type=(int, float)), + "openTypeVheaVertTypoDescender": dict(type=(int, float)), + "openTypeVheaVertTypoLineGap": dict(type=(int, float)), + "openTypeVheaCaretSlopeRise": dict(type=int), + "openTypeVheaCaretSlopeRun": dict(type=int), + "openTypeVheaCaretOffset": dict(type=(int, float)), + "postscriptFontName": dict(type=str), + "postscriptFullName": dict(type=str), + "postscriptSlantAngle": dict(type=(float, int)), + "postscriptUniqueID": dict(type=int), + "postscriptUnderlineThickness": dict(type=(int, float)), + "postscriptUnderlinePosition": dict(type=(int, float)), + "postscriptIsFixedPitch": dict(type=bool), + "postscriptBlueValues": dict( + type="integerList", valueValidator=fontInfoPostscriptBluesValidator + ), + "postscriptOtherBlues": dict( + type="integerList", valueValidator=fontInfoPostscriptOtherBluesValidator + ), + "postscriptFamilyBlues": dict( + type="integerList", valueValidator=fontInfoPostscriptBluesValidator + ), + "postscriptFamilyOtherBlues": dict( + type="integerList", valueValidator=fontInfoPostscriptOtherBluesValidator + ), + "postscriptStemSnapH": dict( + type="integerList", valueValidator=fontInfoPostscriptStemsValidator + ), + "postscriptStemSnapV": dict( + type="integerList", valueValidator=fontInfoPostscriptStemsValidator + ), + "postscriptBlueFuzz": dict(type=(int, float)), + "postscriptBlueShift": dict(type=(int, float)), + "postscriptBlueScale": dict(type=(float, int)), + "postscriptForceBold": dict(type=bool), + "postscriptDefaultWidthX": dict(type=(int, float)), + "postscriptNominalWidthX": dict(type=(int, float)), + "postscriptWeightName": dict(type=str), + "postscriptDefaultCharacter": dict(type=str), + "postscriptWindowsCharacterSet": dict( + type=int, valueValidator=fontInfoPostscriptWindowsCharacterSetValidator + ), + "macintoshFONDFamilyID": dict(type=int), + "macintoshFONDName": dict(type=str), +} +fontInfoAttributesVersion2: set[str] = set(fontInfoAttributesVersion2ValueData.keys()) + +fontInfoAttributesVersion3ValueData: FontInfoAttributes = deepcopy( + fontInfoAttributesVersion2ValueData +) +fontInfoAttributesVersion3ValueData.update( + { + "versionMinor": dict(type=int, valueValidator=genericNonNegativeIntValidator), + "unitsPerEm": dict( + type=(int, float), valueValidator=genericNonNegativeNumberValidator + ), + "openTypeHeadLowestRecPPEM": dict( + type=int, valueValidator=genericNonNegativeNumberValidator + ), + "openTypeHheaAscender": dict(type=int), + "openTypeHheaDescender": dict(type=int), + "openTypeHheaLineGap": dict(type=int), + "openTypeHheaCaretOffset": dict(type=int), + "openTypeOS2Panose": dict( + type="integerList", + valueValidator=fontInfoVersion3OpenTypeOS2PanoseValidator, + ), + "openTypeOS2TypoAscender": dict(type=int), + "openTypeOS2TypoDescender": dict(type=int), + "openTypeOS2TypoLineGap": dict(type=int), + "openTypeOS2WinAscent": dict( + type=int, valueValidator=genericNonNegativeNumberValidator + ), + "openTypeOS2WinDescent": dict( + type=int, valueValidator=genericNonNegativeNumberValidator + ), + "openTypeOS2SubscriptXSize": dict(type=int), + "openTypeOS2SubscriptYSize": dict(type=int), + "openTypeOS2SubscriptXOffset": dict(type=int), + "openTypeOS2SubscriptYOffset": dict(type=int), + "openTypeOS2SuperscriptXSize": dict(type=int), + "openTypeOS2SuperscriptYSize": dict(type=int), + "openTypeOS2SuperscriptXOffset": dict(type=int), + "openTypeOS2SuperscriptYOffset": dict(type=int), + "openTypeOS2StrikeoutSize": dict(type=int), + "openTypeOS2StrikeoutPosition": dict(type=int), + "openTypeGaspRangeRecords": dict( + type="dictList", valueValidator=fontInfoOpenTypeGaspRangeRecordsValidator + ), + "openTypeNameRecords": dict( + type="dictList", valueValidator=fontInfoOpenTypeNameRecordsValidator + ), + "openTypeVheaVertTypoAscender": dict(type=int), + "openTypeVheaVertTypoDescender": dict(type=int), + "openTypeVheaVertTypoLineGap": dict(type=int), + "openTypeVheaCaretOffset": dict(type=int), + "woffMajorVersion": dict( + type=int, valueValidator=genericNonNegativeIntValidator + ), + "woffMinorVersion": dict( + type=int, valueValidator=genericNonNegativeIntValidator + ), + "woffMetadataUniqueID": dict( + type=dict, valueValidator=fontInfoWOFFMetadataUniqueIDValidator + ), + "woffMetadataVendor": dict( + type=dict, valueValidator=fontInfoWOFFMetadataVendorValidator + ), + "woffMetadataCredits": dict( + type=dict, valueValidator=fontInfoWOFFMetadataCreditsValidator + ), + "woffMetadataDescription": dict( + type=dict, valueValidator=fontInfoWOFFMetadataDescriptionValidator + ), + "woffMetadataLicense": dict( + type=dict, valueValidator=fontInfoWOFFMetadataLicenseValidator + ), + "woffMetadataCopyright": dict( + type=dict, valueValidator=fontInfoWOFFMetadataCopyrightValidator + ), + "woffMetadataTrademark": dict( + type=dict, valueValidator=fontInfoWOFFMetadataTrademarkValidator + ), + "woffMetadataLicensee": dict( + type=dict, valueValidator=fontInfoWOFFMetadataLicenseeValidator + ), + "woffMetadataExtensions": dict( + type=list, valueValidator=fontInfoWOFFMetadataExtensionsValidator + ), + "guidelines": dict(type=list, valueValidator=guidelinesValidator), + } +) +fontInfoAttributesVersion3: set[str] = set(fontInfoAttributesVersion3ValueData.keys()) + +# insert the type validator for all attrs that +# have no defined validator. +for attr, dataDict in list(fontInfoAttributesVersion2ValueData.items()): + if "valueValidator" not in dataDict: + dataDict["valueValidator"] = genericTypeValidator + +for attr, dataDict in list(fontInfoAttributesVersion3ValueData.items()): + if "valueValidator" not in dataDict: + dataDict["valueValidator"] = genericTypeValidator + +# Version Conversion Support +# These are used from converting from version 1 +# to version 2 or vice-versa. + + +def _flipDict(d: dict[K, V]) -> dict[V, K]: + flipped = {} + for key, value in list(d.items()): + flipped[value] = key + return flipped + + +fontInfoAttributesVersion1To2: dict[str, str] = { + "menuName": "styleMapFamilyName", + "designer": "openTypeNameDesigner", + "designerURL": "openTypeNameDesignerURL", + "createdBy": "openTypeNameManufacturer", + "vendorURL": "openTypeNameManufacturerURL", + "license": "openTypeNameLicense", + "licenseURL": "openTypeNameLicenseURL", + "ttVersion": "openTypeNameVersion", + "ttUniqueID": "openTypeNameUniqueID", + "notice": "openTypeNameDescription", + "otFamilyName": "openTypeNamePreferredFamilyName", + "otStyleName": "openTypeNamePreferredSubfamilyName", + "otMacName": "openTypeNameCompatibleFullName", + "weightName": "postscriptWeightName", + "weightValue": "openTypeOS2WeightClass", + "ttVendor": "openTypeOS2VendorID", + "uniqueID": "postscriptUniqueID", + "fontName": "postscriptFontName", + "fondID": "macintoshFONDFamilyID", + "fondName": "macintoshFONDName", + "defaultWidth": "postscriptDefaultWidthX", + "slantAngle": "postscriptSlantAngle", + "fullName": "postscriptFullName", + # require special value conversion + "fontStyle": "styleMapStyleName", + "widthName": "openTypeOS2WidthClass", + "msCharSet": "postscriptWindowsCharacterSet", +} +fontInfoAttributesVersion2To1 = _flipDict(fontInfoAttributesVersion1To2) +deprecatedFontInfoAttributesVersion2 = set(fontInfoAttributesVersion1To2.keys()) + +_fontStyle1To2: dict[int, str] = { + 64: "regular", + 1: "italic", + 32: "bold", + 33: "bold italic", +} +_fontStyle2To1: dict[str, int] = _flipDict(_fontStyle1To2) +# Some UFO 1 files have 0 +_fontStyle1To2[0] = "regular" + +_widthName1To2: dict[str, int] = { + "Ultra-condensed": 1, + "Extra-condensed": 2, + "Condensed": 3, + "Semi-condensed": 4, + "Medium (normal)": 5, + "Semi-expanded": 6, + "Expanded": 7, + "Extra-expanded": 8, + "Ultra-expanded": 9, +} +_widthName2To1: dict[int, str] = _flipDict(_widthName1To2) +# FontLab's default width value is "Normal". +# Many format version 1 UFOs will have this. +_widthName1To2["Normal"] = 5 +# FontLab has an "All" width value. In UFO 1 +# move this up to "Normal". +_widthName1To2["All"] = 5 +# "medium" appears in a lot of UFO 1 files. +_widthName1To2["medium"] = 5 +# "Medium" appears in a lot of UFO 1 files. +_widthName1To2["Medium"] = 5 + +_msCharSet1To2: dict[int, int] = { + 0: 1, + 1: 2, + 2: 3, + 77: 4, + 128: 5, + 129: 6, + 130: 7, + 134: 8, + 136: 9, + 161: 10, + 162: 11, + 163: 12, + 177: 13, + 178: 14, + 186: 15, + 200: 16, + 204: 17, + 222: 18, + 238: 19, + 255: 20, +} +_msCharSet2To1: dict[int, int] = _flipDict(_msCharSet1To2) + +# 1 <-> 2 + + +def convertFontInfoValueForAttributeFromVersion1ToVersion2( + attr: str, value: Any +) -> tuple[str, Any]: + """ + Convert value from version 1 to version 2 format. + Returns the new attribute name and the converted value. + If the value is None, None will be returned for the new value. + """ + # convert floats to ints if possible + if isinstance(value, float): + if int(value) == value: + value = int(value) + if value is not None: + if attr == "fontStyle": + v: Optional[Union[str, int]] = _fontStyle1To2.get(value) + if v is None: + raise UFOLibError( + f"Cannot convert value ({value!r}) for attribute {attr}." + ) + value = v + elif attr == "widthName": + v = _widthName1To2.get(value) + if v is None: + raise UFOLibError( + f"Cannot convert value ({value!r}) for attribute {attr}." + ) + value = v + elif attr == "msCharSet": + v = _msCharSet1To2.get(value) + if v is None: + raise UFOLibError( + f"Cannot convert value ({value!r}) for attribute {attr}." + ) + value = v + attr = fontInfoAttributesVersion1To2.get(attr, attr) + return attr, value + + +def convertFontInfoValueForAttributeFromVersion2ToVersion1( + attr: str, value: Any +) -> tuple[str, Any]: + """ + Convert value from version 2 to version 1 format. + Returns the new attribute name and the converted value. + If the value is None, None will be returned for the new value. + """ + if value is not None: + if attr == "styleMapStyleName": + value = _fontStyle2To1.get(value) + elif attr == "openTypeOS2WidthClass": + value = _widthName2To1.get(value) + elif attr == "postscriptWindowsCharacterSet": + value = _msCharSet2To1.get(value) + attr = fontInfoAttributesVersion2To1.get(attr, attr) + return attr, value + + +def _convertFontInfoDataVersion1ToVersion2(data: dict[str, Any]) -> dict[str, Any]: + converted = {} + for attr, value in list(data.items()): + # FontLab gives -1 for the weightValue + # for fonts wil no defined value. Many + # format version 1 UFOs will have this. + if attr == "weightValue" and value == -1: + continue + newAttr, newValue = convertFontInfoValueForAttributeFromVersion1ToVersion2( + attr, value + ) + # skip if the attribute is not part of version 2 + if newAttr not in fontInfoAttributesVersion2: + continue + # catch values that can't be converted + if value is None: + raise UFOLibError( + f"Cannot convert value ({value!r}) for attribute {newAttr}." + ) + # store + converted[newAttr] = newValue + return converted + + +def _convertFontInfoDataVersion2ToVersion1(data: dict[str, Any]) -> dict[str, Any]: + converted = {} + for attr, value in list(data.items()): + newAttr, newValue = convertFontInfoValueForAttributeFromVersion2ToVersion1( + attr, value + ) + # only take attributes that are registered for version 1 + if newAttr not in fontInfoAttributesVersion1: + continue + # catch values that can't be converted + if value is None: + raise UFOLibError( + f"Cannot convert value ({value!r}) for attribute {newAttr}." + ) + # store + converted[newAttr] = newValue + return converted + + +# 2 <-> 3 + +_ufo2To3NonNegativeInt: set[str] = { + "versionMinor", + "openTypeHeadLowestRecPPEM", + "openTypeOS2WinAscent", + "openTypeOS2WinDescent", +} +_ufo2To3NonNegativeIntOrFloat: set[str] = { + "unitsPerEm", +} +_ufo2To3FloatToInt: set[str] = { + "openTypeHeadLowestRecPPEM", + "openTypeHheaAscender", + "openTypeHheaDescender", + "openTypeHheaLineGap", + "openTypeHheaCaretOffset", + "openTypeOS2TypoAscender", + "openTypeOS2TypoDescender", + "openTypeOS2TypoLineGap", + "openTypeOS2WinAscent", + "openTypeOS2WinDescent", + "openTypeOS2SubscriptXSize", + "openTypeOS2SubscriptYSize", + "openTypeOS2SubscriptXOffset", + "openTypeOS2SubscriptYOffset", + "openTypeOS2SuperscriptXSize", + "openTypeOS2SuperscriptYSize", + "openTypeOS2SuperscriptXOffset", + "openTypeOS2SuperscriptYOffset", + "openTypeOS2StrikeoutSize", + "openTypeOS2StrikeoutPosition", + "openTypeVheaVertTypoAscender", + "openTypeVheaVertTypoDescender", + "openTypeVheaVertTypoLineGap", + "openTypeVheaCaretOffset", +} + + +def convertFontInfoValueForAttributeFromVersion2ToVersion3( + attr: str, value: Any +) -> tuple[str, Any]: + """ + Convert value from version 2 to version 3 format. + Returns the new attribute name and the converted value. + If the value is None, None will be returned for the new value. + """ + if attr in _ufo2To3FloatToInt: + try: + value = round(value) + except (ValueError, TypeError): + raise UFOLibError("Could not convert value for %s." % attr) + if attr in _ufo2To3NonNegativeInt: + try: + value = int(abs(value)) + except (ValueError, TypeError): + raise UFOLibError("Could not convert value for %s." % attr) + elif attr in _ufo2To3NonNegativeIntOrFloat: + try: + v = float(abs(value)) + except (ValueError, TypeError): + raise UFOLibError("Could not convert value for %s." % attr) + if v == int(v): + v = int(v) + if v != value: + value = v + return attr, value + + +def convertFontInfoValueForAttributeFromVersion3ToVersion2( + attr: str, value: Any +) -> tuple[str, Any]: + """ + Convert value from version 3 to version 2 format. + Returns the new attribute name and the converted value. + If the value is None, None will be returned for the new value. + """ + return attr, value + + +def _convertFontInfoDataVersion3ToVersion2(data: dict[str, Any]) -> dict[str, Any]: + converted = {} + for attr, value in list(data.items()): + newAttr, newValue = convertFontInfoValueForAttributeFromVersion3ToVersion2( + attr, value + ) + if newAttr not in fontInfoAttributesVersion2: + continue + converted[newAttr] = newValue + return converted + + +def _convertFontInfoDataVersion2ToVersion3(data: dict[str, Any]) -> dict[str, Any]: + converted = {} + for attr, value in list(data.items()): + attr, value = convertFontInfoValueForAttributeFromVersion2ToVersion3( + attr, value + ) + converted[attr] = value + return converted + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/.venv/lib/python3.13/site-packages/fontTools/ufoLib/filenames.py b/.venv/lib/python3.13/site-packages/fontTools/ufoLib/filenames.py new file mode 100644 index 0000000000000000000000000000000000000000..6a4090a75536a0dc1e3d7b7e096982d3e6287726 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ufoLib/filenames.py @@ -0,0 +1,356 @@ +from __future__ import annotations + +from collections.abc import Iterable + +""" +Convert user-provided internal UFO names to spec-compliant filenames. + +This module implements the algorithm for converting between a "user name" - +something that a user can choose arbitrarily inside a font editor - and a file +name suitable for use in a wide range of operating systems and filesystems. + +The `UFO 3 specification <http://unifiedfontobject.org/versions/ufo3/conventions/>`_ +provides an example of an algorithm for such conversion, which avoids illegal +characters, reserved file names, ambiguity between upper- and lower-case +characters, and clashes with existing files. + +This code was originally copied from +`ufoLib <https://github.com/unified-font-object/ufoLib/blob/8747da7/Lib/ufoLib/filenames.py>`_ +by Tal Leming and is copyright (c) 2005-2016, The RoboFab Developers: + +- Erik van Blokland +- Tal Leming +- Just van Rossum +""" + +# Restrictions are taken mostly from +# https://docs.microsoft.com/en-gb/windows/win32/fileio/naming-a-file#naming-conventions. +# +# 1. Integer value zero, sometimes referred to as the ASCII NUL character. +# 2. Characters whose integer representations are in the range 1 to 31, +# inclusive. +# 3. Various characters that (mostly) Windows and POSIX-y filesystems don't +# allow, plus "(" and ")", as per the specification. +illegalCharacters: set[str] = { + "\x00", + "\x01", + "\x02", + "\x03", + "\x04", + "\x05", + "\x06", + "\x07", + "\x08", + "\t", + "\n", + "\x0b", + "\x0c", + "\r", + "\x0e", + "\x0f", + "\x10", + "\x11", + "\x12", + "\x13", + "\x14", + "\x15", + "\x16", + "\x17", + "\x18", + "\x19", + "\x1a", + "\x1b", + "\x1c", + "\x1d", + "\x1e", + "\x1f", + '"', + "*", + "+", + "/", + ":", + "<", + ">", + "?", + "[", + "\\", + "]", + "(", + ")", + "|", + "\x7f", +} +reservedFileNames: set[str] = { + "aux", + "clock$", + "com1", + "com2", + "com3", + "com4", + "com5", + "com6", + "com7", + "com8", + "com9", + "con", + "lpt1", + "lpt2", + "lpt3", + "lpt4", + "lpt5", + "lpt6", + "lpt7", + "lpt8", + "lpt9", + "nul", + "prn", +} +maxFileNameLength: int = 255 + + +class NameTranslationError(Exception): + pass + + +def userNameToFileName( + userName: str, existing: Iterable[str] = (), prefix: str = "", suffix: str = "" +) -> str: + """Converts from a user name to a file name. + + Takes care to avoid illegal characters, reserved file names, ambiguity between + upper- and lower-case characters, and clashes with existing files. + + Args: + userName (str): The input file name. + existing: A case-insensitive list of all existing file names. + prefix: Prefix to be prepended to the file name. + suffix: Suffix to be appended to the file name. + + Returns: + A suitable filename. + + Raises: + NameTranslationError: If no suitable name could be generated. + + Examples:: + + >>> userNameToFileName("a") == "a" + True + >>> userNameToFileName("A") == "A_" + True + >>> userNameToFileName("AE") == "A_E_" + True + >>> userNameToFileName("Ae") == "A_e" + True + >>> userNameToFileName("ae") == "ae" + True + >>> userNameToFileName("aE") == "aE_" + True + >>> userNameToFileName("a.alt") == "a.alt" + True + >>> userNameToFileName("A.alt") == "A_.alt" + True + >>> userNameToFileName("A.Alt") == "A_.A_lt" + True + >>> userNameToFileName("A.aLt") == "A_.aL_t" + True + >>> userNameToFileName(u"A.alT") == "A_.alT_" + True + >>> userNameToFileName("T_H") == "T__H_" + True + >>> userNameToFileName("T_h") == "T__h" + True + >>> userNameToFileName("t_h") == "t_h" + True + >>> userNameToFileName("F_F_I") == "F__F__I_" + True + >>> userNameToFileName("f_f_i") == "f_f_i" + True + >>> userNameToFileName("Aacute_V.swash") == "A_acute_V_.swash" + True + >>> userNameToFileName(".notdef") == "_notdef" + True + >>> userNameToFileName("con") == "_con" + True + >>> userNameToFileName("CON") == "C_O_N_" + True + >>> userNameToFileName("con.alt") == "_con.alt" + True + >>> userNameToFileName("alt.con") == "alt._con" + True + """ + # the incoming name must be a string + if not isinstance(userName, str): + raise ValueError("The value for userName must be a string.") + # establish the prefix and suffix lengths + prefixLength = len(prefix) + suffixLength = len(suffix) + # replace an initial period with an _ + # if no prefix is to be added + if not prefix and userName[0] == ".": + userName = "_" + userName[1:] + # filter the user name + filteredUserName = [] + for character in userName: + # replace illegal characters with _ + if character in illegalCharacters: + character = "_" + # add _ to all non-lower characters + elif character != character.lower(): + character += "_" + filteredUserName.append(character) + userName = "".join(filteredUserName) + # clip to 255 + sliceLength = maxFileNameLength - prefixLength - suffixLength + userName = userName[:sliceLength] + # test for illegal files names + parts = [] + for part in userName.split("."): + if part.lower() in reservedFileNames: + part = "_" + part + parts.append(part) + userName = ".".join(parts) + # test for clash + fullName = prefix + userName + suffix + if fullName.lower() in existing: + fullName = handleClash1(userName, existing, prefix, suffix) + # finished + return fullName + + +def handleClash1( + userName: str, existing: Iterable[str] = [], prefix: str = "", suffix: str = "" +) -> str: + """A helper function that resolves collisions with existing names when choosing a filename. + + This function attempts to append an unused integer counter to the filename. + + Args: + userName (str): The input file name. + existing: A case-insensitive list of all existing file names. + prefix: Prefix to be prepended to the file name. + suffix: Suffix to be appended to the file name. + + Returns: + A suitable filename. + + >>> prefix = ("0" * 5) + "." + >>> suffix = "." + ("0" * 10) + >>> existing = ["a" * 5] + + >>> e = list(existing) + >>> handleClash1(userName="A" * 5, existing=e, + ... prefix=prefix, suffix=suffix) == ( + ... '00000.AAAAA000000000000001.0000000000') + True + + >>> e = list(existing) + >>> e.append(prefix + "aaaaa" + "1".zfill(15) + suffix) + >>> handleClash1(userName="A" * 5, existing=e, + ... prefix=prefix, suffix=suffix) == ( + ... '00000.AAAAA000000000000002.0000000000') + True + + >>> e = list(existing) + >>> e.append(prefix + "AAAAA" + "2".zfill(15) + suffix) + >>> handleClash1(userName="A" * 5, existing=e, + ... prefix=prefix, suffix=suffix) == ( + ... '00000.AAAAA000000000000001.0000000000') + True + """ + # if the prefix length + user name length + suffix length + 15 is at + # or past the maximum length, silce 15 characters off of the user name + prefixLength = len(prefix) + suffixLength = len(suffix) + if prefixLength + len(userName) + suffixLength + 15 > maxFileNameLength: + l = prefixLength + len(userName) + suffixLength + 15 + sliceLength = maxFileNameLength - l + userName = userName[:sliceLength] + finalName = None + # try to add numbers to create a unique name + counter = 1 + while finalName is None: + name = userName + str(counter).zfill(15) + fullName = prefix + name + suffix + if fullName.lower() not in existing: + finalName = fullName + break + else: + counter += 1 + if counter >= 999999999999999: + break + # if there is a clash, go to the next fallback + if finalName is None: + finalName = handleClash2(existing, prefix, suffix) + # finished + return finalName + + +def handleClash2( + existing: Iterable[str] = [], prefix: str = "", suffix: str = "" +) -> str: + """A helper function that resolves collisions with existing names when choosing a filename. + + This function is a fallback to :func:`handleClash1`. It attempts to append an unused integer counter to the filename. + + Args: + userName (str): The input file name. + existing: A case-insensitive list of all existing file names. + prefix: Prefix to be prepended to the file name. + suffix: Suffix to be appended to the file name. + + Returns: + A suitable filename. + + Raises: + NameTranslationError: If no suitable name could be generated. + + Examples:: + + >>> prefix = ("0" * 5) + "." + >>> suffix = "." + ("0" * 10) + >>> existing = [prefix + str(i) + suffix for i in range(100)] + + >>> e = list(existing) + >>> handleClash2(existing=e, prefix=prefix, suffix=suffix) == ( + ... '00000.100.0000000000') + True + + >>> e = list(existing) + >>> e.remove(prefix + "1" + suffix) + >>> handleClash2(existing=e, prefix=prefix, suffix=suffix) == ( + ... '00000.1.0000000000') + True + + >>> e = list(existing) + >>> e.remove(prefix + "2" + suffix) + >>> handleClash2(existing=e, prefix=prefix, suffix=suffix) == ( + ... '00000.2.0000000000') + True + """ + # calculate the longest possible string + maxLength = maxFileNameLength - len(prefix) - len(suffix) + maxValue = int("9" * maxLength) + # try to find a number + finalName = None + counter = 1 + while finalName is None: + fullName = prefix + str(counter) + suffix + if fullName.lower() not in existing: + finalName = fullName + break + else: + counter += 1 + if counter >= maxValue: + break + # raise an error if nothing has been found + if finalName is None: + raise NameTranslationError("No unique name could be found.") + # finished + return finalName + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/.venv/lib/python3.13/site-packages/fontTools/ufoLib/glifLib.py b/.venv/lib/python3.13/site-packages/fontTools/ufoLib/glifLib.py new file mode 100644 index 0000000000000000000000000000000000000000..040c31c4990b3cbb2cd631bdabceac6c7d868425 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ufoLib/glifLib.py @@ -0,0 +1,2120 @@ +""" +Generic module for reading and writing the .glif format. + +More info about the .glif format (GLyphInterchangeFormat) can be found here: + + http://unifiedfontobject.org + +The main class in this module is :class:`GlyphSet`. It manages a set of .glif files +in a folder. It offers two ways to read glyph data, and one way to write +glyph data. See the class doc string for details. +""" + +from __future__ import annotations + +import logging +from collections import OrderedDict +from typing import TYPE_CHECKING, Any, Optional, Union, cast +from warnings import warn + +import fontTools.misc.filesystem as fs +from fontTools.misc import etree, plistlib +from fontTools.misc.textTools import tobytes +from fontTools.pens.pointPen import AbstractPointPen, PointToSegmentPen +from fontTools.ufoLib import UFOFormatVersion, _UFOBaseIO +from fontTools.ufoLib.errors import GlifLibError +from fontTools.ufoLib.filenames import userNameToFileName +from fontTools.ufoLib.utils import ( + BaseFormatVersion, + normalizeFormatVersion, + numberTypes, +) +from fontTools.ufoLib.validators import ( + anchorsValidator, + colorValidator, + genericTypeValidator, + glyphLibValidator, + guidelinesValidator, + identifierValidator, + imageValidator, +) + +if TYPE_CHECKING: + from collections.abc import Callable, Iterable, Set + from logging import Logger + + from fontTools.annotations import ( + ElementType, + FormatVersion, + FormatVersions, + GLIFFormatVersionInput, + GlyphNameToFileNameFunc, + IntFloat, + PathOrFS, + UFOFormatVersionInput, + ) + from fontTools.misc.filesystem._base import FS + + +__all__: list[str] = [ + "GlyphSet", + "GlifLibError", + "readGlyphFromString", + "writeGlyphToString", + "glyphNameToFileName", +] + +logger: Logger = logging.getLogger(__name__) + + +# --------- +# Constants +# --------- + +CONTENTS_FILENAME = "contents.plist" +LAYERINFO_FILENAME = "layerinfo.plist" + + +class GLIFFormatVersion(BaseFormatVersion): + """Class representing the versions of the .glif format supported by the UFO version in use. + + For a given :mod:`fontTools.ufoLib.UFOFormatVersion`, the :func:`supported_versions` method will + return the supported versions of the GLIF file format. If the UFO version is unspecified, the + :func:`supported_versions` method will return all available GLIF format versions. + """ + + FORMAT_1_0 = (1, 0) + FORMAT_2_0 = (2, 0) + + @classmethod + def default( + cls, ufoFormatVersion: Optional[UFOFormatVersion] = None + ) -> GLIFFormatVersion: + if ufoFormatVersion is not None: + return max(cls.supported_versions(ufoFormatVersion)) + return super().default() + + @classmethod + def supported_versions( + cls, ufoFormatVersion: Optional[UFOFormatVersion] = None + ) -> frozenset[GLIFFormatVersion]: + if ufoFormatVersion is None: + # if ufo format unspecified, return all the supported GLIF formats + return super().supported_versions() + # else only return the GLIF formats supported by the given UFO format + versions = {cls.FORMAT_1_0} + if ufoFormatVersion >= UFOFormatVersion.FORMAT_3_0: + versions.add(cls.FORMAT_2_0) + return frozenset(versions) + + +# ------------ +# Simple Glyph +# ------------ + + +class Glyph: + """ + Minimal glyph object. It has no glyph attributes until either + the draw() or the drawPoints() method has been called. + """ + + def __init__(self, glyphName: str, glyphSet: GlyphSet) -> None: + self.glyphName: str = glyphName + self.glyphSet: GlyphSet = glyphSet + + def draw(self, pen: Any, outputImpliedClosingLine: bool = False) -> None: + """ + Draw this glyph onto a *FontTools* Pen. + """ + pointPen = PointToSegmentPen( + pen, outputImpliedClosingLine=outputImpliedClosingLine + ) + self.drawPoints(pointPen) + + def drawPoints(self, pointPen: AbstractPointPen) -> None: + """ + Draw this glyph onto a PointPen. + """ + self.glyphSet.readGlyph(self.glyphName, self, pointPen) + + +# --------- +# Glyph Set +# --------- + + +class GlyphSet(_UFOBaseIO): + """ + GlyphSet manages a set of .glif files inside one directory. + + GlyphSet's constructor takes a path to an existing directory as it's + first argument. Reading glyph data can either be done through the + readGlyph() method, or by using GlyphSet's dictionary interface, where + the keys are glyph names and the values are (very) simple glyph objects. + + To write a glyph to the glyph set, you use the writeGlyph() method. + The simple glyph objects returned through the dict interface do not + support writing, they are just a convenient way to get at the glyph data. + """ + + glyphClass = Glyph + + def __init__( + self, + path: PathOrFS, + glyphNameToFileNameFunc: GlyphNameToFileNameFunc = None, + ufoFormatVersion: UFOFormatVersionInput = None, + validateRead: bool = True, + validateWrite: bool = True, + expectContentsFile: bool = False, + ) -> None: + """ + 'path' should be a path (string) to an existing local directory, or + an instance of fs.base.FS class. + + The optional 'glyphNameToFileNameFunc' argument must be a callback + function that takes two arguments: a glyph name and a list of all + existing filenames (if any exist). It should return a file name + (including the .glif extension). The glyphNameToFileName function + is called whenever a file name is created for a given glyph name. + + ``validateRead`` will validate read operations. Its default is ``True``. + ``validateWrite`` will validate write operations. Its default is ``True``. + ``expectContentsFile`` will raise a GlifLibError if a contents.plist file is + not found on the glyph set file system. This should be set to ``True`` if you + are reading an existing UFO and ``False`` if you create a fresh glyph set. + """ + try: + ufoFormatVersion = normalizeFormatVersion( + ufoFormatVersion, UFOFormatVersion + ) + except ValueError as e: + from fontTools.ufoLib.errors import UnsupportedUFOFormat + + raise UnsupportedUFOFormat( + f"Unsupported UFO format: {ufoFormatVersion!r}" + ) from e + + if hasattr(path, "__fspath__"): # support os.PathLike objects + path = path.__fspath__() + + if isinstance(path, str): + try: + filesystem: FS = fs.osfs.OSFS(path) + except fs.errors.CreateFailed: + raise GlifLibError("No glyphs directory '%s'" % path) + self._shouldClose: bool = True + elif isinstance(path, fs.base.FS): + filesystem = path + try: + filesystem.check() + except fs.errors.FilesystemClosed: + raise GlifLibError("the filesystem '%s' is closed" % filesystem) + self._shouldClose = False + else: + raise TypeError( + "Expected a path string or fs object, found %s" % type(path).__name__ + ) + try: + path = filesystem.getsyspath("/") + except fs.errors.NoSysPath: + # network or in-memory FS may not map to the local one + path = str(filesystem) + # 'dirName' is kept for backward compatibility only, but it's DEPRECATED + # as it's not guaranteed that it maps to an existing OSFS directory. + # Client could use the FS api via the `self.fs` attribute instead. + self.dirName: str = fs.path.basename(path) + self.fs: FS = filesystem + # if glyphSet contains no 'contents.plist', we consider it empty + self._havePreviousFile: bool = filesystem.exists(CONTENTS_FILENAME) + if expectContentsFile and not self._havePreviousFile: + raise GlifLibError(f"{CONTENTS_FILENAME} is missing.") + # attribute kept for backward compatibility + self.ufoFormatVersion: int = ufoFormatVersion.major + self.ufoFormatVersionTuple: UFOFormatVersion = ufoFormatVersion + if glyphNameToFileNameFunc is None: + glyphNameToFileNameFunc = glyphNameToFileName + self.glyphNameToFileName: Callable[[str, set[str]], str] = ( + glyphNameToFileNameFunc + ) + self._validateRead: bool = validateRead + self._validateWrite: bool = validateWrite + self._existingFileNames: set[str] | None = None + self._reverseContents: Optional[dict[str, str]] = None + + self.rebuildContents() + + def rebuildContents(self, validateRead: bool = False) -> None: + """ + Rebuild the contents dict by loading contents.plist. + + ``validateRead`` will validate the data, by default it is set to the + class's ``validateRead`` value, can be overridden. + """ + if validateRead is None: + validateRead = self._validateRead + contents = self._getPlist(CONTENTS_FILENAME, {}) + # validate the contents + if validateRead: + invalidFormat = False + if not isinstance(contents, dict): + invalidFormat = True + else: + for name, fileName in contents.items(): + if not isinstance(name, str): + invalidFormat = True + if not isinstance(fileName, str): + invalidFormat = True + elif not self.fs.exists(fileName): + raise GlifLibError( + "%s references a file that does not exist: %s" + % (CONTENTS_FILENAME, fileName) + ) + if invalidFormat: + raise GlifLibError("%s is not properly formatted" % CONTENTS_FILENAME) + self.contents: dict[str, str] = contents + self._existingFileNames = None + self._reverseContents = None + + def getReverseContents(self) -> dict[str, str]: + """ + Return a reversed dict of self.contents, mapping file names to + glyph names. This is primarily an aid for custom glyph name to file + name schemes that want to make sure they don't generate duplicate + file names. The file names are converted to lowercase so we can + reliably check for duplicates that only differ in case, which is + important for case-insensitive file systems. + """ + if self._reverseContents is None: + d = {} + for k, v in self.contents.items(): + d[v.lower()] = k + self._reverseContents = d + return self._reverseContents + + def writeContents(self) -> None: + """ + Write the contents.plist file out to disk. Call this method when + you're done writing glyphs. + """ + self._writePlist(CONTENTS_FILENAME, self.contents) + + # layer info + + def readLayerInfo(self, info: Any, validateRead: Optional[bool] = None) -> None: + """ + ``validateRead`` will validate the data, by default it is set to the + class's ``validateRead`` value, can be overridden. + """ + if validateRead is None: + validateRead = self._validateRead + infoDict = self._getPlist(LAYERINFO_FILENAME, {}) + if validateRead: + if not isinstance(infoDict, dict): + raise GlifLibError("layerinfo.plist is not properly formatted.") + infoDict = validateLayerInfoVersion3Data(infoDict) + # populate the object + for attr, value in infoDict.items(): + try: + setattr(info, attr, value) + except AttributeError: + raise GlifLibError( + "The supplied layer info object does not support setting a necessary attribute (%s)." + % attr + ) + + def writeLayerInfo(self, info: Any, validateWrite: Optional[bool] = None) -> None: + """ + ``validateWrite`` will validate the data, by default it is set to the + class's ``validateWrite`` value, can be overridden. + """ + if validateWrite is None: + validateWrite = self._validateWrite + if self.ufoFormatVersionTuple.major < 3: + raise GlifLibError( + "layerinfo.plist is not allowed in UFO %d." + % self.ufoFormatVersionTuple.major + ) + # gather data + infoData = {} + for attr in layerInfoVersion3ValueData.keys(): + if hasattr(info, attr): + try: + value = getattr(info, attr) + except AttributeError: + raise GlifLibError( + "The supplied info object does not support getting a necessary attribute (%s)." + % attr + ) + if value is None or (attr == "lib" and not value): + continue + infoData[attr] = value + if infoData: + # validate + if validateWrite: + infoData = validateLayerInfoVersion3Data(infoData) + # write file + self._writePlist(LAYERINFO_FILENAME, infoData) + elif self._havePreviousFile and self.fs.exists(LAYERINFO_FILENAME): + # data empty, remove existing file + self.fs.remove(LAYERINFO_FILENAME) + + def getGLIF(self, glyphName: str) -> bytes: + """ + Get the raw GLIF text for a given glyph name. This only works + for GLIF files that are already on disk. + + This method is useful in situations when the raw XML needs to be + read from a glyph set for a particular glyph before fully parsing + it into an object structure via the readGlyph method. + + Raises KeyError if 'glyphName' is not in contents.plist, or + GlifLibError if the file associated with can't be found. + """ + fileName = self.contents[glyphName] + try: + return self.fs.readbytes(fileName) + except fs.errors.ResourceNotFound: + raise GlifLibError( + "The file '%s' associated with glyph '%s' in contents.plist " + "does not exist on %s" % (fileName, glyphName, self.fs) + ) + + def getGLIFModificationTime(self, glyphName: str) -> Optional[float]: + """ + Returns the modification time for the GLIF file with 'glyphName', as + a floating point number giving the number of seconds since the epoch. + Return None if the associated file does not exist or the underlying + filesystem does not support getting modified times. + Raises KeyError if the glyphName is not in contents.plist. + """ + fileName = self.contents[glyphName] + return self.getFileModificationTime(fileName) + + # reading/writing API + + def readGlyph( + self, + glyphName: str, + glyphObject: Optional[Any] = None, + pointPen: Optional[AbstractPointPen] = None, + validate: Optional[bool] = None, + ) -> None: + """ + Read a .glif file for 'glyphName' from the glyph set. The + 'glyphObject' argument can be any kind of object (even None); + the readGlyph() method will attempt to set the following + attributes on it: + + width + the advance width of the glyph + height + the advance height of the glyph + unicodes + a list of unicode values for this glyph + note + a string + lib + a dictionary containing custom data + image + a dictionary containing image data + guidelines + a list of guideline data dictionaries + anchors + a list of anchor data dictionaries + + All attributes are optional, in two ways: + + 1) An attribute *won't* be set if the .glif file doesn't + contain data for it. 'glyphObject' will have to deal + with default values itself. + 2) If setting the attribute fails with an AttributeError + (for example if the 'glyphObject' attribute is read- + only), readGlyph() will not propagate that exception, + but ignore that attribute. + + To retrieve outline information, you need to pass an object + conforming to the PointPen protocol as the 'pointPen' argument. + This argument may be None if you don't need the outline data. + + readGlyph() will raise KeyError if the glyph is not present in + the glyph set. + + ``validate`` will validate the data, by default it is set to the + class's ``validateRead`` value, can be overridden. + """ + if validate is None: + validate = self._validateRead + text = self.getGLIF(glyphName) + try: + tree = _glifTreeFromString(text) + formatVersions = GLIFFormatVersion.supported_versions( + self.ufoFormatVersionTuple + ) + _readGlyphFromTree( + tree, + glyphObject, + pointPen, + formatVersions=formatVersions, + validate=validate, + ) + except GlifLibError as glifLibError: + # Re-raise with a note that gives extra context, describing where + # the error occurred. + fileName = self.contents[glyphName] + try: + glifLocation = f"'{self.fs.getsyspath(fileName)}'" + except fs.errors.NoSysPath: + # Network or in-memory FS may not map to a local path, so use + # the best string representation we have. + glifLocation = f"'{fileName}' from '{str(self.fs)}'" + + glifLibError._add_note( + f"The issue is in glyph '{glyphName}', located in {glifLocation}." + ) + raise + + def writeGlyph( + self, + glyphName: str, + glyphObject: Optional[Any] = None, + drawPointsFunc: Optional[Callable[[AbstractPointPen], None]] = None, + formatVersion: GLIFFormatVersionInput = None, + validate: Optional[bool] = None, + ) -> None: + """ + Write a .glif file for 'glyphName' to the glyph set. The + 'glyphObject' argument can be any kind of object (even None); + the writeGlyph() method will attempt to get the following + attributes from it: + + width + the advance width of the glyph + height + the advance height of the glyph + unicodes + a list of unicode values for this glyph + note + a string + lib + a dictionary containing custom data + image + a dictionary containing image data + guidelines + a list of guideline data dictionaries + anchors + a list of anchor data dictionaries + + All attributes are optional: if 'glyphObject' doesn't + have the attribute, it will simply be skipped. + + To write outline data to the .glif file, writeGlyph() needs + a function (any callable object actually) that will take one + argument: an object that conforms to the PointPen protocol. + The function will be called by writeGlyph(); it has to call the + proper PointPen methods to transfer the outline to the .glif file. + + The GLIF format version will be chosen based on the ufoFormatVersion + passed during the creation of this object. If a particular format + version is desired, it can be passed with the formatVersion argument. + The formatVersion argument accepts either a tuple of integers for + (major, minor), or a single integer for the major digit only (with + minor digit implied as 0). + + An UnsupportedGLIFFormat exception is raised if the requested GLIF + formatVersion is not supported. + + ``validate`` will validate the data, by default it is set to the + class's ``validateWrite`` value, can be overridden. + """ + if formatVersion is None: + formatVersion = GLIFFormatVersion.default(self.ufoFormatVersionTuple) + else: + try: + formatVersion = normalizeFormatVersion(formatVersion, GLIFFormatVersion) + except ValueError as e: + from fontTools.ufoLib.errors import UnsupportedGLIFFormat + + raise UnsupportedGLIFFormat( + f"Unsupported GLIF format version: {formatVersion!r}" + ) from e + if formatVersion not in GLIFFormatVersion.supported_versions( + self.ufoFormatVersionTuple + ): + from fontTools.ufoLib.errors import UnsupportedGLIFFormat + + raise UnsupportedGLIFFormat( + f"Unsupported GLIF format version ({formatVersion!s}) " + f"for UFO format version {self.ufoFormatVersionTuple!s}." + ) + if validate is None: + validate = self._validateWrite + fileName = self.contents.get(glyphName) + if fileName is None: + if self._existingFileNames is None: + self._existingFileNames = { + fileName.lower() for fileName in self.contents.values() + } + fileName = self.glyphNameToFileName(glyphName, self._existingFileNames) + self.contents[glyphName] = fileName + self._existingFileNames.add(fileName.lower()) + if self._reverseContents is not None: + self._reverseContents[fileName.lower()] = glyphName + data = _writeGlyphToBytes( + glyphName, + glyphObject, + drawPointsFunc, + formatVersion=formatVersion, + validate=validate, + ) + if ( + self._havePreviousFile + and self.fs.exists(fileName) + and data == self.fs.readbytes(fileName) + ): + return + self.fs.writebytes(fileName, data) + + def deleteGlyph(self, glyphName: str) -> None: + """Permanently delete the glyph from the glyph set on disk. Will + raise KeyError if the glyph is not present in the glyph set. + """ + fileName = self.contents[glyphName] + self.fs.remove(fileName) + if self._existingFileNames is not None: + self._existingFileNames.remove(fileName.lower()) + if self._reverseContents is not None: + del self._reverseContents[fileName.lower()] + del self.contents[glyphName] + + # dict-like support + + def keys(self) -> list[str]: + return list(self.contents.keys()) + + def has_key(self, glyphName: str) -> bool: + return glyphName in self.contents + + __contains__ = has_key + + def __len__(self) -> int: + return len(self.contents) + + def __getitem__(self, glyphName: str) -> Any: + if glyphName not in self.contents: + raise KeyError(glyphName) + return self.glyphClass(glyphName, self) + + # quickly fetch unicode values + + def getUnicodes( + self, glyphNames: Optional[Iterable[str]] = None + ) -> dict[str, list[int]]: + """ + Return a dictionary that maps glyph names to lists containing + the unicode value[s] for that glyph, if any. This parses the .glif + files partially, so it is a lot faster than parsing all files completely. + By default this checks all glyphs, but a subset can be passed with glyphNames. + """ + unicodes = {} + if glyphNames is None: + glyphNames = self.contents.keys() + for glyphName in glyphNames: + text = self.getGLIF(glyphName) + unicodes[glyphName] = _fetchUnicodes(text) + return unicodes + + def getComponentReferences( + self, glyphNames: Optional[Iterable[str]] = None + ) -> dict[str, list[str]]: + """ + Return a dictionary that maps glyph names to lists containing the + base glyph name of components in the glyph. This parses the .glif + files partially, so it is a lot faster than parsing all files completely. + By default this checks all glyphs, but a subset can be passed with glyphNames. + """ + components = {} + if glyphNames is None: + glyphNames = self.contents.keys() + for glyphName in glyphNames: + text = self.getGLIF(glyphName) + components[glyphName] = _fetchComponentBases(text) + return components + + def getImageReferences( + self, glyphNames: Optional[Iterable[str]] = None + ) -> dict[str, Optional[str]]: + """ + Return a dictionary that maps glyph names to the file name of the image + referenced by the glyph. This parses the .glif files partially, so it is a + lot faster than parsing all files completely. + By default this checks all glyphs, but a subset can be passed with glyphNames. + """ + images = {} + if glyphNames is None: + glyphNames = self.contents.keys() + for glyphName in glyphNames: + text = self.getGLIF(glyphName) + images[glyphName] = _fetchImageFileName(text) + return images + + def close(self) -> None: + if self._shouldClose: + self.fs.close() + + def __enter__(self) -> GlyphSet: + return self + + def __exit__(self, exc_type: Any, exc_value: Any, exc_tb: Any) -> None: + self.close() + + +# ----------------------- +# Glyph Name to File Name +# ----------------------- + + +def glyphNameToFileName(glyphName: str, existingFileNames: Optional[set[str]]) -> str: + """ + Wrapper around the userNameToFileName function in filenames.py + + Note that existingFileNames should be a set for large glyphsets + or performance will suffer. + """ + if existingFileNames is None: + existingFileNames = set() + return userNameToFileName(glyphName, existing=existingFileNames, suffix=".glif") + + +# ----------------------- +# GLIF To and From String +# ----------------------- + + +def readGlyphFromString( + aString: Union[str, bytes], + glyphObject: Optional[Any] = None, + pointPen: Optional[Any] = None, + formatVersions: FormatVersions = None, + validate: bool = True, +) -> None: + """ + Read .glif data from a string into a glyph object. + + The 'glyphObject' argument can be any kind of object (even None); + the readGlyphFromString() method will attempt to set the following + attributes on it: + + width + the advance width of the glyph + height + the advance height of the glyph + unicodes + a list of unicode values for this glyph + note + a string + lib + a dictionary containing custom data + image + a dictionary containing image data + guidelines + a list of guideline data dictionaries + anchors + a list of anchor data dictionaries + + All attributes are optional, in two ways: + + 1) An attribute *won't* be set if the .glif file doesn't + contain data for it. 'glyphObject' will have to deal + with default values itself. + 2) If setting the attribute fails with an AttributeError + (for example if the 'glyphObject' attribute is read- + only), readGlyphFromString() will not propagate that + exception, but ignore that attribute. + + To retrieve outline information, you need to pass an object + conforming to the PointPen protocol as the 'pointPen' argument. + This argument may be None if you don't need the outline data. + + The formatVersions optional argument define the GLIF format versions + that are allowed to be read. + The type is Optional[Iterable[tuple[int, int], int]]. It can contain + either integers (for the major versions to be allowed, with minor + digits defaulting to 0), or tuples of integers to specify both + (major, minor) versions. + By default when formatVersions is None all the GLIF format versions + currently defined are allowed to be read. + + ``validate`` will validate the read data. It is set to ``True`` by default. + """ + tree = _glifTreeFromString(aString) + + if formatVersions is None: + validFormatVersions: Set[GLIFFormatVersion] = ( + GLIFFormatVersion.supported_versions() + ) + else: + validFormatVersions, invalidFormatVersions = set(), set() + for v in formatVersions: + try: + formatVersion = normalizeFormatVersion(v, GLIFFormatVersion) + except ValueError: + invalidFormatVersions.add(v) + else: + validFormatVersions.add(formatVersion) + if not validFormatVersions: + raise ValueError( + "None of the requested GLIF formatVersions are supported: " + f"{formatVersions!r}" + ) + + _readGlyphFromTree( + tree, + glyphObject, + pointPen, + formatVersions=validFormatVersions, + validate=validate, + ) + + +def _writeGlyphToBytes( + glyphName: str, + glyphObject: Optional[Any] = None, + drawPointsFunc: Optional[Callable[[Any], None]] = None, + writer: Optional[Any] = None, + formatVersion: Optional[FormatVersion] = None, + validate: bool = True, +) -> bytes: + """Return .glif data for a glyph as a UTF-8 encoded bytes string.""" + try: + formatVersion = normalizeFormatVersion(formatVersion, GLIFFormatVersion) + except ValueError: + from fontTools.ufoLib.errors import UnsupportedGLIFFormat + + raise UnsupportedGLIFFormat( + "Unsupported GLIF format version: {formatVersion!r}" + ) + # start + if validate and not isinstance(glyphName, str): + raise GlifLibError("The glyph name is not properly formatted.") + if validate and len(glyphName) == 0: + raise GlifLibError("The glyph name is empty.") + glyphAttrs = OrderedDict( + [("name", glyphName), ("format", repr(formatVersion.major))] + ) + if formatVersion.minor != 0: + glyphAttrs["formatMinor"] = repr(formatVersion.minor) + root = etree.Element("glyph", glyphAttrs) + identifiers: set[str] = set() + # advance + _writeAdvance(glyphObject, root, validate) + # unicodes + if getattr(glyphObject, "unicodes", None): + _writeUnicodes(glyphObject, root, validate) + # note + if getattr(glyphObject, "note", None): + _writeNote(glyphObject, root, validate) + # image + if formatVersion.major >= 2 and getattr(glyphObject, "image", None): + _writeImage(glyphObject, root, validate) + # guidelines + if formatVersion.major >= 2 and getattr(glyphObject, "guidelines", None): + _writeGuidelines(glyphObject, root, identifiers, validate) + # anchors + anchors = getattr(glyphObject, "anchors", None) + if formatVersion.major >= 2 and anchors: + _writeAnchors(glyphObject, root, identifiers, validate) + # outline + if drawPointsFunc is not None: + outline = etree.SubElement(root, "outline") + pen = GLIFPointPen(outline, identifiers=identifiers, validate=validate) + drawPointsFunc(pen) + if formatVersion.major == 1 and anchors: + _writeAnchorsFormat1(pen, anchors, validate) + # prevent lxml from writing self-closing tags + if not len(outline): + outline.text = "\n " + # lib + if getattr(glyphObject, "lib", None): + _writeLib(glyphObject, root, validate) + # return the text + data = etree.tostring( + root, encoding="UTF-8", xml_declaration=True, pretty_print=True + ) + return data + + +def writeGlyphToString( + glyphName: str, + glyphObject: Optional[Any] = None, + drawPointsFunc: Optional[Callable[[Any], None]] = None, + formatVersion: Optional[FormatVersion] = None, + validate: bool = True, +) -> str: + """ + Return .glif data for a glyph as a string. The XML declaration's + encoding is always set to "UTF-8". + The 'glyphObject' argument can be any kind of object (even None); + the writeGlyphToString() method will attempt to get the following + attributes from it: + + width + the advance width of the glyph + height + the advance height of the glyph + unicodes + a list of unicode values for this glyph + note + a string + lib + a dictionary containing custom data + image + a dictionary containing image data + guidelines + a list of guideline data dictionaries + anchors + a list of anchor data dictionaries + + All attributes are optional: if 'glyphObject' doesn't + have the attribute, it will simply be skipped. + + To write outline data to the .glif file, writeGlyphToString() needs + a function (any callable object actually) that will take one + argument: an object that conforms to the PointPen protocol. + The function will be called by writeGlyphToString(); it has to call the + proper PointPen methods to transfer the outline to the .glif file. + + The GLIF format version can be specified with the formatVersion argument. + This accepts either a tuple of integers for (major, minor), or a single + integer for the major digit only (with minor digit implied as 0). + By default when formatVesion is None the latest GLIF format version will + be used; currently it's 2.0, which is equivalent to formatVersion=(2, 0). + + An UnsupportedGLIFFormat exception is raised if the requested UFO + formatVersion is not supported. + + ``validate`` will validate the written data. It is set to ``True`` by default. + """ + data = _writeGlyphToBytes( + glyphName, + glyphObject=glyphObject, + drawPointsFunc=drawPointsFunc, + formatVersion=formatVersion, + validate=validate, + ) + return data.decode("utf-8") + + +def _writeAdvance(glyphObject: Any, element: ElementType, validate: bool) -> None: + width = getattr(glyphObject, "width", None) + if width is not None: + if validate and not isinstance(width, numberTypes): + raise GlifLibError("width attribute must be int or float") + if width == 0: + width = None + height = getattr(glyphObject, "height", None) + if height is not None: + if validate and not isinstance(height, numberTypes): + raise GlifLibError("height attribute must be int or float") + if height == 0: + height = None + if width is not None and height is not None: + etree.SubElement( + element, + "advance", + OrderedDict([("height", repr(height)), ("width", repr(width))]), + ) + elif width is not None: + etree.SubElement(element, "advance", dict(width=repr(width))) + elif height is not None: + etree.SubElement(element, "advance", dict(height=repr(height))) + + +def _writeUnicodes(glyphObject: Any, element: ElementType, validate: bool) -> None: + unicodes = getattr(glyphObject, "unicodes", []) + if validate and isinstance(unicodes, int): + unicodes = [unicodes] + seen = set() + for code in unicodes: + if validate and not isinstance(code, int): + raise GlifLibError("unicode values must be int") + if code in seen: + continue + seen.add(code) + hexCode = "%04X" % code + etree.SubElement(element, "unicode", dict(hex=hexCode)) + + +def _writeNote(glyphObject: Any, element: ElementType, validate: bool) -> None: + note = getattr(glyphObject, "note", None) + if validate and not isinstance(note, str): + raise GlifLibError("note attribute must be str") + if isinstance(note, str): + note = note.strip() + note = "\n" + note + "\n" + etree.SubElement(element, "note").text = note + + +def _writeImage(glyphObject: Any, element: ElementType, validate: bool) -> None: + image = getattr(glyphObject, "image", None) + if image is None: + return + + if validate and not imageValidator(image): + raise GlifLibError( + "image attribute must be a dict or dict-like object with the proper structure." + ) + attrs = OrderedDict([("fileName", image["fileName"])]) + for attr, default in _transformationInfo: + value = image.get(attr, default) + if value != default: + attrs[attr] = repr(value) + color = image.get("color") + if color is not None: + attrs["color"] = color + etree.SubElement(element, "image", attrs) + + +def _writeGuidelines( + glyphObject: Any, element: ElementType, identifiers: set[str], validate: bool +) -> None: + guidelines = getattr(glyphObject, "guidelines", []) + if validate and not guidelinesValidator(guidelines): + raise GlifLibError("guidelines attribute does not have the proper structure.") + for guideline in guidelines: + attrs = OrderedDict() + x = guideline.get("x") + if x is not None: + attrs["x"] = repr(x) + y = guideline.get("y") + if y is not None: + attrs["y"] = repr(y) + angle = guideline.get("angle") + if angle is not None: + attrs["angle"] = repr(angle) + name = guideline.get("name") + if name is not None: + attrs["name"] = name + color = guideline.get("color") + if color is not None: + attrs["color"] = color + identifier = guideline.get("identifier") + if identifier is not None: + if validate and identifier in identifiers: + raise GlifLibError("identifier used more than once: %s" % identifier) + attrs["identifier"] = identifier + identifiers.add(identifier) + etree.SubElement(element, "guideline", attrs) + + +def _writeAnchorsFormat1(pen: Any, anchors: Any, validate: bool) -> None: + if validate and not anchorsValidator(anchors): + raise GlifLibError("anchors attribute does not have the proper structure.") + for anchor in anchors: + attrs = {} + x = anchor["x"] + attrs["x"] = repr(x) + y = anchor["y"] + attrs["y"] = repr(y) + name = anchor.get("name") + if name is not None: + attrs["name"] = name + pen.beginPath() + pen.addPoint((x, y), segmentType="move", name=name) + pen.endPath() + + +def _writeAnchors( + glyphObject: Any, + element: ElementType, + identifiers: set[str], + validate: bool, +) -> None: + anchors = getattr(glyphObject, "anchors", []) + if validate and not anchorsValidator(anchors): + raise GlifLibError("anchors attribute does not have the proper structure.") + for anchor in anchors: + attrs = OrderedDict() + x = anchor["x"] + attrs["x"] = repr(x) + y = anchor["y"] + attrs["y"] = repr(y) + name = anchor.get("name") + if name is not None: + attrs["name"] = name + color = anchor.get("color") + if color is not None: + attrs["color"] = color + identifier = anchor.get("identifier") + if identifier is not None: + if validate and identifier in identifiers: + raise GlifLibError("identifier used more than once: %s" % identifier) + attrs["identifier"] = identifier + identifiers.add(identifier) + etree.SubElement(element, "anchor", attrs) + + +def _writeLib(glyphObject: Any, element: ElementType, validate: bool) -> None: + lib = getattr(glyphObject, "lib", None) + if not lib: + # don't write empty lib + return + if validate: + valid, message = glyphLibValidator(lib) + if not valid: + raise GlifLibError(message) + if not isinstance(lib, dict): + lib = dict(lib) + # plist inside GLIF begins with 2 levels of indentation + e = plistlib.totree(lib, indent_level=2) + etree.SubElement(element, "lib").append(e) + + +# ----------------------- +# layerinfo.plist Support +# ----------------------- + +layerInfoVersion3ValueData = { + "color": dict(type=str, valueValidator=colorValidator), + "lib": dict(type=dict, valueValidator=genericTypeValidator), +} + + +def validateLayerInfoVersion3ValueForAttribute(attr: str, value: Any) -> bool: + """ + This performs very basic validation of the value for attribute + following the UFO 3 fontinfo.plist specification. The results + of this should not be interpretted as *correct* for the font + that they are part of. This merely indicates that the value + is of the proper type and, where the specification defines + a set range of possible values for an attribute, that the + value is in the accepted range. + """ + if attr not in layerInfoVersion3ValueData: + return False + dataValidationDict = layerInfoVersion3ValueData[attr] + valueType = dataValidationDict.get("type") + validator = dataValidationDict.get("valueValidator") + valueOptions = dataValidationDict.get("valueOptions") + # have specific options for the validator + assert callable(validator) + if valueOptions is not None: + isValidValue = validator(value, valueOptions) + # no specific options + else: + if validator == genericTypeValidator: + isValidValue = validator(value, valueType) + else: + isValidValue = validator(value) + return isValidValue + + +def validateLayerInfoVersion3Data(infoData: dict[str, Any]) -> dict[str, Any]: + """ + This performs very basic validation of the value for infoData + following the UFO 3 layerinfo.plist specification. The results + of this should not be interpretted as *correct* for the font + that they are part of. This merely indicates that the values + are of the proper type and, where the specification defines + a set range of possible values for an attribute, that the + value is in the accepted range. + """ + for attr, value in infoData.items(): + if attr not in layerInfoVersion3ValueData: + raise GlifLibError("Unknown attribute %s." % attr) + isValidValue = validateLayerInfoVersion3ValueForAttribute(attr, value) + if not isValidValue: + raise GlifLibError(f"Invalid value for attribute {attr} ({value!r}).") + return infoData + + +# ----------------- +# GLIF Tree Support +# ----------------- + + +def _glifTreeFromFile(aFile: Union[str, bytes, int]) -> ElementType: + if etree._have_lxml: + tree = etree.parse(aFile, parser=etree.XMLParser(remove_comments=True)) + else: + tree = etree.parse(aFile) + root = tree.getroot() + if root.tag != "glyph": + raise GlifLibError("The GLIF is not properly formatted.") + if root.text and root.text.strip() != "": + raise GlifLibError("Invalid GLIF structure.") + return root + + +def _glifTreeFromString(aString: Union[str, bytes]) -> ElementType: + data = tobytes(aString, encoding="utf-8") + try: + if etree._have_lxml: + root = etree.fromstring(data, parser=etree.XMLParser(remove_comments=True)) + else: + root = etree.fromstring(data) + except Exception as etree_exception: + raise GlifLibError("GLIF contains invalid XML.") from etree_exception + + if root.tag != "glyph": + raise GlifLibError("The GLIF is not properly formatted.") + if root.text and root.text.strip() != "": + raise GlifLibError("Invalid GLIF structure.") + return root + + +def _readGlyphFromTree( + tree: ElementType, + glyphObject: Optional[Any] = None, + pointPen: Optional[AbstractPointPen] = None, + formatVersions: Set[GLIFFormatVersion] = GLIFFormatVersion.supported_versions(), + validate: bool = True, +) -> None: + # check the format version + formatVersionMajor = tree.get("format") + if formatVersionMajor is None: + if validate: + raise GlifLibError("Unspecified format version in GLIF.") + formatVersionMajor = 0 + formatVersionMinor = tree.get("formatMinor", 0) + try: + formatVersion = GLIFFormatVersion( + (int(formatVersionMajor), int(formatVersionMinor)) + ) + except ValueError as e: + msg = "Unsupported GLIF format: %s.%s" % ( + formatVersionMajor, + formatVersionMinor, + ) + if validate: + from fontTools.ufoLib.errors import UnsupportedGLIFFormat + + raise UnsupportedGLIFFormat(msg) from e + # warn but continue using the latest supported format + formatVersion = GLIFFormatVersion.default() + logger.warning( + "%s. Assuming the latest supported version (%s). " + "Some data may be skipped or parsed incorrectly.", + msg, + formatVersion, + ) + + if validate and formatVersion not in formatVersions: + raise GlifLibError(f"Forbidden GLIF format version: {formatVersion!s}") + + try: + readGlyphFromTree = _READ_GLYPH_FROM_TREE_FUNCS[formatVersion] + except KeyError: + raise NotImplementedError(formatVersion) + + readGlyphFromTree( + tree=tree, + glyphObject=glyphObject, + pointPen=pointPen, + validate=validate, + formatMinor=formatVersion.minor, + ) + + +def _readGlyphFromTreeFormat1( + tree: ElementType, + glyphObject: Optional[Any] = None, + pointPen: Optional[AbstractPointPen] = None, + validate: bool = False, + **kwargs: Any, +) -> None: + # get the name + _readName(glyphObject, tree, validate) + # populate the sub elements + unicodes = [] + haveSeenAdvance = haveSeenOutline = haveSeenLib = haveSeenNote = False + for element in tree: + if glyphObject is None: + continue + + if element.tag == "outline": + if validate: + if haveSeenOutline: + raise GlifLibError("The outline element occurs more than once.") + if element.attrib: + raise GlifLibError( + "The outline element contains unknown attributes." + ) + if element.text and element.text.strip() != "": + raise GlifLibError("Invalid outline structure.") + haveSeenOutline = True + buildOutlineFormat1(glyphObject, pointPen, element, validate) + elif element.tag == "advance": + if validate and haveSeenAdvance: + raise GlifLibError("The advance element occurs more than once.") + haveSeenAdvance = True + _readAdvance(glyphObject, element) + elif element.tag == "unicode": + v = element.get("hex") + if v is None: + raise GlifLibError( + "A unicode element is missing its required hex attribute." + ) + try: + v = int(v, 16) + if v not in unicodes: + unicodes.append(v) + except ValueError: + raise GlifLibError( + "Illegal value for hex attribute of unicode element." + ) + elif element.tag == "note": + if validate and haveSeenNote: + raise GlifLibError("The note element occurs more than once.") + haveSeenNote = True + _readNote(glyphObject, element) + elif element.tag == "lib": + if validate and haveSeenLib: + raise GlifLibError("The lib element occurs more than once.") + haveSeenLib = True + _readLib(glyphObject, element, validate) + else: + raise GlifLibError("Unknown element in GLIF: %s" % element) + # set the collected unicodes + if unicodes: + _relaxedSetattr(glyphObject, "unicodes", unicodes) + + +def _readGlyphFromTreeFormat2( + tree: ElementType, + glyphObject: Optional[Any] = None, + pointPen: Optional[AbstractPointPen] = None, + validate: bool = False, + formatMinor: int = 0, +) -> None: + # get the name + _readName(glyphObject, tree, validate) + # populate the sub elements + unicodes = [] + guidelines = [] + anchors = [] + haveSeenAdvance = haveSeenImage = haveSeenOutline = haveSeenLib = haveSeenNote = ( + False + ) + identifiers: set[str] = set() + for element in tree: + if glyphObject is None: + continue + if element.tag == "outline": + if validate: + if haveSeenOutline: + raise GlifLibError("The outline element occurs more than once.") + if element.attrib: + raise GlifLibError( + "The outline element contains unknown attributes." + ) + if element.text and element.text.strip() != "": + raise GlifLibError("Invalid outline structure.") + haveSeenOutline = True + if pointPen is not None: + buildOutlineFormat2( + glyphObject, pointPen, element, identifiers, validate + ) + elif element.tag == "advance": + if validate and haveSeenAdvance: + raise GlifLibError("The advance element occurs more than once.") + haveSeenAdvance = True + _readAdvance(glyphObject, element) + elif element.tag == "unicode": + v = element.get("hex") + if v is None: + raise GlifLibError( + "A unicode element is missing its required hex attribute." + ) + try: + v = int(v, 16) + if v not in unicodes: + unicodes.append(v) + except ValueError: + raise GlifLibError( + "Illegal value for hex attribute of unicode element." + ) + elif element.tag == "guideline": + if validate and len(element): + raise GlifLibError("Unknown children in guideline element.") + attrib = dict(element.attrib) + for attr in ("x", "y", "angle"): + if attr in attrib: + attrib[attr] = _number(attrib[attr]) + guidelines.append(attrib) + elif element.tag == "anchor": + if validate and len(element): + raise GlifLibError("Unknown children in anchor element.") + attrib = dict(element.attrib) + for attr in ("x", "y"): + if attr in element.attrib: + attrib[attr] = _number(attrib[attr]) + anchors.append(attrib) + elif element.tag == "image": + if validate: + if haveSeenImage: + raise GlifLibError("The image element occurs more than once.") + if len(element): + raise GlifLibError("Unknown children in image element.") + haveSeenImage = True + _readImage(glyphObject, element, validate) + elif element.tag == "note": + if validate and haveSeenNote: + raise GlifLibError("The note element occurs more than once.") + haveSeenNote = True + _readNote(glyphObject, element) + elif element.tag == "lib": + if validate and haveSeenLib: + raise GlifLibError("The lib element occurs more than once.") + haveSeenLib = True + _readLib(glyphObject, element, validate) + else: + raise GlifLibError("Unknown element in GLIF: %s" % element) + # set the collected unicodes + if unicodes: + _relaxedSetattr(glyphObject, "unicodes", unicodes) + # set the collected guidelines + if guidelines: + if validate and not guidelinesValidator(guidelines, identifiers): + raise GlifLibError("The guidelines are improperly formatted.") + _relaxedSetattr(glyphObject, "guidelines", guidelines) + # set the collected anchors + if anchors: + if validate and not anchorsValidator(anchors, identifiers): + raise GlifLibError("The anchors are improperly formatted.") + _relaxedSetattr(glyphObject, "anchors", anchors) + + +_READ_GLYPH_FROM_TREE_FUNCS: dict[GLIFFormatVersion, Callable[..., Any]] = { + GLIFFormatVersion.FORMAT_1_0: _readGlyphFromTreeFormat1, + GLIFFormatVersion.FORMAT_2_0: _readGlyphFromTreeFormat2, +} + + +def _readName(glyphObject: Optional[Any], root: ElementType, validate: bool) -> None: + glyphName = root.get("name") + if validate and not glyphName: + raise GlifLibError("Empty glyph name in GLIF.") + if glyphName and glyphObject is not None: + _relaxedSetattr(glyphObject, "name", glyphName) + + +def _readAdvance(glyphObject: Optional[Any], advance: ElementType) -> None: + width = _number(advance.get("width", 0)) + _relaxedSetattr(glyphObject, "width", width) + height = _number(advance.get("height", 0)) + _relaxedSetattr(glyphObject, "height", height) + + +def _readNote(glyphObject: Optional[Any], note: ElementType) -> None: + if note.text is None: + return + lines = note.text.split("\n") + note = "\n".join(line.strip() for line in lines if line.strip()) + _relaxedSetattr(glyphObject, "note", note) + + +def _readLib(glyphObject: Optional[Any], lib: ElementType, validate: bool) -> None: + assert len(lib) == 1 + child = lib[0] + plist = plistlib.fromtree(child) + if validate: + valid, message = glyphLibValidator(plist) + if not valid: + raise GlifLibError(message) + _relaxedSetattr(glyphObject, "lib", plist) + + +def _readImage(glyphObject: Optional[Any], image: ElementType, validate: bool) -> None: + imageData = dict(image.attrib) + for attr, default in _transformationInfo: + value = imageData.get(attr, default) + imageData[attr] = _number(value) + if validate and not imageValidator(imageData): + raise GlifLibError("The image element is not properly formatted.") + _relaxedSetattr(glyphObject, "image", imageData) + + +# ---------------- +# GLIF to PointPen +# ---------------- + +contourAttributesFormat2: set[str] = {"identifier"} +componentAttributesFormat1: set[str] = { + "base", + "xScale", + "xyScale", + "yxScale", + "yScale", + "xOffset", + "yOffset", +} +componentAttributesFormat2: set[str] = componentAttributesFormat1 | {"identifier"} +pointAttributesFormat1: set[str] = {"x", "y", "type", "smooth", "name"} +pointAttributesFormat2: set[str] = pointAttributesFormat1 | {"identifier"} +pointSmoothOptions: set[str] = {"no", "yes"} +pointTypeOptions: set[str] = {"move", "line", "offcurve", "curve", "qcurve"} + +# format 1 + + +def buildOutlineFormat1( + glyphObject: Any, + pen: Optional[AbstractPointPen], + outline: Iterable[ElementType], + validate: bool, +) -> None: + anchors = [] + for element in outline: + if element.tag == "contour": + if len(element) == 1: + point = element[0] + if point.tag == "point": + anchor = _buildAnchorFormat1(point, validate) + if anchor is not None: + anchors.append(anchor) + continue + if pen is not None: + _buildOutlineContourFormat1(pen, element, validate) + elif element.tag == "component": + if pen is not None: + _buildOutlineComponentFormat1(pen, element, validate) + else: + raise GlifLibError("Unknown element in outline element: %s" % element) + if glyphObject is not None and anchors: + if validate and not anchorsValidator(anchors): + raise GlifLibError("GLIF 1 anchors are not properly formatted.") + _relaxedSetattr(glyphObject, "anchors", anchors) + + +def _buildAnchorFormat1(point: ElementType, validate: bool) -> Optional[dict[str, Any]]: + if point.get("type") != "move": + return None + name = point.get("name") + if name is None: + return None + x = point.get("x") + y = point.get("y") + if validate and x is None: + raise GlifLibError("Required x attribute is missing in point element.") + assert x is not None + if validate and y is None: + raise GlifLibError("Required y attribute is missing in point element.") + assert y is not None + x = _number(x) + y = _number(y) + anchor = dict(x=x, y=y, name=name) + return anchor + + +def _buildOutlineContourFormat1( + pen: AbstractPointPen, contour: ElementType, validate: bool +) -> None: + if validate and contour.attrib: + raise GlifLibError("Unknown attributes in contour element.") + pen.beginPath() + if len(contour): + massaged = _validateAndMassagePointStructures( + contour, + pointAttributesFormat1, + openContourOffCurveLeniency=True, + validate=validate, + ) + _buildOutlinePointsFormat1(pen, massaged) + pen.endPath() + + +def _buildOutlinePointsFormat1( + pen: AbstractPointPen, contour: list[dict[str, Any]] +) -> None: + for point in contour: + x = point["x"] + y = point["y"] + segmentType = point["segmentType"] + smooth = point["smooth"] + name = point["name"] + pen.addPoint((x, y), segmentType=segmentType, smooth=smooth, name=name) + + +def _buildOutlineComponentFormat1( + pen: AbstractPointPen, component: ElementType, validate: bool +) -> None: + if validate: + if len(component): + raise GlifLibError("Unknown child elements of component element.") + for attr in component.attrib.keys(): + if attr not in componentAttributesFormat1: + raise GlifLibError("Unknown attribute in component element: %s" % attr) + baseGlyphName = component.get("base") + if validate and baseGlyphName is None: + raise GlifLibError("The base attribute is not defined in the component.") + assert baseGlyphName is not None + transformation = tuple( + _number(component.get(attr) or default) for attr, default in _transformationInfo + ) + transformation = cast( + tuple[float, float, float, float, float, float], transformation + ) + pen.addComponent(baseGlyphName, transformation) + + +# format 2 + + +def buildOutlineFormat2( + glyphObject: Any, + pen: AbstractPointPen, + outline: Iterable[ElementType], + identifiers: set[str], + validate: bool, +) -> None: + for element in outline: + if element.tag == "contour": + _buildOutlineContourFormat2(pen, element, identifiers, validate) + elif element.tag == "component": + _buildOutlineComponentFormat2(pen, element, identifiers, validate) + else: + raise GlifLibError("Unknown element in outline element: %s" % element.tag) + + +def _buildOutlineContourFormat2( + pen: AbstractPointPen, contour: ElementType, identifiers: set[str], validate: bool +) -> None: + if validate: + for attr in contour.attrib.keys(): + if attr not in contourAttributesFormat2: + raise GlifLibError("Unknown attribute in contour element: %s" % attr) + identifier = contour.get("identifier") + if identifier is not None: + if validate: + if identifier in identifiers: + raise GlifLibError( + "The identifier %s is used more than once." % identifier + ) + if not identifierValidator(identifier): + raise GlifLibError( + "The contour identifier %s is not valid." % identifier + ) + identifiers.add(identifier) + try: + pen.beginPath(identifier=identifier) + except TypeError: + pen.beginPath() + warn( + "The beginPath method needs an identifier kwarg. The contour's identifier value has been discarded.", + DeprecationWarning, + ) + if len(contour): + massaged = _validateAndMassagePointStructures( + contour, pointAttributesFormat2, validate=validate + ) + _buildOutlinePointsFormat2(pen, massaged, identifiers, validate) + pen.endPath() + + +def _buildOutlinePointsFormat2( + pen: AbstractPointPen, + contour: list[dict[str, Any]], + identifiers: set[str], + validate: bool, +) -> None: + for point in contour: + x = point["x"] + y = point["y"] + segmentType = point["segmentType"] + smooth = point["smooth"] + name = point["name"] + identifier = point.get("identifier") + if identifier is not None: + if validate: + if identifier in identifiers: + raise GlifLibError( + "The identifier %s is used more than once." % identifier + ) + if not identifierValidator(identifier): + raise GlifLibError("The identifier %s is not valid." % identifier) + identifiers.add(identifier) + try: + pen.addPoint( + (x, y), + segmentType=segmentType, + smooth=smooth, + name=name, + identifier=identifier, + ) + except TypeError: + pen.addPoint((x, y), segmentType=segmentType, smooth=smooth, name=name) + warn( + "The addPoint method needs an identifier kwarg. The point's identifier value has been discarded.", + DeprecationWarning, + ) + + +def _buildOutlineComponentFormat2( + pen: AbstractPointPen, component: ElementType, identifiers: set[str], validate: bool +) -> None: + if validate: + if len(component): + raise GlifLibError("Unknown child elements of component element.") + for attr in component.attrib.keys(): + if attr not in componentAttributesFormat2: + raise GlifLibError("Unknown attribute in component element: %s" % attr) + baseGlyphName = component.get("base") + if validate and baseGlyphName is None: + raise GlifLibError("The base attribute is not defined in the component.") + assert baseGlyphName is not None + transformation = tuple( + _number(component.get(attr) or default) for attr, default in _transformationInfo + ) + transformation = cast( + tuple[float, float, float, float, float, float], transformation + ) + identifier = component.get("identifier") + if identifier is not None: + if validate: + if identifier in identifiers: + raise GlifLibError( + "The identifier %s is used more than once." % identifier + ) + if validate and not identifierValidator(identifier): + raise GlifLibError("The identifier %s is not valid." % identifier) + identifiers.add(identifier) + try: + pen.addComponent(baseGlyphName, transformation, identifier=identifier) + except TypeError: + pen.addComponent(baseGlyphName, transformation) + warn( + "The addComponent method needs an identifier kwarg. The component's identifier value has been discarded.", + DeprecationWarning, + ) + + +# all formats + + +def _validateAndMassagePointStructures( + contour, pointAttributes, openContourOffCurveLeniency=False, validate=True +): + if not len(contour): + return + # store some data for later validation + lastOnCurvePoint = None + haveOffCurvePoint = False + # validate and massage the individual point elements + massaged = [] + for index, element in enumerate(contour): + # not <point> + if element.tag != "point": + raise GlifLibError( + "Unknown child element (%s) of contour element." % element.tag + ) + point = dict(element.attrib) + massaged.append(point) + if validate: + # unknown attributes + for attr in point.keys(): + if attr not in pointAttributes: + raise GlifLibError("Unknown attribute in point element: %s" % attr) + # search for unknown children + if len(element): + raise GlifLibError("Unknown child elements in point element.") + # x and y are required + for attr in ("x", "y"): + try: + point[attr] = _number(point[attr]) + except KeyError as e: + raise GlifLibError( + f"Required {attr} attribute is missing in point element." + ) from e + # segment type + pointType = point.pop("type", "offcurve") + if validate and pointType not in pointTypeOptions: + raise GlifLibError("Unknown point type: %s" % pointType) + if pointType == "offcurve": + pointType = None + point["segmentType"] = pointType + if pointType is None: + haveOffCurvePoint = True + else: + lastOnCurvePoint = index + # move can only occur as the first point + if validate and pointType == "move" and index != 0: + raise GlifLibError( + "A move point occurs after the first point in the contour." + ) + # smooth is optional + smooth = point.get("smooth", "no") + if validate and smooth is not None: + if smooth not in pointSmoothOptions: + raise GlifLibError("Unknown point smooth value: %s" % smooth) + smooth = smooth == "yes" + point["smooth"] = smooth + # smooth can only be applied to curve and qcurve + if validate and smooth and pointType is None: + raise GlifLibError("smooth attribute set in an offcurve point.") + # name is optional + if "name" not in element.attrib: + point["name"] = None + if openContourOffCurveLeniency: + # remove offcurves that precede a move. this is technically illegal, + # but we let it slide because there are fonts out there in the wild like this. + if massaged[0]["segmentType"] == "move": + count = 0 + for point in reversed(massaged): + if point["segmentType"] is None: + count += 1 + else: + break + if count: + massaged = massaged[:-count] + # validate the off-curves in the segments + if validate and haveOffCurvePoint and lastOnCurvePoint is not None: + # we only care about how many offCurves there are before an onCurve + # filter out the trailing offCurves + offCurvesCount = len(massaged) - 1 - lastOnCurvePoint + for point in massaged: + segmentType = point["segmentType"] + if segmentType is None: + offCurvesCount += 1 + else: + if offCurvesCount: + # move and line can't be preceded by off-curves + if segmentType == "move": + # this will have been filtered out already + raise GlifLibError("move can not have an offcurve.") + elif segmentType == "line": + raise GlifLibError("line can not have an offcurve.") + elif segmentType == "curve": + if offCurvesCount > 2: + raise GlifLibError("Too many offcurves defined for curve.") + elif segmentType == "qcurve": + pass + else: + # unknown segment type. it'll be caught later. + pass + offCurvesCount = 0 + return massaged + + +# --------------------- +# Misc Helper Functions +# --------------------- + + +def _relaxedSetattr(object: Any, attr: str, value: Any) -> None: + try: + setattr(object, attr, value) + except AttributeError: + pass + + +def _number(s: Union[str, int, float]) -> IntFloat: + """ + Given a numeric string, return an integer or a float, whichever + the string indicates. _number("1") will return the integer 1, + _number("1.0") will return the float 1.0. + + >>> _number("1") + 1 + >>> _number("1.0") + 1.0 + >>> _number("a") # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + GlifLibError: Could not convert a to an int or float. + """ + try: + n: IntFloat = int(s) + return n + except ValueError: + pass + try: + n = float(s) + return n + except ValueError: + raise GlifLibError("Could not convert %s to an int or float." % s) + + +# -------------------- +# Rapid Value Fetching +# -------------------- + +# base + + +class _DoneParsing(Exception): + pass + + +class _BaseParser: + def __init__(self) -> None: + self._elementStack: list[str] = [] + + def parse(self, text: bytes): + from xml.parsers.expat import ParserCreate + + parser = ParserCreate() + parser.StartElementHandler = self.startElementHandler + parser.EndElementHandler = self.endElementHandler + parser.Parse(text, True) + + def startElementHandler(self, name: str, attrs: Any) -> None: + self._elementStack.append(name) + + def endElementHandler(self, name: str) -> None: + other = self._elementStack.pop(-1) + assert other == name + + +# unicodes + + +def _fetchUnicodes(glif: bytes) -> list[int]: + """ + Get a list of unicodes listed in glif. + """ + parser = _FetchUnicodesParser() + parser.parse(glif) + return parser.unicodes + + +class _FetchUnicodesParser(_BaseParser): + def __init__(self) -> None: + self.unicodes: list[int] = [] + super().__init__() + + def startElementHandler(self, name: str, attrs: dict[str, str]) -> None: + if ( + name == "unicode" + and self._elementStack + and self._elementStack[-1] == "glyph" + ): + value = attrs.get("hex") + if value is not None: + try: + intValue = int(value, 16) + if intValue not in self.unicodes: + self.unicodes.append(intValue) + except ValueError: + pass + super().startElementHandler(name, attrs) + + +# image + + +def _fetchImageFileName(glif: bytes) -> Optional[str]: + """ + The image file name (if any) from glif. + """ + parser = _FetchImageFileNameParser() + try: + parser.parse(glif) + except _DoneParsing: + pass + return parser.fileName + + +class _FetchImageFileNameParser(_BaseParser): + def __init__(self) -> None: + self.fileName: Optional[str] = None + super().__init__() + + def startElementHandler(self, name: str, attrs: dict[str, str]) -> None: + if name == "image" and self._elementStack and self._elementStack[-1] == "glyph": + self.fileName = attrs.get("fileName") + raise _DoneParsing + super().startElementHandler(name, attrs) + + +# component references + + +def _fetchComponentBases(glif: bytes) -> list[str]: + """ + Get a list of component base glyphs listed in glif. + """ + parser = _FetchComponentBasesParser() + try: + parser.parse(glif) + except _DoneParsing: + pass + return list(parser.bases) + + +class _FetchComponentBasesParser(_BaseParser): + def __init__(self) -> None: + self.bases: list[str] = [] + super().__init__() + + def startElementHandler(self, name: str, attrs: dict[str, str]) -> None: + if ( + name == "component" + and self._elementStack + and self._elementStack[-1] == "outline" + ): + base = attrs.get("base") + if base is not None: + self.bases.append(base) + super().startElementHandler(name, attrs) + + def endElementHandler(self, name: str) -> None: + if name == "outline": + raise _DoneParsing + super().endElementHandler(name) + + +# -------------- +# GLIF Point Pen +# -------------- + +_transformationInfo: list[tuple[str, int]] = [ + # field name, default value + ("xScale", 1), + ("xyScale", 0), + ("yxScale", 0), + ("yScale", 1), + ("xOffset", 0), + ("yOffset", 0), +] + + +class GLIFPointPen(AbstractPointPen): + """ + Helper class using the PointPen protocol to write the <outline> + part of .glif files. + """ + + def __init__( + self, + element: ElementType, + formatVersion: Optional[FormatVersion] = None, + identifiers: Optional[set[str]] = None, + validate: bool = True, + ) -> None: + if identifiers is None: + identifiers = set() + self.formatVersion = normalizeFormatVersion(formatVersion, GLIFFormatVersion) + self.identifiers = identifiers + self.outline = element + self.contour = None + self.prevOffCurveCount = 0 + self.prevPointTypes: list[str] = [] + self.validate = validate + + def beginPath(self, identifier=None, **kwargs): + attrs = OrderedDict() + if identifier is not None and self.formatVersion.major >= 2: + if self.validate: + if identifier in self.identifiers: + raise GlifLibError( + "identifier used more than once: %s" % identifier + ) + if not identifierValidator(identifier): + raise GlifLibError( + "identifier not formatted properly: %s" % identifier + ) + attrs["identifier"] = identifier + self.identifiers.add(identifier) + self.contour = etree.SubElement(self.outline, "contour", attrs) + self.prevOffCurveCount = 0 + + def endPath(self): + if self.prevPointTypes and self.prevPointTypes[0] == "move": + if self.validate and self.prevPointTypes[-1] == "offcurve": + raise GlifLibError("open contour has loose offcurve point") + # prevent lxml from writing self-closing tags + if not len(self.contour): + self.contour.text = "\n " + self.contour = None + self.prevPointType = None + self.prevOffCurveCount = 0 + self.prevPointTypes = [] + + def addPoint( + self, pt, segmentType=None, smooth=None, name=None, identifier=None, **kwargs + ): + attrs = OrderedDict() + # coordinates + if pt is not None: + if self.validate: + for coord in pt: + if not isinstance(coord, numberTypes): + raise GlifLibError("coordinates must be int or float") + attrs["x"] = repr(pt[0]) + attrs["y"] = repr(pt[1]) + # segment type + if segmentType == "offcurve": + segmentType = None + if self.validate: + if segmentType == "move" and self.prevPointTypes: + raise GlifLibError( + "move occurs after a point has already been added to the contour." + ) + if ( + segmentType in ("move", "line") + and self.prevPointTypes + and self.prevPointTypes[-1] == "offcurve" + ): + raise GlifLibError("offcurve occurs before %s point." % segmentType) + if segmentType == "curve" and self.prevOffCurveCount > 2: + raise GlifLibError("too many offcurve points before curve point.") + if segmentType is not None: + attrs["type"] = segmentType + else: + segmentType = "offcurve" + if segmentType == "offcurve": + self.prevOffCurveCount += 1 + else: + self.prevOffCurveCount = 0 + self.prevPointTypes.append(segmentType) + # smooth + if smooth: + if self.validate and segmentType == "offcurve": + raise GlifLibError("can't set smooth in an offcurve point.") + attrs["smooth"] = "yes" + # name + if name is not None: + attrs["name"] = name + # identifier + if identifier is not None and self.formatVersion.major >= 2: + if self.validate: + if identifier in self.identifiers: + raise GlifLibError( + "identifier used more than once: %s" % identifier + ) + if not identifierValidator(identifier): + raise GlifLibError( + "identifier not formatted properly: %s" % identifier + ) + attrs["identifier"] = identifier + self.identifiers.add(identifier) + etree.SubElement(self.contour, "point", attrs) + + def addComponent(self, glyphName, transformation, identifier=None, **kwargs): + attrs = OrderedDict([("base", glyphName)]) + for (attr, default), value in zip(_transformationInfo, transformation): + if self.validate and not isinstance(value, numberTypes): + raise GlifLibError("transformation values must be int or float") + if value != default: + attrs[attr] = repr(value) + if identifier is not None and self.formatVersion.major >= 2: + if self.validate: + if identifier in self.identifiers: + raise GlifLibError( + "identifier used more than once: %s" % identifier + ) + if self.validate and not identifierValidator(identifier): + raise GlifLibError( + "identifier not formatted properly: %s" % identifier + ) + attrs["identifier"] = identifier + self.identifiers.add(identifier) + etree.SubElement(self.outline, "component", attrs) + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/.venv/lib/python3.13/site-packages/fontTools/ufoLib/kerning.py b/.venv/lib/python3.13/site-packages/fontTools/ufoLib/kerning.py new file mode 100644 index 0000000000000000000000000000000000000000..01ae55c062cad4ef8e6f7c0a400c51f17cb29d58 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ufoLib/kerning.py @@ -0,0 +1,141 @@ +from __future__ import annotations + +from typing import Optional + +from fontTools.annotations import KerningPair, KerningDict, KerningGroups, IntFloat + +StrDict = dict[str, str] + + +def lookupKerningValue( + pair: KerningPair, + kerning: KerningDict, + groups: KerningGroups, + fallback: IntFloat = 0, + glyphToFirstGroup: Optional[StrDict] = None, + glyphToSecondGroup: Optional[StrDict] = None, +) -> IntFloat: + """Retrieve the kerning value (if any) between a pair of elements. + + The elments can be either individual glyphs (by name) or kerning + groups (by name), or any combination of the two. + + Args: + pair: + A tuple, in logical order (first, second) with respect + to the reading direction, to query the font for kerning + information on. Each element in the tuple can be either + a glyph name or a kerning group name. + kerning: + A dictionary of kerning pairs. + groups: + A set of kerning groups. + fallback: + The fallback value to return if no kern is found between + the elements in ``pair``. Defaults to 0. + glyphToFirstGroup: + A dictionary mapping glyph names to the first-glyph kerning + groups to which they belong. Defaults to ``None``. + glyphToSecondGroup: + A dictionary mapping glyph names to the second-glyph kerning + groups to which they belong. Defaults to ``None``. + + Returns: + The kerning value between the element pair. If no kerning for + the pair is found, the fallback value is returned. + + Note: This function expects the ``kerning`` argument to be a flat + dictionary of kerning pairs, not the nested structure used in a + kerning.plist file. + + Examples:: + + >>> groups = { + ... "public.kern1.O" : ["O", "D", "Q"], + ... "public.kern2.E" : ["E", "F"] + ... } + >>> kerning = { + ... ("public.kern1.O", "public.kern2.E") : -100, + ... ("public.kern1.O", "F") : -200, + ... ("D", "F") : -300 + ... } + >>> lookupKerningValue(("D", "F"), kerning, groups) + -300 + >>> lookupKerningValue(("O", "F"), kerning, groups) + -200 + >>> lookupKerningValue(("O", "E"), kerning, groups) + -100 + >>> lookupKerningValue(("O", "O"), kerning, groups) + 0 + >>> lookupKerningValue(("E", "E"), kerning, groups) + 0 + >>> lookupKerningValue(("E", "O"), kerning, groups) + 0 + >>> lookupKerningValue(("X", "X"), kerning, groups) + 0 + >>> lookupKerningValue(("public.kern1.O", "public.kern2.E"), + ... kerning, groups) + -100 + >>> lookupKerningValue(("public.kern1.O", "F"), kerning, groups) + -200 + >>> lookupKerningValue(("O", "public.kern2.E"), kerning, groups) + -100 + >>> lookupKerningValue(("public.kern1.X", "public.kern2.X"), kerning, groups) + 0 + """ + # quickly check to see if the pair is in the kerning dictionary + if pair in kerning: + return kerning[pair] + # ensure both or no glyph-to-group mappings are provided + if (glyphToFirstGroup is None) != (glyphToSecondGroup is None): + raise ValueError( + "Must provide both 'glyphToFirstGroup' and 'glyphToSecondGroup', or neither." + ) + # create glyph to group mapping + if glyphToFirstGroup is None: + glyphToFirstGroup = {} + glyphToSecondGroup = {} + for group, groupMembers in groups.items(): + if group.startswith("public.kern1."): + for glyph in groupMembers: + glyphToFirstGroup[glyph] = group + elif group.startswith("public.kern2."): + for glyph in groupMembers: + glyphToSecondGroup[glyph] = group + # ensure type safety for mappings + assert glyphToFirstGroup is not None + assert glyphToSecondGroup is not None + # get group names and make sure first and second are glyph names + first, second = pair + firstGroup = secondGroup = None + if first.startswith("public.kern1."): + firstGroup = first + firstGlyph = None + else: + firstGroup = glyphToFirstGroup.get(first) + firstGlyph = first + if second.startswith("public.kern2."): + secondGroup = second + secondGlyph = None + else: + secondGroup = glyphToSecondGroup.get(second) + secondGlyph = second + # make an ordered list of pairs to look up + pairs = [ + (a, b) + for a in (firstGlyph, firstGroup) + for b in (secondGlyph, secondGroup) + if a is not None and b is not None + ] + # look up the pairs and return any matches + for pair in pairs: + if pair in kerning: + return kerning[pair] + # use the fallback value + return fallback + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/.venv/lib/python3.13/site-packages/fontTools/ufoLib/pointPen.py b/.venv/lib/python3.13/site-packages/fontTools/ufoLib/pointPen.py new file mode 100644 index 0000000000000000000000000000000000000000..4a8126cd6481a39b5bfeec7348c8efd168118236 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ufoLib/pointPen.py @@ -0,0 +1,6 @@ +"""DEPRECATED - This module is kept here only as a backward compatibility shim +for the old `ufoLib.pointPen` module, which was moved to :class:`fontTools.pens.pointPen`. +Please use the latter instead. +""" + +from fontTools.pens.pointPen import * diff --git a/.venv/lib/python3.13/site-packages/fontTools/ufoLib/validators.py b/.venv/lib/python3.13/site-packages/fontTools/ufoLib/validators.py new file mode 100644 index 0000000000000000000000000000000000000000..54c65fb6cf6da81c98986a45b21102f8e476a8d6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/ufoLib/validators.py @@ -0,0 +1,1208 @@ +"""Various low level data validators.""" + +from __future__ import annotations + +import calendar +from collections.abc import Mapping, Sequence +from io import open + +import fontTools.misc.filesystem as fs +from typing import Any, Type, Optional, Union + +from fontTools.annotations import IntFloat +from fontTools.ufoLib.utils import numberTypes + +GenericDict = dict[str, tuple[Union[type, tuple[Type[Any], ...]], bool]] + +# ------- +# Generic +# ------- + + +def isDictEnough(value: Any) -> bool: + """ + Some objects will likely come in that aren't + dicts but are dict-ish enough. + """ + if isinstance(value, Mapping): + return True + for attr in ("keys", "values", "items"): + if not hasattr(value, attr): + return False + return True + + +def genericTypeValidator(value: Any, typ: Type[Any]) -> bool: + """ + Generic. (Added at version 2.) + """ + return isinstance(value, typ) + + +def genericIntListValidator(values: Any, validValues: Sequence[int]) -> bool: + """ + Generic. (Added at version 2.) + """ + if not isinstance(values, (list, tuple)): + return False + valuesSet = set(values) + validValuesSet = set(validValues) + if valuesSet - validValuesSet: + return False + for value in values: + if not isinstance(value, int): + return False + return True + + +def genericNonNegativeIntValidator(value: Any) -> bool: + """ + Generic. (Added at version 3.) + """ + if not isinstance(value, int): + return False + if value < 0: + return False + return True + + +def genericNonNegativeNumberValidator(value: Any) -> bool: + """ + Generic. (Added at version 3.) + """ + if not isinstance(value, numberTypes): + return False + if value < 0: + return False + return True + + +def genericDictValidator(value: Any, prototype: GenericDict) -> bool: + """ + Generic. (Added at version 3.) + """ + # not a dict + if not isinstance(value, Mapping): + return False + # missing required keys + for key, (typ, required) in prototype.items(): + if not required: + continue + if key not in value: + return False + # unknown keys + for key in value.keys(): + if key not in prototype: + return False + # incorrect types + for key, v in value.items(): + prototypeType, required = prototype[key] + if v is None and not required: + continue + if not isinstance(v, prototypeType): + return False + return True + + +# -------------- +# fontinfo.plist +# -------------- + +# Data Validators + + +def fontInfoStyleMapStyleNameValidator(value: Any) -> bool: + """ + Version 2+. + """ + options = ["regular", "italic", "bold", "bold italic"] + return value in options + + +def fontInfoOpenTypeGaspRangeRecordsValidator(value: Any) -> bool: + """ + Version 3+. + """ + if not isinstance(value, list): + return False + if len(value) == 0: + return True + validBehaviors = [0, 1, 2, 3] + dictPrototype: GenericDict = dict( + rangeMaxPPEM=(int, True), rangeGaspBehavior=(list, True) + ) + ppemOrder = [] + for rangeRecord in value: + if not genericDictValidator(rangeRecord, dictPrototype): + return False + ppem = rangeRecord["rangeMaxPPEM"] + behavior = rangeRecord["rangeGaspBehavior"] + ppemValidity = genericNonNegativeIntValidator(ppem) + if not ppemValidity: + return False + behaviorValidity = genericIntListValidator(behavior, validBehaviors) + if not behaviorValidity: + return False + ppemOrder.append(ppem) + if ppemOrder != sorted(ppemOrder): + return False + return True + + +def fontInfoOpenTypeHeadCreatedValidator(value: Any) -> bool: + """ + Version 2+. + """ + # format: 0000/00/00 00:00:00 + if not isinstance(value, str): + return False + # basic formatting + if not len(value) == 19: + return False + if value.count(" ") != 1: + return False + strDate, strTime = value.split(" ") + if strDate.count("/") != 2: + return False + if strTime.count(":") != 2: + return False + # date + strYear, strMonth, strDay = strDate.split("/") + if len(strYear) != 4: + return False + if len(strMonth) != 2: + return False + if len(strDay) != 2: + return False + try: + intYear = int(strYear) + intMonth = int(strMonth) + intDay = int(strDay) + except ValueError: + return False + if intMonth < 1 or intMonth > 12: + return False + monthMaxDay = calendar.monthrange(intYear, intMonth)[1] + if intDay < 1 or intDay > monthMaxDay: + return False + # time + strHour, strMinute, strSecond = strTime.split(":") + if len(strHour) != 2: + return False + if len(strMinute) != 2: + return False + if len(strSecond) != 2: + return False + try: + intHour = int(strHour) + intMinute = int(strMinute) + intSecond = int(strSecond) + except ValueError: + return False + if intHour < 0 or intHour > 23: + return False + if intMinute < 0 or intMinute > 59: + return False + if intSecond < 0 or intSecond > 59: + return False + # fallback + return True + + +def fontInfoOpenTypeNameRecordsValidator(value: Any) -> bool: + """ + Version 3+. + """ + if not isinstance(value, list): + return False + dictPrototype: GenericDict = dict( + nameID=(int, True), + platformID=(int, True), + encodingID=(int, True), + languageID=(int, True), + string=(str, True), + ) + for nameRecord in value: + if not genericDictValidator(nameRecord, dictPrototype): + return False + return True + + +def fontInfoOpenTypeOS2WeightClassValidator(value: Any) -> bool: + """ + Version 2+. + """ + if not isinstance(value, int): + return False + if value < 0: + return False + return True + + +def fontInfoOpenTypeOS2WidthClassValidator(value: Any) -> bool: + """ + Version 2+. + """ + if not isinstance(value, int): + return False + if value < 1: + return False + if value > 9: + return False + return True + + +def fontInfoVersion2OpenTypeOS2PanoseValidator(values: Any) -> bool: + """ + Version 2. + """ + if not isinstance(values, (list, tuple)): + return False + if len(values) != 10: + return False + for value in values: + if not isinstance(value, int): + return False + # XXX further validation? + return True + + +def fontInfoVersion3OpenTypeOS2PanoseValidator(values: Any) -> bool: + """ + Version 3+. + """ + if not isinstance(values, (list, tuple)): + return False + if len(values) != 10: + return False + for value in values: + if not isinstance(value, int): + return False + if value < 0: + return False + # XXX further validation? + return True + + +def fontInfoOpenTypeOS2FamilyClassValidator(values: Any) -> bool: + """ + Version 2+. + """ + if not isinstance(values, (list, tuple)): + return False + if len(values) != 2: + return False + for value in values: + if not isinstance(value, int): + return False + classID, subclassID = values + if classID < 0 or classID > 14: + return False + if subclassID < 0 or subclassID > 15: + return False + return True + + +def fontInfoPostscriptBluesValidator(values: Any) -> bool: + """ + Version 2+. + """ + if not isinstance(values, (list, tuple)): + return False + if len(values) > 14: + return False + if len(values) % 2: + return False + for value in values: + if not isinstance(value, numberTypes): + return False + return True + + +def fontInfoPostscriptOtherBluesValidator(values: Any) -> bool: + """ + Version 2+. + """ + if not isinstance(values, (list, tuple)): + return False + if len(values) > 10: + return False + if len(values) % 2: + return False + for value in values: + if not isinstance(value, numberTypes): + return False + return True + + +def fontInfoPostscriptStemsValidator(values: Any) -> bool: + """ + Version 2+. + """ + if not isinstance(values, (list, tuple)): + return False + if len(values) > 12: + return False + for value in values: + if not isinstance(value, numberTypes): + return False + return True + + +def fontInfoPostscriptWindowsCharacterSetValidator(value: Any) -> bool: + """ + Version 2+. + """ + validValues = list(range(1, 21)) + if value not in validValues: + return False + return True + + +def fontInfoWOFFMetadataUniqueIDValidator(value: Any) -> bool: + """ + Version 3+. + """ + dictPrototype: GenericDict = dict(id=(str, True)) + if not genericDictValidator(value, dictPrototype): + return False + return True + + +def fontInfoWOFFMetadataVendorValidator(value: Any) -> bool: + """ + Version 3+. + """ + dictPrototype: GenericDict = { + "name": (str, True), + "url": (str, False), + "dir": (str, False), + "class": (str, False), + } + if not genericDictValidator(value, dictPrototype): + return False + if "dir" in value and value.get("dir") not in ("ltr", "rtl"): + return False + return True + + +def fontInfoWOFFMetadataCreditsValidator(value: Any) -> bool: + """ + Version 3+. + """ + dictPrototype: GenericDict = dict(credits=(list, True)) + if not genericDictValidator(value, dictPrototype): + return False + if not len(value["credits"]): + return False + dictPrototype = { + "name": (str, True), + "url": (str, False), + "role": (str, False), + "dir": (str, False), + "class": (str, False), + } + for credit in value["credits"]: + if not genericDictValidator(credit, dictPrototype): + return False + if "dir" in credit and credit.get("dir") not in ("ltr", "rtl"): + return False + return True + + +def fontInfoWOFFMetadataDescriptionValidator(value: Any) -> bool: + """ + Version 3+. + """ + dictPrototype: GenericDict = dict(url=(str, False), text=(list, True)) + if not genericDictValidator(value, dictPrototype): + return False + for text in value["text"]: + if not fontInfoWOFFMetadataTextValue(text): + return False + return True + + +def fontInfoWOFFMetadataLicenseValidator(value: Any) -> bool: + """ + Version 3+. + """ + dictPrototype: GenericDict = dict( + url=(str, False), text=(list, False), id=(str, False) + ) + if not genericDictValidator(value, dictPrototype): + return False + if "text" in value: + for text in value["text"]: + if not fontInfoWOFFMetadataTextValue(text): + return False + return True + + +def fontInfoWOFFMetadataTrademarkValidator(value: Any) -> bool: + """ + Version 3+. + """ + dictPrototype: GenericDict = dict(text=(list, True)) + if not genericDictValidator(value, dictPrototype): + return False + for text in value["text"]: + if not fontInfoWOFFMetadataTextValue(text): + return False + return True + + +def fontInfoWOFFMetadataCopyrightValidator(value: Any) -> bool: + """ + Version 3+. + """ + dictPrototype: GenericDict = dict(text=(list, True)) + if not genericDictValidator(value, dictPrototype): + return False + for text in value["text"]: + if not fontInfoWOFFMetadataTextValue(text): + return False + return True + + +def fontInfoWOFFMetadataLicenseeValidator(value: Any) -> bool: + """ + Version 3+. + """ + dictPrototype: GenericDict = { + "name": (str, True), + "dir": (str, False), + "class": (str, False), + } + if not genericDictValidator(value, dictPrototype): + return False + if "dir" in value and value.get("dir") not in ("ltr", "rtl"): + return False + return True + + +def fontInfoWOFFMetadataTextValue(value: Any) -> bool: + """ + Version 3+. + """ + dictPrototype: GenericDict = { + "text": (str, True), + "language": (str, False), + "dir": (str, False), + "class": (str, False), + } + if not genericDictValidator(value, dictPrototype): + return False + if "dir" in value and value.get("dir") not in ("ltr", "rtl"): + return False + return True + + +def fontInfoWOFFMetadataExtensionsValidator(value: Any) -> bool: + """ + Version 3+. + """ + if not isinstance(value, list): + return False + if not value: + return False + for extension in value: + if not fontInfoWOFFMetadataExtensionValidator(extension): + return False + return True + + +def fontInfoWOFFMetadataExtensionValidator(value: Any) -> bool: + """ + Version 3+. + """ + dictPrototype: GenericDict = dict( + names=(list, False), items=(list, True), id=(str, False) + ) + if not genericDictValidator(value, dictPrototype): + return False + if "names" in value: + for name in value["names"]: + if not fontInfoWOFFMetadataExtensionNameValidator(name): + return False + for item in value["items"]: + if not fontInfoWOFFMetadataExtensionItemValidator(item): + return False + return True + + +def fontInfoWOFFMetadataExtensionItemValidator(value: Any) -> bool: + """ + Version 3+. + """ + dictPrototype: GenericDict = dict( + id=(str, False), names=(list, True), values=(list, True) + ) + if not genericDictValidator(value, dictPrototype): + return False + for name in value["names"]: + if not fontInfoWOFFMetadataExtensionNameValidator(name): + return False + for val in value["values"]: + if not fontInfoWOFFMetadataExtensionValueValidator(val): + return False + return True + + +def fontInfoWOFFMetadataExtensionNameValidator(value: Any) -> bool: + """ + Version 3+. + """ + dictPrototype: GenericDict = { + "text": (str, True), + "language": (str, False), + "dir": (str, False), + "class": (str, False), + } + if not genericDictValidator(value, dictPrototype): + return False + if "dir" in value and value.get("dir") not in ("ltr", "rtl"): + return False + return True + + +def fontInfoWOFFMetadataExtensionValueValidator(value: Any) -> bool: + """ + Version 3+. + """ + dictPrototype: GenericDict = { + "text": (str, True), + "language": (str, False), + "dir": (str, False), + "class": (str, False), + } + if not genericDictValidator(value, dictPrototype): + return False + if "dir" in value and value.get("dir") not in ("ltr", "rtl"): + return False + return True + + +# ---------- +# Guidelines +# ---------- + + +def guidelinesValidator(value: Any, identifiers: Optional[set[str]] = None) -> bool: + """ + Version 3+. + """ + if not isinstance(value, list): + return False + if identifiers is None: + identifiers = set() + for guide in value: + if not guidelineValidator(guide): + return False + identifier = guide.get("identifier") + if identifier is not None: + if identifier in identifiers: + return False + identifiers.add(identifier) + return True + + +_guidelineDictPrototype: GenericDict = dict( + x=((int, float), False), + y=((int, float), False), + angle=((int, float), False), + name=(str, False), + color=(str, False), + identifier=(str, False), +) + + +def guidelineValidator(value: Any) -> bool: + """ + Version 3+. + """ + if not genericDictValidator(value, _guidelineDictPrototype): + return False + x = value.get("x") + y = value.get("y") + angle = value.get("angle") + # x or y must be present + if x is None and y is None: + return False + # if x or y are None, angle must not be present + if x is None or y is None: + if angle is not None: + return False + # if x and y are defined, angle must be defined + if x is not None and y is not None and angle is None: + return False + # angle must be between 0 and 360 + if angle is not None: + if angle < 0: + return False + if angle > 360: + return False + # identifier must be 1 or more characters + identifier = value.get("identifier") + if identifier is not None and not identifierValidator(identifier): + return False + # color must follow the proper format + color = value.get("color") + if color is not None and not colorValidator(color): + return False + return True + + +# ------- +# Anchors +# ------- + + +def anchorsValidator(value: Any, identifiers: Optional[set[str]] = None) -> bool: + """ + Version 3+. + """ + if not isinstance(value, list): + return False + if identifiers is None: + identifiers = set() + for anchor in value: + if not anchorValidator(anchor): + return False + identifier = anchor.get("identifier") + if identifier is not None: + if identifier in identifiers: + return False + identifiers.add(identifier) + return True + + +_anchorDictPrototype: GenericDict = dict( + x=((int, float), False), + y=((int, float), False), + name=(str, False), + color=(str, False), + identifier=(str, False), +) + + +def anchorValidator(value: Any) -> bool: + """ + Version 3+. + """ + if not genericDictValidator(value, _anchorDictPrototype): + return False + x = value.get("x") + y = value.get("y") + # x and y must be present + if x is None or y is None: + return False + # identifier must be 1 or more characters + identifier = value.get("identifier") + if identifier is not None and not identifierValidator(identifier): + return False + # color must follow the proper format + color = value.get("color") + if color is not None and not colorValidator(color): + return False + return True + + +# ---------- +# Identifier +# ---------- + + +def identifierValidator(value: Any) -> bool: + """ + Version 3+. + + >>> identifierValidator("a") + True + >>> identifierValidator("") + False + >>> identifierValidator("a" * 101) + False + """ + validCharactersMin = 0x20 + validCharactersMax = 0x7E + if not isinstance(value, str): + return False + if not value: + return False + if len(value) > 100: + return False + for c in value: + i = ord(c) + if i < validCharactersMin or i > validCharactersMax: + return False + return True + + +# ----- +# Color +# ----- + + +def colorValidator(value: Any) -> bool: + """ + Version 3+. + + >>> colorValidator("0,0,0,0") + True + >>> colorValidator(".5,.5,.5,.5") + True + >>> colorValidator("0.5,0.5,0.5,0.5") + True + >>> colorValidator("1,1,1,1") + True + + >>> colorValidator("2,0,0,0") + False + >>> colorValidator("0,2,0,0") + False + >>> colorValidator("0,0,2,0") + False + >>> colorValidator("0,0,0,2") + False + + >>> colorValidator("1r,1,1,1") + False + >>> colorValidator("1,1g,1,1") + False + >>> colorValidator("1,1,1b,1") + False + >>> colorValidator("1,1,1,1a") + False + + >>> colorValidator("1 1 1 1") + False + >>> colorValidator("1 1,1,1") + False + >>> colorValidator("1,1 1,1") + False + >>> colorValidator("1,1,1 1") + False + + >>> colorValidator("1, 1, 1, 1") + True + """ + if not isinstance(value, str): + return False + parts = value.split(",") + if len(parts) != 4: + return False + for part in parts: + part = part.strip() + converted = False + number: IntFloat + try: + number = int(part) + converted = True + except ValueError: + pass + if not converted: + try: + number = float(part) + converted = True + except ValueError: + pass + if not converted: + return False + if not 0 <= number <= 1: + return False + return True + + +# ----- +# image +# ----- + +pngSignature: bytes = b"\x89PNG\r\n\x1a\n" + +_imageDictPrototype: GenericDict = dict( + fileName=(str, True), + xScale=((int, float), False), + xyScale=((int, float), False), + yxScale=((int, float), False), + yScale=((int, float), False), + xOffset=((int, float), False), + yOffset=((int, float), False), + color=(str, False), +) + + +def imageValidator(value): + """ + Version 3+. + """ + if not genericDictValidator(value, _imageDictPrototype): + return False + # fileName must be one or more characters + if not value["fileName"]: + return False + # color must follow the proper format + color = value.get("color") + if color is not None and not colorValidator(color): + return False + return True + + +def pngValidator( + path: Optional[str] = None, + data: Optional[bytes] = None, + fileObj: Optional[Any] = None, +) -> tuple[bool, Any]: + """ + Version 3+. + + This checks the signature of the image data. + """ + assert path is not None or data is not None or fileObj is not None + if path is not None: + with open(path, "rb") as f: + signature = f.read(8) + elif data is not None: + signature = data[:8] + elif fileObj is not None: + pos = fileObj.tell() + signature = fileObj.read(8) + fileObj.seek(pos) + if signature != pngSignature: + return False, "Image does not begin with the PNG signature." + return True, None + + +# ------------------- +# layercontents.plist +# ------------------- + + +def layerContentsValidator( + value: Any, ufoPathOrFileSystem: Union[str, fs.base.FS] +) -> tuple[bool, Optional[str]]: + """ + Check the validity of layercontents.plist. + Version 3+. + """ + if isinstance(ufoPathOrFileSystem, fs.base.FS): + fileSystem = ufoPathOrFileSystem + else: + fileSystem = fs.osfs.OSFS(ufoPathOrFileSystem) + + bogusFileMessage = "layercontents.plist in not in the correct format." + # file isn't in the right format + if not isinstance(value, list): + return False, bogusFileMessage + # work through each entry + usedLayerNames = set() + usedDirectories = set() + contents = {} + for entry in value: + # layer entry in the incorrect format + if not isinstance(entry, list): + return False, bogusFileMessage + if not len(entry) == 2: + return False, bogusFileMessage + for i in entry: + if not isinstance(i, str): + return False, bogusFileMessage + layerName, directoryName = entry + # check directory naming + if directoryName != "glyphs": + if not directoryName.startswith("glyphs."): + return ( + False, + "Invalid directory name (%s) in layercontents.plist." + % directoryName, + ) + if len(layerName) == 0: + return False, "Empty layer name in layercontents.plist." + # directory doesn't exist + if not fileSystem.exists(directoryName): + return False, "A glyphset does not exist at %s." % directoryName + # default layer name + if layerName == "public.default" and directoryName != "glyphs": + return ( + False, + "The name public.default is being used by a layer that is not the default.", + ) + # check usage + if layerName in usedLayerNames: + return ( + False, + "The layer name %s is used by more than one layer." % layerName, + ) + usedLayerNames.add(layerName) + if directoryName in usedDirectories: + return ( + False, + "The directory %s is used by more than one layer." % directoryName, + ) + usedDirectories.add(directoryName) + # store + contents[layerName] = directoryName + # missing default layer + foundDefault = "glyphs" in contents.values() + if not foundDefault: + return False, "The required default glyph set is not in the UFO." + return True, None + + +# ------------ +# groups.plist +# ------------ + + +def groupsValidator(value: Any) -> tuple[bool, Optional[str]]: + """ + Check the validity of the groups. + Version 3+ (though it's backwards compatible with UFO 1 and UFO 2). + + >>> groups = {"A" : ["A", "A"], "A2" : ["A"]} + >>> groupsValidator(groups) + (True, None) + + >>> groups = {"" : ["A"]} + >>> valid, msg = groupsValidator(groups) + >>> valid + False + >>> print(msg) + A group has an empty name. + + >>> groups = {"public.awesome" : ["A"]} + >>> groupsValidator(groups) + (True, None) + + >>> groups = {"public.kern1." : ["A"]} + >>> valid, msg = groupsValidator(groups) + >>> valid + False + >>> print(msg) + The group data contains a kerning group with an incomplete name. + >>> groups = {"public.kern2." : ["A"]} + >>> valid, msg = groupsValidator(groups) + >>> valid + False + >>> print(msg) + The group data contains a kerning group with an incomplete name. + + >>> groups = {"public.kern1.A" : ["A"], "public.kern2.A" : ["A"]} + >>> groupsValidator(groups) + (True, None) + + >>> groups = {"public.kern1.A1" : ["A"], "public.kern1.A2" : ["A"]} + >>> valid, msg = groupsValidator(groups) + >>> valid + False + >>> print(msg) + The glyph "A" occurs in too many kerning groups. + """ + bogusFormatMessage = "The group data is not in the correct format." + if not isDictEnough(value): + return False, bogusFormatMessage + firstSideMapping: dict[str, str] = {} + secondSideMapping: dict[str, str] = {} + for groupName, glyphList in value.items(): + if not isinstance(groupName, (str)): + return False, bogusFormatMessage + if not isinstance(glyphList, (list, tuple)): + return False, bogusFormatMessage + if not groupName: + return False, "A group has an empty name." + if groupName.startswith("public."): + if not groupName.startswith("public.kern1.") and not groupName.startswith( + "public.kern2." + ): + # unknown public.* name. silently skip. + continue + else: + if len("public.kernN.") == len(groupName): + return ( + False, + "The group data contains a kerning group with an incomplete name.", + ) + if groupName.startswith("public.kern1."): + d = firstSideMapping + else: + d = secondSideMapping + for glyphName in glyphList: + if not isinstance(glyphName, str): + return ( + False, + "The group data %s contains an invalid member." % groupName, + ) + if glyphName in d: + return ( + False, + 'The glyph "%s" occurs in too many kerning groups.' % glyphName, + ) + d[glyphName] = groupName + return True, None + + +# ------------- +# kerning.plist +# ------------- + + +def kerningValidator(data: Any) -> tuple[bool, Optional[str]]: + """ + Check the validity of the kerning data structure. + Version 3+ (though it's backwards compatible with UFO 1 and UFO 2). + + >>> kerning = {"A" : {"B" : 100}} + >>> kerningValidator(kerning) + (True, None) + + >>> kerning = {"A" : ["B"]} + >>> valid, msg = kerningValidator(kerning) + >>> valid + False + >>> print(msg) + The kerning data is not in the correct format. + + >>> kerning = {"A" : {"B" : "100"}} + >>> valid, msg = kerningValidator(kerning) + >>> valid + False + >>> print(msg) + The kerning data is not in the correct format. + """ + bogusFormatMessage = "The kerning data is not in the correct format." + if not isinstance(data, Mapping): + return False, bogusFormatMessage + for first, secondDict in data.items(): + if not isinstance(first, str): + return False, bogusFormatMessage + elif not isinstance(secondDict, Mapping): + return False, bogusFormatMessage + for second, value in secondDict.items(): + if not isinstance(second, str): + return False, bogusFormatMessage + elif not isinstance(value, numberTypes): + return False, bogusFormatMessage + return True, None + + +# ------------- +# lib.plist/lib +# ------------- + +_bogusLibFormatMessage = "The lib data is not in the correct format: %s" + + +def fontLibValidator(value: Any) -> tuple[bool, Optional[str]]: + """ + Check the validity of the lib. + Version 3+ (though it's backwards compatible with UFO 1 and UFO 2). + + >>> lib = {"foo" : "bar"} + >>> fontLibValidator(lib) + (True, None) + + >>> lib = {"public.awesome" : "hello"} + >>> fontLibValidator(lib) + (True, None) + + >>> lib = {"public.glyphOrder" : ["A", "C", "B"]} + >>> fontLibValidator(lib) + (True, None) + + >>> lib = "hello" + >>> valid, msg = fontLibValidator(lib) + >>> valid + False + >>> print(msg) # doctest: +ELLIPSIS + The lib data is not in the correct format: expected a dictionary, ... + + >>> lib = {1: "hello"} + >>> valid, msg = fontLibValidator(lib) + >>> valid + False + >>> print(msg) + The lib key is not properly formatted: expected str, found int: 1 + + >>> lib = {"public.glyphOrder" : "hello"} + >>> valid, msg = fontLibValidator(lib) + >>> valid + False + >>> print(msg) # doctest: +ELLIPSIS + public.glyphOrder is not properly formatted: expected list or tuple,... + + >>> lib = {"public.glyphOrder" : ["A", 1, "B"]} + >>> valid, msg = fontLibValidator(lib) + >>> valid + False + >>> print(msg) # doctest: +ELLIPSIS + public.glyphOrder is not properly formatted: expected str,... + """ + if not isDictEnough(value): + reason = "expected a dictionary, found %s" % type(value).__name__ + return False, _bogusLibFormatMessage % reason + for key, value in value.items(): + if not isinstance(key, str): + return False, ( + "The lib key is not properly formatted: expected str, found %s: %r" + % (type(key).__name__, key) + ) + # public.glyphOrder + if key == "public.glyphOrder": + bogusGlyphOrderMessage = "public.glyphOrder is not properly formatted: %s" + if not isinstance(value, (list, tuple)): + reason = "expected list or tuple, found %s" % type(value).__name__ + return False, bogusGlyphOrderMessage % reason + for glyphName in value: + if not isinstance(glyphName, str): + reason = "expected str, found %s" % type(glyphName).__name__ + return False, bogusGlyphOrderMessage % reason + return True, None + + +# -------- +# GLIF lib +# -------- + + +def glyphLibValidator(value: Any) -> tuple[bool, Optional[str]]: + """ + Check the validity of the lib. + Version 3+ (though it's backwards compatible with UFO 1 and UFO 2). + + >>> lib = {"foo" : "bar"} + >>> glyphLibValidator(lib) + (True, None) + + >>> lib = {"public.awesome" : "hello"} + >>> glyphLibValidator(lib) + (True, None) + + >>> lib = {"public.markColor" : "1,0,0,0.5"} + >>> glyphLibValidator(lib) + (True, None) + + >>> lib = {"public.markColor" : 1} + >>> valid, msg = glyphLibValidator(lib) + >>> valid + False + >>> print(msg) + public.markColor is not properly formatted. + """ + if not isDictEnough(value): + reason = "expected a dictionary, found %s" % type(value).__name__ + return False, _bogusLibFormatMessage % reason + for key, value in value.items(): + if not isinstance(key, str): + reason = "key (%s) should be a string" % key + return False, _bogusLibFormatMessage % reason + # public.markColor + if key == "public.markColor": + if not colorValidator(value): + return False, "public.markColor is not properly formatted." + return True, None + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/__init__.py b/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/__main__.py b/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..1bb27dbfd53902914177ee7fb24a21402b9ae3d3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/__main__.py @@ -0,0 +1,72 @@ +import logging + +log = logging.getLogger("fontTools.varLib.avar") + + +def main(args=None): + from fontTools.ttLib import TTFont + from fontTools.misc.cliTools import makeOutputFileName + from fontTools import configLogger + import argparse + import sys + + print( + "WARNING: This script is deprecated. Use `fonttools varLib.avar.build` " + "or `fonttools varLib.avar.unbuild` instead.\n", + file=sys.stderr, + ) + + if args is None: + args = sys.argv[1:] + + parser = argparse.ArgumentParser( + "fonttools varLib.avar", + description="Add `avar` table from designspace file to variable font.", + ) + parser.add_argument("font", metavar="varfont.ttf", help="Variable-font file.") + parser.add_argument( + "designspace", + metavar="family.designspace", + help="Designspace file.", + nargs="?", + default=None, + ) + parser.add_argument( + "-o", + "--output-file", + type=str, + help="Output font file name.", + ) + parser.add_argument( + "-v", "--verbose", action="store_true", help="Run more verbosely." + ) + + options = parser.parse_args(args) + + configLogger(level=("INFO" if options.verbose else "WARNING")) + + font = TTFont(options.font) + + if options.designspace is None: + from .unbuild import unbuild + + unbuild(font) + return 0 + + from .build import build + + build(font, options.designspace) + + if options.output_file is None: + outfile = makeOutputFileName(options.font, overWrite=True, suffix=".avar") + else: + outfile = options.output_file + if outfile: + log.info("Saving %s", outfile) + font.save(outfile) + + +if __name__ == "__main__": + import sys + + sys.exit(main()) diff --git a/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/build.py b/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/build.py new file mode 100644 index 0000000000000000000000000000000000000000..e70925cbd746f3913c8048a5098ffd95a0a6e93b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/build.py @@ -0,0 +1,79 @@ +from fontTools.varLib import _add_fvar, _add_avar, load_designspace +from fontTools.ttLib import newTable +import logging + +log = logging.getLogger("fontTools.varLib.avar") + + +def build(font, designspace_file): + ds = load_designspace(designspace_file, require_sources=False) + + if not "fvar" in font: + # if "name" not in font: + font["name"] = newTable("name") + _add_fvar(font, ds.axes, ds.instances) + + axisTags = [a.axisTag for a in font["fvar"].axes] + + if "avar" in font: + log.warning("avar table already present, overwriting.") + del font["avar"] + + _add_avar(font, ds.axes, ds.axisMappings, axisTags) + + +def main(args=None): + """Add `avar` table from designspace file to variable font.""" + + from fontTools.ttLib import TTFont + from fontTools.misc.cliTools import makeOutputFileName + from fontTools import configLogger + import argparse + + if args is None: + import sys + + args = sys.argv[1:] + + parser = argparse.ArgumentParser( + "fonttools varLib.avar.build", + description="Add `avar` table from designspace file to variable font.", + ) + parser.add_argument("font", metavar="varfont.ttf", help="Variable-font file.") + parser.add_argument( + "designspace", + metavar="family.designspace", + help="Designspace file.", + default=None, + ) + parser.add_argument( + "-o", + "--output-file", + type=str, + help="Output font file name.", + ) + parser.add_argument( + "-v", "--verbose", action="store_true", help="Run more verbosely." + ) + + options = parser.parse_args(args) + + configLogger(level=("INFO" if options.verbose else "WARNING")) + + font = TTFont(options.font) + + build(font, options.designspace) + + if options.output_file is None: + outfile = makeOutputFileName(options.font, overWrite=True, suffix=".avar") + else: + outfile = options.output_file + if outfile: + log.info("Saving %s", outfile) + font.save(outfile) + + +if __name__ == "__main__": + import sys + + sys.exit(main()) diff --git a/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/map.py b/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/map.py new file mode 100644 index 0000000000000000000000000000000000000000..68eed6c83eba0b8def0e30bcbde3918fc1d7a789 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/map.py @@ -0,0 +1,108 @@ +from fontTools.varLib.models import normalizeValue + + +def _denormalize(v, triplet): + if v >= 0: + return triplet[1] + v * (triplet[2] - triplet[1]) + else: + return triplet[1] + v * (triplet[1] - triplet[0]) + + +def map( + font, location, *, inputNormalized=False, outputNormalized=False, dropZeroes=False +): + if "fvar" not in font: + return None + + fvar = font["fvar"] + axes = {a.axisTag: (a.minValue, a.defaultValue, a.maxValue) for a in fvar.axes} + + if not inputNormalized: + location = { + tag: normalizeValue(value, axes[tag]) for tag, value in location.items() + } + + if "avar" in font: + location = font["avar"].renormalizeLocation(location, font, dropZeroes) + + if not outputNormalized: + location = { + tag: _denormalize(value, axes[tag]) for tag, value in location.items() + } + + return location + + +def main(args=None): + """Map variation coordinates through the `avar` table.""" + + from fontTools.ttLib import TTFont + import argparse + + if args is None: + import sys + + args = sys.argv[1:] + + parser = argparse.ArgumentParser( + "fonttools varLib.avar.map", + description="Map variation coordinates through the `avar` table.", + ) + parser.add_argument("font", metavar="varfont.ttf", help="Variable-font file.") + parser.add_argument( + "coords", + metavar="[AXIS=value...]", + help="Coordinates to map, e.g. 'wght=700 wdth=75'.", + nargs="*", + default=None, + ) + parser.add_argument( + "-f", action="store_true", help="Do not omit axes at default location." + ) + parser.add_argument( + "-i", action="store_true", help="Input coordinates are normalized (-1..1)." + ) + parser.add_argument( + "-o", action="store_true", help="Output coordinates as normalized (-1..1)." + ) + + options = parser.parse_args(args) + + if not options.coords: + parser.error( + "No coordinates provided. Please specify at least one axis coordinate (e.g., wght=500)" + ) + + if options.font.endswith(".designspace"): + from .build import build + + font = TTFont() + build(font, options.font) + else: + font = TTFont(options.font) + if "fvar" not in font: + parser.error(f"Font '{options.font}' does not contain an 'fvar' table.") + + location = { + tag: float(value) for tag, value in (item.split("=") for item in options.coords) + } + + mapped = map( + font, + location, + inputNormalized=options.i, + outputNormalized=options.o, + dropZeroes=not options.f, + ) + assert mapped is not None + + for tag in mapped: + v = mapped[tag] + v = int(v) if v == int(v) else v + print(f"{tag}={v:g}") + + +if __name__ == "__main__": + import sys + + sys.exit(main()) diff --git a/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/plan.py b/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/plan.py new file mode 100644 index 0000000000000000000000000000000000000000..c211dd24626560f2a60386391098e427b616aa6f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/plan.py @@ -0,0 +1,1004 @@ +from fontTools.ttLib import newTable +from fontTools.ttLib.tables._f_v_a_r import Axis as fvarAxis +from fontTools.pens.areaPen import AreaPen +from fontTools.pens.basePen import NullPen +from fontTools.pens.statisticsPen import StatisticsPen +from fontTools.varLib.models import piecewiseLinearMap, normalizeValue +from fontTools.misc.cliTools import makeOutputFileName +import math +import logging +from pprint import pformat + +__all__ = [ + "planWeightAxis", + "planWidthAxis", + "planSlantAxis", + "planOpticalSizeAxis", + "planAxis", + "sanitizeWeight", + "sanitizeWidth", + "sanitizeSlant", + "measureWeight", + "measureWidth", + "measureSlant", + "normalizeLinear", + "normalizeLog", + "normalizeDegrees", + "interpolateLinear", + "interpolateLog", + "processAxis", + "makeDesignspaceSnippet", + "addEmptyAvar", + "main", +] + +log = logging.getLogger("fontTools.varLib.avar.plan") + +WEIGHTS = [ + 50, + 100, + 150, + 200, + 250, + 300, + 350, + 400, + 450, + 500, + 550, + 600, + 650, + 700, + 750, + 800, + 850, + 900, + 950, +] + +WIDTHS = [ + 25.0, + 37.5, + 50.0, + 62.5, + 75.0, + 87.5, + 100.0, + 112.5, + 125.0, + 137.5, + 150.0, + 162.5, + 175.0, + 187.5, + 200.0, +] + +SLANTS = list(math.degrees(math.atan(d / 20.0)) for d in range(-20, 21)) + +SIZES = [ + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 14, + 18, + 24, + 30, + 36, + 48, + 60, + 72, + 96, + 120, + 144, + 192, + 240, + 288, +] + + +SAMPLES = 8 + + +def normalizeLinear(value, rangeMin, rangeMax): + """Linearly normalize value in [rangeMin, rangeMax] to [0, 1], with extrapolation.""" + return (value - rangeMin) / (rangeMax - rangeMin) + + +def interpolateLinear(t, a, b): + """Linear interpolation between a and b, with t typically in [0, 1].""" + return a + t * (b - a) + + +def normalizeLog(value, rangeMin, rangeMax): + """Logarithmically normalize value in [rangeMin, rangeMax] to [0, 1], with extrapolation.""" + logMin = math.log(rangeMin) + logMax = math.log(rangeMax) + return (math.log(value) - logMin) / (logMax - logMin) + + +def interpolateLog(t, a, b): + """Logarithmic interpolation between a and b, with t typically in [0, 1].""" + logA = math.log(a) + logB = math.log(b) + return math.exp(logA + t * (logB - logA)) + + +def normalizeDegrees(value, rangeMin, rangeMax): + """Angularly normalize value in [rangeMin, rangeMax] to [0, 1], with extrapolation.""" + tanMin = math.tan(math.radians(rangeMin)) + tanMax = math.tan(math.radians(rangeMax)) + return (math.tan(math.radians(value)) - tanMin) / (tanMax - tanMin) + + +def measureWeight(glyphset, glyphs=None): + """Measure the perceptual average weight of the given glyphs.""" + if isinstance(glyphs, dict): + frequencies = glyphs + else: + frequencies = {g: 1 for g in glyphs} + + wght_sum = wdth_sum = 0 + for glyph_name in glyphs: + if frequencies is not None: + frequency = frequencies.get(glyph_name, 0) + if frequency == 0: + continue + else: + frequency = 1 + + glyph = glyphset[glyph_name] + + pen = AreaPen(glyphset=glyphset) + glyph.draw(pen) + + mult = glyph.width * frequency + wght_sum += mult * abs(pen.value) + wdth_sum += mult + + return wght_sum / wdth_sum + + +def measureWidth(glyphset, glyphs=None): + """Measure the average width of the given glyphs.""" + if isinstance(glyphs, dict): + frequencies = glyphs + else: + frequencies = {g: 1 for g in glyphs} + + wdth_sum = 0 + freq_sum = 0 + for glyph_name in glyphs: + if frequencies is not None: + frequency = frequencies.get(glyph_name, 0) + if frequency == 0: + continue + else: + frequency = 1 + + glyph = glyphset[glyph_name] + + pen = NullPen() + glyph.draw(pen) + + wdth_sum += glyph.width * frequency + freq_sum += frequency + + return wdth_sum / freq_sum + + +def measureSlant(glyphset, glyphs=None): + """Measure the perceptual average slant angle of the given glyphs.""" + if isinstance(glyphs, dict): + frequencies = glyphs + else: + frequencies = {g: 1 for g in glyphs} + + slnt_sum = 0 + freq_sum = 0 + for glyph_name in glyphs: + if frequencies is not None: + frequency = frequencies.get(glyph_name, 0) + if frequency == 0: + continue + else: + frequency = 1 + + glyph = glyphset[glyph_name] + + pen = StatisticsPen(glyphset=glyphset) + glyph.draw(pen) + + mult = glyph.width * frequency + slnt_sum += mult * pen.slant + freq_sum += mult + + return -math.degrees(math.atan(slnt_sum / freq_sum)) + + +def sanitizeWidth(userTriple, designTriple, pins, measurements): + """Sanitize the width axis limits.""" + + minVal, defaultVal, maxVal = ( + measurements[designTriple[0]], + measurements[designTriple[1]], + measurements[designTriple[2]], + ) + + calculatedMinVal = userTriple[1] * (minVal / defaultVal) + calculatedMaxVal = userTriple[1] * (maxVal / defaultVal) + + log.info("Original width axis limits: %g:%g:%g", *userTriple) + log.info( + "Calculated width axis limits: %g:%g:%g", + calculatedMinVal, + userTriple[1], + calculatedMaxVal, + ) + + if ( + abs(calculatedMinVal - userTriple[0]) / userTriple[1] > 0.05 + or abs(calculatedMaxVal - userTriple[2]) / userTriple[1] > 0.05 + ): + log.warning("Calculated width axis min/max do not match user input.") + log.warning( + " Current width axis limits: %g:%g:%g", + *userTriple, + ) + log.warning( + " Suggested width axis limits: %g:%g:%g", + calculatedMinVal, + userTriple[1], + calculatedMaxVal, + ) + + return False + + return True + + +def sanitizeWeight(userTriple, designTriple, pins, measurements): + """Sanitize the weight axis limits.""" + + if len(set(userTriple)) < 3: + return True + + minVal, defaultVal, maxVal = ( + measurements[designTriple[0]], + measurements[designTriple[1]], + measurements[designTriple[2]], + ) + + logMin = math.log(minVal) + logDefault = math.log(defaultVal) + logMax = math.log(maxVal) + + t = (userTriple[1] - userTriple[0]) / (userTriple[2] - userTriple[0]) + y = math.exp(logMin + t * (logMax - logMin)) + t = (y - minVal) / (maxVal - minVal) + calculatedDefaultVal = userTriple[0] + t * (userTriple[2] - userTriple[0]) + + log.info("Original weight axis limits: %g:%g:%g", *userTriple) + log.info( + "Calculated weight axis limits: %g:%g:%g", + userTriple[0], + calculatedDefaultVal, + userTriple[2], + ) + + if abs(calculatedDefaultVal - userTriple[1]) / userTriple[1] > 0.05: + log.warning("Calculated weight axis default does not match user input.") + + log.warning( + " Current weight axis limits: %g:%g:%g", + *userTriple, + ) + + log.warning( + " Suggested weight axis limits, changing default: %g:%g:%g", + userTriple[0], + calculatedDefaultVal, + userTriple[2], + ) + + t = (userTriple[2] - userTriple[0]) / (userTriple[1] - userTriple[0]) + y = math.exp(logMin + t * (logDefault - logMin)) + t = (y - minVal) / (defaultVal - minVal) + calculatedMaxVal = userTriple[0] + t * (userTriple[1] - userTriple[0]) + log.warning( + " Suggested weight axis limits, changing maximum: %g:%g:%g", + userTriple[0], + userTriple[1], + calculatedMaxVal, + ) + + t = (userTriple[0] - userTriple[2]) / (userTriple[1] - userTriple[2]) + y = math.exp(logMax + t * (logDefault - logMax)) + t = (y - maxVal) / (defaultVal - maxVal) + calculatedMinVal = userTriple[2] + t * (userTriple[1] - userTriple[2]) + log.warning( + " Suggested weight axis limits, changing minimum: %g:%g:%g", + calculatedMinVal, + userTriple[1], + userTriple[2], + ) + + return False + + return True + + +def sanitizeSlant(userTriple, designTriple, pins, measurements): + """Sanitize the slant axis limits.""" + + log.info("Original slant axis limits: %g:%g:%g", *userTriple) + log.info( + "Calculated slant axis limits: %g:%g:%g", + measurements[designTriple[0]], + measurements[designTriple[1]], + measurements[designTriple[2]], + ) + + if ( + abs(measurements[designTriple[0]] - userTriple[0]) > 1 + or abs(measurements[designTriple[1]] - userTriple[1]) > 1 + or abs(measurements[designTriple[2]] - userTriple[2]) > 1 + ): + log.warning("Calculated slant axis min/default/max do not match user input.") + log.warning( + " Current slant axis limits: %g:%g:%g", + *userTriple, + ) + log.warning( + " Suggested slant axis limits: %g:%g:%g", + measurements[designTriple[0]], + measurements[designTriple[1]], + measurements[designTriple[2]], + ) + + return False + + return True + + +def planAxis( + measureFunc, + normalizeFunc, + interpolateFunc, + glyphSetFunc, + axisTag, + axisLimits, + values, + samples=None, + glyphs=None, + designLimits=None, + pins=None, + sanitizeFunc=None, +): + """Plan an axis. + + measureFunc: callable that takes a glyphset and an optional + list of glyphnames, and returns the glyphset-wide measurement + to be used for the axis. + + normalizeFunc: callable that takes a measurement and a minimum + and maximum, and normalizes the measurement into the range 0..1, + possibly extrapolating too. + + interpolateFunc: callable that takes a normalized t value, and a + minimum and maximum, and returns the interpolated value, + possibly extrapolating too. + + glyphSetFunc: callable that takes a variations "location" dictionary, + and returns a glyphset. + + axisTag: the axis tag string. + + axisLimits: a triple of minimum, default, and maximum values for + the axis. Or an `fvar` Axis object. + + values: a list of output values to map for this axis. + + samples: the number of samples to use when sampling. Default 8. + + glyphs: a list of glyph names to use when sampling. Defaults to None, + which will process all glyphs. + + designLimits: an optional triple of minimum, default, and maximum values + represenging the "design" limits for the axis. If not provided, the + axisLimits will be used. + + pins: an optional dictionary of before/after mapping entries to pin in + the output. + + sanitizeFunc: an optional callable to call to sanitize the axis limits. + """ + + if isinstance(axisLimits, fvarAxis): + axisLimits = (axisLimits.minValue, axisLimits.defaultValue, axisLimits.maxValue) + minValue, defaultValue, maxValue = axisLimits + + if samples is None: + samples = SAMPLES + if glyphs is None: + glyphs = glyphSetFunc({}).keys() + if pins is None: + pins = {} + else: + pins = pins.copy() + + log.info( + "Axis limits min %g / default %g / max %g", minValue, defaultValue, maxValue + ) + triple = (minValue, defaultValue, maxValue) + + if designLimits is not None: + log.info("Axis design-limits min %g / default %g / max %g", *designLimits) + else: + designLimits = triple + + if pins: + log.info("Pins %s", sorted(pins.items())) + pins.update( + { + minValue: designLimits[0], + defaultValue: designLimits[1], + maxValue: designLimits[2], + } + ) + + out = {} + outNormalized = {} + + axisMeasurements = {} + for value in sorted({minValue, defaultValue, maxValue} | set(pins.keys())): + glyphset = glyphSetFunc(location={axisTag: value}) + designValue = pins[value] + axisMeasurements[designValue] = measureFunc(glyphset, glyphs) + + if sanitizeFunc is not None: + log.info("Sanitizing axis limit values for the `%s` axis.", axisTag) + sanitizeFunc(triple, designLimits, pins, axisMeasurements) + + log.debug("Calculated average value:\n%s", pformat(axisMeasurements)) + + for (rangeMin, targetMin), (rangeMax, targetMax) in zip( + list(sorted(pins.items()))[:-1], + list(sorted(pins.items()))[1:], + ): + targetValues = {w for w in values if rangeMin < w < rangeMax} + if not targetValues: + continue + + normalizedMin = normalizeValue(rangeMin, triple) + normalizedMax = normalizeValue(rangeMax, triple) + normalizedTargetMin = normalizeValue(targetMin, designLimits) + normalizedTargetMax = normalizeValue(targetMax, designLimits) + + log.info("Planning target values %s.", sorted(targetValues)) + log.info("Sampling %u points in range %g,%g.", samples, rangeMin, rangeMax) + valueMeasurements = axisMeasurements.copy() + for sample in range(1, samples + 1): + value = rangeMin + (rangeMax - rangeMin) * sample / (samples + 1) + log.debug("Sampling value %g.", value) + glyphset = glyphSetFunc(location={axisTag: value}) + designValue = piecewiseLinearMap(value, pins) + valueMeasurements[designValue] = measureFunc(glyphset, glyphs) + log.debug("Sampled average value:\n%s", pformat(valueMeasurements)) + + measurementValue = {} + for value in sorted(valueMeasurements): + measurementValue[valueMeasurements[value]] = value + + out[rangeMin] = targetMin + outNormalized[normalizedMin] = normalizedTargetMin + for value in sorted(targetValues): + t = normalizeFunc(value, rangeMin, rangeMax) + targetMeasurement = interpolateFunc( + t, valueMeasurements[targetMin], valueMeasurements[targetMax] + ) + targetValue = piecewiseLinearMap(targetMeasurement, measurementValue) + log.debug("Planned mapping value %g to %g." % (value, targetValue)) + out[value] = targetValue + valueNormalized = normalizedMin + (value - rangeMin) / ( + rangeMax - rangeMin + ) * (normalizedMax - normalizedMin) + outNormalized[valueNormalized] = normalizedTargetMin + ( + targetValue - targetMin + ) / (targetMax - targetMin) * (normalizedTargetMax - normalizedTargetMin) + out[rangeMax] = targetMax + outNormalized[normalizedMax] = normalizedTargetMax + + log.info("Planned mapping for the `%s` axis:\n%s", axisTag, pformat(out)) + log.info( + "Planned normalized mapping for the `%s` axis:\n%s", + axisTag, + pformat(outNormalized), + ) + + if all(abs(k - v) < 0.01 for k, v in outNormalized.items()): + log.info("Detected identity mapping for the `%s` axis. Dropping.", axisTag) + out = {} + outNormalized = {} + + return out, outNormalized + + +def planWeightAxis( + glyphSetFunc, + axisLimits, + weights=None, + samples=None, + glyphs=None, + designLimits=None, + pins=None, + sanitize=False, +): + """Plan a weight (`wght`) axis. + + weights: A list of weight values to plan for. If None, the default + values are used. + + This function simply calls planAxis with values=weights, and the appropriate + arguments. See documenation for planAxis for more information. + """ + + if weights is None: + weights = WEIGHTS + + return planAxis( + measureWeight, + normalizeLinear, + interpolateLog, + glyphSetFunc, + "wght", + axisLimits, + values=weights, + samples=samples, + glyphs=glyphs, + designLimits=designLimits, + pins=pins, + sanitizeFunc=sanitizeWeight if sanitize else None, + ) + + +def planWidthAxis( + glyphSetFunc, + axisLimits, + widths=None, + samples=None, + glyphs=None, + designLimits=None, + pins=None, + sanitize=False, +): + """Plan a width (`wdth`) axis. + + widths: A list of width values (percentages) to plan for. If None, the default + values are used. + + This function simply calls planAxis with values=widths, and the appropriate + arguments. See documenation for planAxis for more information. + """ + + if widths is None: + widths = WIDTHS + + return planAxis( + measureWidth, + normalizeLinear, + interpolateLinear, + glyphSetFunc, + "wdth", + axisLimits, + values=widths, + samples=samples, + glyphs=glyphs, + designLimits=designLimits, + pins=pins, + sanitizeFunc=sanitizeWidth if sanitize else None, + ) + + +def planSlantAxis( + glyphSetFunc, + axisLimits, + slants=None, + samples=None, + glyphs=None, + designLimits=None, + pins=None, + sanitize=False, +): + """Plan a slant (`slnt`) axis. + + slants: A list slant angles to plan for. If None, the default + values are used. + + This function simply calls planAxis with values=slants, and the appropriate + arguments. See documenation for planAxis for more information. + """ + + if slants is None: + slants = SLANTS + + return planAxis( + measureSlant, + normalizeDegrees, + interpolateLinear, + glyphSetFunc, + "slnt", + axisLimits, + values=slants, + samples=samples, + glyphs=glyphs, + designLimits=designLimits, + pins=pins, + sanitizeFunc=sanitizeSlant if sanitize else None, + ) + + +def planOpticalSizeAxis( + glyphSetFunc, + axisLimits, + sizes=None, + samples=None, + glyphs=None, + designLimits=None, + pins=None, + sanitize=False, +): + """Plan a optical-size (`opsz`) axis. + + sizes: A list of optical size values to plan for. If None, the default + values are used. + + This function simply calls planAxis with values=sizes, and the appropriate + arguments. See documenation for planAxis for more information. + """ + + if sizes is None: + sizes = SIZES + + return planAxis( + measureWeight, + normalizeLog, + interpolateLog, + glyphSetFunc, + "opsz", + axisLimits, + values=sizes, + samples=samples, + glyphs=glyphs, + designLimits=designLimits, + pins=pins, + ) + + +def makeDesignspaceSnippet(axisTag, axisName, axisLimit, mapping): + """Make a designspace snippet for a single axis.""" + + designspaceSnippet = ( + ' <axis tag="%s" name="%s" minimum="%g" default="%g" maximum="%g"' + % ((axisTag, axisName) + axisLimit) + ) + if mapping: + designspaceSnippet += ">\n" + else: + designspaceSnippet += "/>" + + for key, value in mapping.items(): + designspaceSnippet += ' <map input="%g" output="%g"/>\n' % (key, value) + + if mapping: + designspaceSnippet += " </axis>" + + return designspaceSnippet + + +def addEmptyAvar(font): + """Add an empty `avar` table to the font.""" + font["avar"] = avar = newTable("avar") + for axis in font["fvar"].axes: + avar.segments[axis.axisTag] = {} + + +def processAxis( + font, + planFunc, + axisTag, + axisName, + values, + samples=None, + glyphs=None, + designLimits=None, + pins=None, + sanitize=False, + plot=False, +): + """Process a single axis.""" + + axisLimits = None + for axis in font["fvar"].axes: + if axis.axisTag == axisTag: + axisLimits = axis + break + if axisLimits is None: + return "" + axisLimits = (axisLimits.minValue, axisLimits.defaultValue, axisLimits.maxValue) + + log.info("Planning %s axis.", axisName) + + if "avar" in font: + existingMapping = font["avar"].segments[axisTag] + font["avar"].segments[axisTag] = {} + else: + existingMapping = None + + if values is not None and isinstance(values, str): + values = [float(w) for w in values.split()] + + if designLimits is not None and isinstance(designLimits, str): + designLimits = [float(d) for d in designLimits.split(":")] + assert ( + len(designLimits) == 3 + and designLimits[0] <= designLimits[1] <= designLimits[2] + ) + else: + designLimits = None + + if pins is not None and isinstance(pins, str): + newPins = {} + for pin in pins.split(): + before, after = pin.split(":") + newPins[float(before)] = float(after) + pins = newPins + del newPins + + mapping, mappingNormalized = planFunc( + font.getGlyphSet, + axisLimits, + values, + samples=samples, + glyphs=glyphs, + designLimits=designLimits, + pins=pins, + sanitize=sanitize, + ) + + if plot: + from matplotlib import pyplot + + pyplot.plot( + sorted(mappingNormalized), + [mappingNormalized[k] for k in sorted(mappingNormalized)], + ) + pyplot.show() + + if existingMapping is not None: + log.info("Existing %s mapping:\n%s", axisName, pformat(existingMapping)) + + if mapping: + if "avar" not in font: + addEmptyAvar(font) + font["avar"].segments[axisTag] = mappingNormalized + else: + if "avar" in font: + font["avar"].segments[axisTag] = {} + + designspaceSnippet = makeDesignspaceSnippet( + axisTag, + axisName, + axisLimits, + mapping, + ) + return designspaceSnippet + + +def main(args=None): + """Plan the standard axis mappings for a variable font""" + + if args is None: + import sys + + args = sys.argv[1:] + + from fontTools import configLogger + from fontTools.ttLib import TTFont + import argparse + + parser = argparse.ArgumentParser( + "fonttools varLib.avar.plan", + description="Plan `avar` table for variable font", + ) + parser.add_argument("font", metavar="varfont.ttf", help="Variable-font file.") + parser.add_argument( + "-o", + "--output-file", + type=str, + help="Output font file name.", + ) + parser.add_argument( + "--weights", type=str, help="Space-separate list of weights to generate." + ) + parser.add_argument( + "--widths", type=str, help="Space-separate list of widths to generate." + ) + parser.add_argument( + "--slants", type=str, help="Space-separate list of slants to generate." + ) + parser.add_argument( + "--sizes", type=str, help="Space-separate list of optical-sizes to generate." + ) + parser.add_argument("--samples", type=int, help="Number of samples.") + parser.add_argument( + "-s", "--sanitize", action="store_true", help="Sanitize axis limits" + ) + parser.add_argument( + "-g", + "--glyphs", + type=str, + help="Space-separate list of glyphs to use for sampling.", + ) + parser.add_argument( + "--weight-design-limits", + type=str, + help="min:default:max in design units for the `wght` axis.", + ) + parser.add_argument( + "--width-design-limits", + type=str, + help="min:default:max in design units for the `wdth` axis.", + ) + parser.add_argument( + "--slant-design-limits", + type=str, + help="min:default:max in design units for the `slnt` axis.", + ) + parser.add_argument( + "--optical-size-design-limits", + type=str, + help="min:default:max in design units for the `opsz` axis.", + ) + parser.add_argument( + "--weight-pins", + type=str, + help="Space-separate list of before:after pins for the `wght` axis.", + ) + parser.add_argument( + "--width-pins", + type=str, + help="Space-separate list of before:after pins for the `wdth` axis.", + ) + parser.add_argument( + "--slant-pins", + type=str, + help="Space-separate list of before:after pins for the `slnt` axis.", + ) + parser.add_argument( + "--optical-size-pins", + type=str, + help="Space-separate list of before:after pins for the `opsz` axis.", + ) + parser.add_argument( + "-p", "--plot", action="store_true", help="Plot the resulting mapping." + ) + + logging_group = parser.add_mutually_exclusive_group(required=False) + logging_group.add_argument( + "-v", "--verbose", action="store_true", help="Run more verbosely." + ) + logging_group.add_argument( + "-q", "--quiet", action="store_true", help="Turn verbosity off." + ) + + options = parser.parse_args(args) + + configLogger( + level=("DEBUG" if options.verbose else "WARNING" if options.quiet else "INFO") + ) + + font = TTFont(options.font) + if not "fvar" in font: + log.error("Not a variable font.") + return 1 + + if options.glyphs is not None: + glyphs = options.glyphs.split() + if ":" in options.glyphs: + glyphs = {} + for g in options.glyphs.split(): + if ":" in g: + glyph, frequency = g.split(":") + glyphs[glyph] = float(frequency) + else: + glyphs[g] = 1.0 + else: + glyphs = None + + designspaceSnippets = [] + + designspaceSnippets.append( + processAxis( + font, + planWeightAxis, + "wght", + "Weight", + values=options.weights, + samples=options.samples, + glyphs=glyphs, + designLimits=options.weight_design_limits, + pins=options.weight_pins, + sanitize=options.sanitize, + plot=options.plot, + ) + ) + designspaceSnippets.append( + processAxis( + font, + planWidthAxis, + "wdth", + "Width", + values=options.widths, + samples=options.samples, + glyphs=glyphs, + designLimits=options.width_design_limits, + pins=options.width_pins, + sanitize=options.sanitize, + plot=options.plot, + ) + ) + designspaceSnippets.append( + processAxis( + font, + planSlantAxis, + "slnt", + "Slant", + values=options.slants, + samples=options.samples, + glyphs=glyphs, + designLimits=options.slant_design_limits, + pins=options.slant_pins, + sanitize=options.sanitize, + plot=options.plot, + ) + ) + designspaceSnippets.append( + processAxis( + font, + planOpticalSizeAxis, + "opsz", + "OpticalSize", + values=options.sizes, + samples=options.samples, + glyphs=glyphs, + designLimits=options.optical_size_design_limits, + pins=options.optical_size_pins, + sanitize=options.sanitize, + plot=options.plot, + ) + ) + + log.info("Designspace snippet:") + for snippet in designspaceSnippets: + if snippet: + print(snippet) + + if options.output_file is None: + outfile = makeOutputFileName(options.font, overWrite=True, suffix=".avar") + else: + outfile = options.output_file + if outfile: + log.info("Saving %s", outfile) + font.save(outfile) + + +if __name__ == "__main__": + import sys + + sys.exit(main()) diff --git a/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/unbuild.py b/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/unbuild.py new file mode 100644 index 0000000000000000000000000000000000000000..d592bd731042c412be12bd465fc54a03293bfc65 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/varLib/avar/unbuild.py @@ -0,0 +1,271 @@ +from fontTools.varLib.models import VariationModel +from fontTools.varLib.varStore import VarStoreInstancer +from fontTools.misc.fixedTools import fixedToFloat as fi2fl +from itertools import product +import sys + + +def _denormalize(v, axis): + if v >= 0: + return axis.defaultValue + v * (axis.maxValue - axis.defaultValue) + else: + return axis.defaultValue + v * (axis.defaultValue - axis.minValue) + + +def _pruneLocations(locations, poles, axisTags): + # Now we have all the input locations, find which ones are + # not needed and remove them. + + # Note: This algorithm is heavily tied to how VariationModel + # is implemented. It assumes that input was extracted from + # VariationModel-generated object, like an ItemVariationStore + # created by fontmake using varLib.models.VariationModel. + # Some CoPilot blabbering: + # I *think* I can prove that this algorithm is correct, but + # I'm not 100% sure. It's possible that there are edge cases + # where this algorithm will fail. I'm not sure how to prove + # that it's correct, but I'm also not sure how to prove that + # it's incorrect. I'm not sure how to write a test case that + # would prove that it's incorrect. I'm not sure how to write + # a test case that would prove that it's correct. + + model = VariationModel(locations, axisTags) + modelMapping = model.mapping + modelSupports = model.supports + pins = {tuple(k.items()): None for k in poles} + for location in poles: + i = locations.index(location) + i = modelMapping[i] + support = modelSupports[i] + supportAxes = set(support.keys()) + for axisTag, (minV, _, maxV) in support.items(): + for v in (minV, maxV): + if v in (-1, 0, 1): + continue + for pin in pins.keys(): + pinLocation = dict(pin) + pinAxes = set(pinLocation.keys()) + if pinAxes != supportAxes: + continue + if axisTag not in pinAxes: + continue + if pinLocation[axisTag] == v: + break + else: + # No pin found. Go through the previous masters + # and find a suitable pin. Going backwards is + # better because it can find a pin that is close + # to the pole in more dimensions, and reducing + # the total number of pins needed. + for candidateIdx in range(i - 1, -1, -1): + candidate = modelSupports[candidateIdx] + candidateAxes = set(candidate.keys()) + if candidateAxes != supportAxes: + continue + if axisTag not in candidateAxes: + continue + candidate = { + k: defaultV for k, (_, defaultV, _) in candidate.items() + } + if candidate[axisTag] == v: + pins[tuple(candidate.items())] = None + break + else: + assert False, "No pin found" + return [dict(t) for t in pins.keys()] + + +def mappings_from_avar(font, denormalize=True): + fvarAxes = font["fvar"].axes + axisMap = {a.axisTag: a for a in fvarAxes} + axisTags = [a.axisTag for a in fvarAxes] + axisIndexes = {a.axisTag: i for i, a in enumerate(fvarAxes)} + if "avar" not in font: + return {}, {} + avar = font["avar"] + axisMaps = { + tag: seg + for tag, seg in avar.segments.items() + if seg and seg != {-1: -1, 0: 0, 1: 1} + } + mappings = [] + + if getattr(avar, "majorVersion", 1) == 2: + varStore = avar.table.VarStore + regions = varStore.VarRegionList.Region + + # Find all the input locations; this finds "poles", that are + # locations of the peaks, and "corners", that are locations + # of the corners of the regions. These two sets of locations + # together constitute inputLocations to consider. + + poles = {(): None} # Just using it as an ordered set + inputLocations = set({()}) + for varData in varStore.VarData: + regionIndices = varData.VarRegionIndex + for regionIndex in regionIndices: + peakLocation = [] + corners = [] + region = regions[regionIndex] + for axisIndex, axis in enumerate(region.VarRegionAxis): + if axis.PeakCoord == 0: + continue + axisTag = axisTags[axisIndex] + peakLocation.append((axisTag, axis.PeakCoord)) + corner = [] + if axis.StartCoord != 0: + corner.append((axisTag, axis.StartCoord)) + if axis.EndCoord != 0: + corner.append((axisTag, axis.EndCoord)) + corners.append(corner) + corners = set(product(*corners)) + peakLocation = tuple(peakLocation) + poles[peakLocation] = None + inputLocations.add(peakLocation) + inputLocations.update(corners) + + # Sort them by number of axes, then by axis order + inputLocations = [ + dict(t) + for t in sorted( + inputLocations, + key=lambda t: (len(t), tuple(axisIndexes[tag] for tag, _ in t)), + ) + ] + poles = [dict(t) for t in poles.keys()] + inputLocations = _pruneLocations(inputLocations, list(poles), axisTags) + + # Find the output locations, at input locations + varIdxMap = avar.table.VarIdxMap + instancer = VarStoreInstancer(varStore, fvarAxes) + for location in inputLocations: + instancer.setLocation(location) + outputLocation = {} + for axisIndex, axisTag in enumerate(axisTags): + varIdx = axisIndex + if varIdxMap is not None: + varIdx = varIdxMap[varIdx] + delta = instancer[varIdx] + if delta != 0: + v = location.get(axisTag, 0) + v = v + fi2fl(delta, 14) + # See https://github.com/fonttools/fonttools/pull/3598#issuecomment-2266082009 + # v = max(-1, min(1, v)) + outputLocation[axisTag] = v + mappings.append((location, outputLocation)) + + # Remove base master we added, if it maps to the default location + assert mappings[0][0] == {} + if mappings[0][1] == {}: + mappings.pop(0) + + if denormalize: + for tag, seg in axisMaps.items(): + if tag not in axisMap: + raise ValueError(f"Unknown axis tag {tag}") + denorm = lambda v: _denormalize(v, axisMap[tag]) + axisMaps[tag] = {denorm(k): denorm(v) for k, v in seg.items()} + + for i, (inputLoc, outputLoc) in enumerate(mappings): + inputLoc = { + tag: _denormalize(val, axisMap[tag]) for tag, val in inputLoc.items() + } + outputLoc = { + tag: _denormalize(val, axisMap[tag]) for tag, val in outputLoc.items() + } + mappings[i] = (inputLoc, outputLoc) + + return axisMaps, mappings + + +def unbuild(font, f=sys.stdout): + fvar = font["fvar"] + axes = fvar.axes + segments, mappings = mappings_from_avar(font) + + if "name" in font: + name = font["name"] + axisNames = {axis.axisTag: name.getDebugName(axis.axisNameID) for axis in axes} + else: + axisNames = {a.axisTag: a.axisTag for a in axes} + + print("<?xml version='1.0' encoding='UTF-8'?>", file=f) + print('<designspace format="5.1">', file=f) + print(" <axes>", file=f) + for axis in axes: + + axisName = axisNames[axis.axisTag] + + triplet = (axis.minValue, axis.defaultValue, axis.maxValue) + triplet = [int(v) if v == int(v) else v for v in triplet] + + axisMap = segments.get(axis.axisTag) + closing = "/>" if axisMap is None else ">" + + print( + f' <axis tag="{axis.axisTag}" name="{axisName}" minimum="{triplet[0]}" maximum="{triplet[2]}" default="{triplet[1]}"{closing}', + file=f, + ) + if axisMap is not None: + for k in sorted(axisMap.keys()): + v = axisMap[k] + k = int(k) if k == int(k) else k + v = int(v) if v == int(v) else v + print(f' <map input="{k}" output="{v}"/>', file=f) + print(" </axis>", file=f) + if mappings: + print(" <mappings>", file=f) + for inputLoc, outputLoc in mappings: + print(" <mapping>", file=f) + print(" <input>", file=f) + for tag in sorted(inputLoc.keys()): + v = inputLoc[tag] + v = int(v) if v == int(v) else v + print( + f' <dimension name="{axisNames[tag]}" xvalue="{v}"/>', + file=f, + ) + print(" </input>", file=f) + print(" <output>", file=f) + for tag in sorted(outputLoc.keys()): + v = outputLoc[tag] + v = int(v) if v == int(v) else v + print( + f' <dimension name="{axisNames[tag]}" xvalue="{v}"/>', + file=f, + ) + print(" </output>", file=f) + print(" </mapping>", file=f) + print(" </mappings>", file=f) + print(" </axes>", file=f) + print("</designspace>", file=f) + + +def main(args=None): + """Print `avar` table as a designspace snippet.""" + + if args is None: + args = sys.argv[1:] + + from fontTools.ttLib import TTFont + import argparse + + parser = argparse.ArgumentParser( + "fonttools varLib.avar.unbuild", + description="Print `avar` table as a designspace snippet.", + ) + parser.add_argument("font", metavar="varfont.ttf", help="Variable-font file.") + options = parser.parse_args(args) + + font = TTFont(options.font) + if "fvar" not in font: + print("Not a variable font.", file=sys.stderr) + return 1 + + unbuild(font) + + +if __name__ == "__main__": + import sys + + sys.exit(main()) diff --git a/.venv/lib/python3.13/site-packages/fontTools/varLib/instancer/__init__.py b/.venv/lib/python3.13/site-packages/fontTools/varLib/instancer/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2993bf38bfaff154264f34da2a3de88cc328fa46 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/varLib/instancer/__init__.py @@ -0,0 +1,2052 @@ +"""Partially instantiate a variable font. + +The module exports an `instantiateVariableFont` function and CLI that allow to +create full instances (i.e. static fonts) from variable fonts, as well as "partial" +variable fonts that only contain a subset of the original variation space. + +For example, if you wish to pin the width axis to a given location while also +restricting the weight axis to 400..700 range, you can do: + +.. code-block:: sh + + $ fonttools varLib.instancer ./NotoSans-VF.ttf wdth=85 wght=400:700 + +See `fonttools varLib.instancer --help` for more info on the CLI options. + +The module's entry point is the `instantiateVariableFont` function, which takes +a TTFont object and a dict specifying either axis coodinates or (min, max) ranges, +and returns a new TTFont representing either a partial VF, or full instance if all +the VF axes were given an explicit coordinate. + +E.g. here's how to pin the wght axis at a given location in a wght+wdth variable +font, keeping only the deltas associated with the wdth axis: +.. code-block:: pycon + + >>> + >> from fontTools import ttLib + >> from fontTools.varLib import instancer + >> varfont = ttLib.TTFont("path/to/MyVariableFont.ttf") + >> [a.axisTag for a in varfont["fvar"].axes] # the varfont's current axes + ['wght', 'wdth'] + >> partial = instancer.instantiateVariableFont(varfont, {"wght": 300}) + >> [a.axisTag for a in partial["fvar"].axes] # axes left after pinning 'wght' + ['wdth'] + +If the input location specifies all the axes, the resulting instance is no longer +'variable' (same as using fontools varLib.mutator): +.. code-block:: pycon + + >>> + >> instance = instancer.instantiateVariableFont( + ... varfont, {"wght": 700, "wdth": 67.5} + ... ) + >> "fvar" not in instance + True + +If one just want to drop an axis at the default location, without knowing in +advance what the default value for that axis is, one can pass a `None` value: +.. code-block:: pycon + + >>> + >> instance = instancer.instantiateVariableFont(varfont, {"wght": None}) + >> len(varfont["fvar"].axes) + 1 + +From the console script, this is equivalent to passing `wght=drop` as input. + +This module is similar to fontTools.varLib.mutator, which it's intended to supersede. +Note that, unlike varLib.mutator, when an axis is not mentioned in the input +location, by default the varLib.instancer will keep the axis and the corresponding +deltas, whereas mutator implicitly drops the axis at its default coordinate. +To obtain the same behavior as mutator, pass the `static=True` parameter or +the `--static` CLI option. + +The module supports all the following "levels" of instancing, which can of +course be combined: + +L1 + dropping one or more axes while leaving the default tables unmodified; + .. code-block:: pycon + + >>> + >> font = instancer.instantiateVariableFont(varfont, {"wght": None}) + +L2 + dropping one or more axes while pinning them at non-default locations; + .. code-block:: pycon + + >>> + >> font = instancer.instantiateVariableFont(varfont, {"wght": 700}) + +L3 + restricting the range of variation of one or more axes, by setting either + a new minimum or maximum, potentially -- though not necessarily -- dropping + entire regions of variations that fall completely outside this new range. + .. code-block:: pycon + + >>> + >> font = instancer.instantiateVariableFont(varfont, {"wght": (100, 300)}) + +L4 + moving the default location of an axis, by specifying (min,defalt,max) values: + .. code-block:: pycon + + >>> + >> font = instancer.instantiateVariableFont(varfont, {"wght": (100, 300, 700)}) + +Both TrueType-flavored (glyf+gvar) variable and CFF2 variable fonts are supported. +""" + +from fontTools.misc.fixedTools import ( + floatToFixedToFloat, + strToFixedToFloat, + otRound, +) +from fontTools.varLib.models import normalizeValue, piecewiseLinearMap +from fontTools.ttLib import TTFont, newTable +from fontTools.ttLib.tables.TupleVariation import TupleVariation +from fontTools.ttLib.tables import _g_l_y_f +from fontTools import varLib + +# we import the `subset` module because we use the `prune_lookups` method on the GSUB +# table class, and that method is only defined dynamically upon importing `subset` +from fontTools import subset # noqa: F401 +from fontTools.cffLib import privateDictOperators2 +from fontTools.cffLib.specializer import ( + programToCommands, + commandsToProgram, + specializeCommands, + generalizeCommands, +) +from fontTools.cffLib.CFF2ToCFF import convertCFF2ToCFF +from fontTools.varLib import builder +from fontTools.varLib.mvar import MVAR_ENTRIES +from fontTools.varLib.merger import MutatorMerger +from fontTools.varLib.instancer import names +from .featureVars import instantiateFeatureVariations +from fontTools.misc.cliTools import makeOutputFileName +from fontTools.varLib.instancer import solver +from fontTools.ttLib.tables.otTables import VarComponentFlags +import collections +import dataclasses +from contextlib import contextmanager +from copy import deepcopy +from enum import IntEnum +import logging +import os +import re +import io +from typing import Dict, Iterable, Mapping, Optional, Sequence, Tuple, Union +import warnings + + +log = logging.getLogger("fontTools.varLib.instancer") + + +def AxisRange(minimum, maximum): + warnings.warn( + "AxisRange is deprecated; use AxisTriple instead", + DeprecationWarning, + stacklevel=2, + ) + return AxisTriple(minimum, None, maximum) + + +def NormalizedAxisRange(minimum, maximum): + warnings.warn( + "NormalizedAxisRange is deprecated; use AxisTriple instead", + DeprecationWarning, + stacklevel=2, + ) + return NormalizedAxisTriple(minimum, None, maximum) + + +@dataclasses.dataclass(frozen=True, order=True, repr=False) +class AxisTriple(Sequence): + """A triple of (min, default, max) axis values. + + Any of the values can be None, in which case the limitRangeAndPopulateDefaults() + method can be used to fill in the missing values based on the fvar axis values. + """ + + minimum: Optional[float] + default: Optional[float] + maximum: Optional[float] + + def __post_init__(self): + if self.default is None and self.minimum == self.maximum: + object.__setattr__(self, "default", self.minimum) + if ( + ( + self.minimum is not None + and self.default is not None + and self.minimum > self.default + ) + or ( + self.default is not None + and self.maximum is not None + and self.default > self.maximum + ) + or ( + self.minimum is not None + and self.maximum is not None + and self.minimum > self.maximum + ) + ): + raise ValueError( + f"{type(self).__name__} minimum ({self.minimum}), default ({self.default}), maximum ({self.maximum}) must be in sorted order" + ) + + def __getitem__(self, i): + fields = dataclasses.fields(self) + return getattr(self, fields[i].name) + + def __len__(self): + return len(dataclasses.fields(self)) + + def _replace(self, **kwargs): + return dataclasses.replace(self, **kwargs) + + def __repr__(self): + return ( + f"({', '.join(format(v, 'g') if v is not None else 'None' for v in self)})" + ) + + @classmethod + def expand( + cls, + v: Union[ + "AxisTriple", + float, # pin axis at single value, same as min==default==max + Tuple[float, float], # (min, max), restrict axis and keep default + Tuple[float, float, float], # (min, default, max) + ], + ) -> "AxisTriple": + """Convert a single value or a tuple into an AxisTriple. + + If the input is a single value, it is interpreted as a pin at that value. + If the input is a tuple, it is interpreted as (min, max) or (min, default, max). + """ + if isinstance(v, cls): + return v + if isinstance(v, (int, float)): + return cls(v, v, v) + try: + n = len(v) + except TypeError as e: + raise ValueError( + f"expected float, 2- or 3-tuple of floats; got {type(v)}: {v!r}" + ) from e + default = None + if n == 2: + minimum, maximum = v + elif n >= 3: + return cls(*v) + else: + raise ValueError(f"expected sequence of 2 or 3; got {n}: {v!r}") + return cls(minimum, default, maximum) + + def limitRangeAndPopulateDefaults(self, fvarTriple) -> "AxisTriple": + """Return a new AxisTriple with the default value filled in. + + Set default to fvar axis default if the latter is within the min/max range, + otherwise set default to the min or max value, whichever is closer to the + fvar axis default. + If the default value is already set, return self. + """ + minimum = self.minimum + if minimum is None: + minimum = fvarTriple[0] + default = self.default + if default is None: + default = fvarTriple[1] + maximum = self.maximum + if maximum is None: + maximum = fvarTriple[2] + + minimum = max(minimum, fvarTriple[0]) + maximum = max(maximum, fvarTriple[0]) + minimum = min(minimum, fvarTriple[2]) + maximum = min(maximum, fvarTriple[2]) + default = max(minimum, min(maximum, default)) + + return AxisTriple(minimum, default, maximum) + + +@dataclasses.dataclass(frozen=True, order=True, repr=False) +class NormalizedAxisTriple(AxisTriple): + """A triple of (min, default, max) normalized axis values.""" + + minimum: float + default: float + maximum: float + + def __post_init__(self): + if self.default is None: + object.__setattr__(self, "default", max(self.minimum, min(self.maximum, 0))) + if not (-1.0 <= self.minimum <= self.default <= self.maximum <= 1.0): + raise ValueError( + "Normalized axis values not in -1..+1 range; got " + f"minimum={self.minimum:g}, default={self.default:g}, maximum={self.maximum:g})" + ) + + +@dataclasses.dataclass(frozen=True, order=True, repr=False) +class NormalizedAxisTripleAndDistances(AxisTriple): + """A triple of (min, default, max) normalized axis values, + with distances between min and default, and default and max, + in the *pre-normalized* space.""" + + minimum: float + default: float + maximum: float + distanceNegative: Optional[float] = 1 + distancePositive: Optional[float] = 1 + + def __post_init__(self): + if self.default is None: + object.__setattr__(self, "default", max(self.minimum, min(self.maximum, 0))) + if not (-1.0 <= self.minimum <= self.default <= self.maximum <= 1.0): + raise ValueError( + "Normalized axis values not in -1..+1 range; got " + f"minimum={self.minimum:g}, default={self.default:g}, maximum={self.maximum:g})" + ) + + def reverse_negate(self): + v = self + return self.__class__(-v[2], -v[1], -v[0], v[4], v[3]) + + def renormalizeValue(self, v, extrapolate=True): + """Renormalizes a normalized value v to the range of this axis, + considering the pre-normalized distances as well as the new + axis limits.""" + + lower, default, upper, distanceNegative, distancePositive = self + assert lower <= default <= upper + + if not extrapolate: + v = max(lower, min(upper, v)) + + if v == default: + return 0 + + if default < 0: + return -self.reverse_negate().renormalizeValue(-v, extrapolate=extrapolate) + + # default >= 0 and v != default + + if v > default: + return (v - default) / (upper - default) + + # v < default + + if lower >= 0: + return (v - default) / (default - lower) + + # lower < 0 and v < default + + totalDistance = distanceNegative * -lower + distancePositive * default + + if v >= 0: + vDistance = (default - v) * distancePositive + else: + vDistance = -v * distanceNegative + distancePositive * default + + return -vDistance / totalDistance + + +class _BaseAxisLimits(Mapping[str, AxisTriple]): + def __getitem__(self, key: str) -> AxisTriple: + return self._data[key] + + def __iter__(self) -> Iterable[str]: + return iter(self._data) + + def __len__(self) -> int: + return len(self._data) + + def __repr__(self) -> str: + return f"{type(self).__name__}({self._data!r})" + + def __str__(self) -> str: + return str(self._data) + + def defaultLocation(self) -> Dict[str, float]: + """Return a dict of default axis values.""" + return {k: v.default for k, v in self.items()} + + def pinnedLocation(self) -> Dict[str, float]: + """Return a location dict with only the pinned axes.""" + return {k: v.default for k, v in self.items() if v.minimum == v.maximum} + + +class AxisLimits(_BaseAxisLimits): + """Maps axis tags (str) to AxisTriple values.""" + + def __init__(self, *args, **kwargs): + self._data = data = {} + for k, v in dict(*args, **kwargs).items(): + if v is None: + # will be filled in by limitAxesAndPopulateDefaults + data[k] = v + else: + try: + triple = AxisTriple.expand(v) + except ValueError as e: + raise ValueError(f"Invalid axis limits for {k!r}: {v!r}") from e + data[k] = triple + + def limitAxesAndPopulateDefaults(self, varfont) -> "AxisLimits": + """Return a new AxisLimits with defaults filled in from fvar table. + + If all axis limits already have defaults, return self. + """ + fvar = varfont["fvar"] + fvarTriples = { + a.axisTag: (a.minValue, a.defaultValue, a.maxValue) for a in fvar.axes + } + newLimits = {} + for axisTag, triple in self.items(): + fvarTriple = fvarTriples[axisTag] + default = fvarTriple[1] + if triple is None: + newLimits[axisTag] = AxisTriple(default, default, default) + else: + newLimits[axisTag] = triple.limitRangeAndPopulateDefaults(fvarTriple) + return type(self)(newLimits) + + def normalize(self, varfont, usingAvar=True) -> "NormalizedAxisLimits": + """Return a new NormalizedAxisLimits with normalized -1..0..+1 values. + + If usingAvar is True, the avar table is used to warp the default normalization. + """ + fvar = varfont["fvar"] + badLimits = set(self.keys()).difference(a.axisTag for a in fvar.axes) + if badLimits: + raise ValueError("Cannot limit: {} not present in fvar".format(badLimits)) + + axes = { + a.axisTag: (a.minValue, a.defaultValue, a.maxValue) + for a in fvar.axes + if a.axisTag in self + } + + avarSegments = {} + if usingAvar and "avar" in varfont: + avar = varfont["avar"] + avarSegments = avar.segments + + if getattr(avar, "majorVersion", 1) >= 2 and avar.table.VarStore: + pinnedAxes = set(self.pinnedLocation()) + if not pinnedAxes.issuperset(avarSegments): + raise NotImplementedError( + "Partial-instancing avar2 table is not supported" + ) + + # TODO: Merge this with the main codepath. + + # Full instancing of avar2 font. Use avar table to normalize location and return. + location = self.pinnedLocation() + location = { + tag: normalize(value, axes[tag], None) + for tag, value in location.items() + } + return NormalizedAxisLimits( + **avar.renormalizeLocation(location, varfont, dropZeroes=False) + ) + + normalizedLimits = {} + + for axis_tag, triple in axes.items(): + distanceNegative = triple[1] - triple[0] + distancePositive = triple[2] - triple[1] + + if self[axis_tag] is None: + normalizedLimits[axis_tag] = NormalizedAxisTripleAndDistances( + 0, 0, 0, distanceNegative, distancePositive + ) + continue + + minV, defaultV, maxV = self[axis_tag] + + if defaultV is None: + defaultV = triple[1] + + avarMapping = avarSegments.get(axis_tag, None) + normalizedLimits[axis_tag] = NormalizedAxisTripleAndDistances( + *(normalize(v, triple, avarMapping) for v in (minV, defaultV, maxV)), + distanceNegative, + distancePositive, + ) + + return NormalizedAxisLimits(normalizedLimits) + + +class NormalizedAxisLimits(_BaseAxisLimits): + """Maps axis tags (str) to NormalizedAxisTriple values.""" + + def __init__(self, *args, **kwargs): + self._data = data = {} + for k, v in dict(*args, **kwargs).items(): + try: + triple = NormalizedAxisTripleAndDistances.expand(v) + except ValueError as e: + raise ValueError(f"Invalid axis limits for {k!r}: {v!r}") from e + data[k] = triple + + +class OverlapMode(IntEnum): + KEEP_AND_DONT_SET_FLAGS = 0 + KEEP_AND_SET_FLAGS = 1 + REMOVE = 2 + REMOVE_AND_IGNORE_ERRORS = 3 + + +def instantiateVARC(varfont, axisLimits): + log.info("Instantiating VARC tables") + + # TODO(behdad) My confidence in this function is rather low; + # It needs more testing. Specially with partial-instancing, + # I don't think it currently works. + + varc = varfont["VARC"].table + fvarAxes = varfont["fvar"].axes if "fvar" in varfont else [] + + location = axisLimits.pinnedLocation() + axisMap = [i for i, axis in enumerate(fvarAxes) if axis.axisTag not in location] + reverseAxisMap = {i: j for j, i in enumerate(axisMap)} + + if varc.AxisIndicesList: + axisIndicesList = varc.AxisIndicesList.Item + for i, axisIndices in enumerate(axisIndicesList): + if any(fvarAxes[j].axisTag in axisLimits for j in axisIndices): + raise NotImplementedError( + "Instancing across VarComponent axes is not supported." + ) + axisIndicesList[i] = [reverseAxisMap[j] for j in axisIndices] + + store = varc.MultiVarStore + if store: + for region in store.SparseVarRegionList.Region: + newRegionAxis = [] + for regionRecord in region.SparseVarRegionAxis: + tag = fvarAxes[regionRecord.AxisIndex].axisTag + if tag in axisLimits: + raise NotImplementedError( + "Instancing across VarComponent axes is not supported." + ) + regionRecord.AxisIndex = reverseAxisMap[regionRecord.AxisIndex] + + +def instantiateTupleVariationStore( + variations, axisLimits, origCoords=None, endPts=None +): + """Instantiate TupleVariation list at the given location, or limit axes' min/max. + + The 'variations' list of TupleVariation objects is modified in-place. + The 'axisLimits' (dict) maps axis tags (str) to NormalizedAxisTriple namedtuples + specifying (minimum, default, maximum) in the -1,0,+1 normalized space. Pinned axes + have minimum == default == maximum. + + A 'full' instance (i.e. static font) is produced when all the axes are pinned to + single coordinates; a 'partial' instance (i.e. a less variable font) is produced + when some of the axes are omitted, or restricted with a new range. + + Tuples that do not participate are kept as they are. Those that have 0 influence + at the given location are removed from the variation store. + Those that are fully instantiated (i.e. all their axes are being pinned) are also + removed from the variation store, their scaled deltas accummulated and returned, so + that they can be added by the caller to the default instance's coordinates. + Tuples that are only partially instantiated (i.e. not all the axes that they + participate in are being pinned) are kept in the store, and their deltas multiplied + by the scalar support of the axes to be pinned at the desired location. + + Args: + variations: List[TupleVariation] from either 'gvar' or 'cvar'. + axisLimits: NormalizedAxisLimits: map from axis tags to (min, default, max) + normalized coordinates for the full or partial instance. + origCoords: GlyphCoordinates: default instance's coordinates for computing 'gvar' + inferred points (cf. table__g_l_y_f._getCoordinatesAndControls). + endPts: List[int]: indices of contour end points, for inferring 'gvar' deltas. + + Returns: + List[float]: the overall delta adjustment after applicable deltas were summed. + """ + + newVariations = changeTupleVariationsAxisLimits(variations, axisLimits) + + mergedVariations = collections.OrderedDict() + for var in newVariations: + # compute inferred deltas only for gvar ('origCoords' is None for cvar) + if origCoords is not None: + var.calcInferredDeltas(origCoords, endPts) + + # merge TupleVariations with overlapping "tents" + axes = frozenset(var.axes.items()) + if axes in mergedVariations: + mergedVariations[axes] += var + else: + mergedVariations[axes] = var + + # drop TupleVariation if all axes have been pinned (var.axes.items() is empty); + # its deltas will be added to the default instance's coordinates + defaultVar = mergedVariations.pop(frozenset(), None) + + for var in mergedVariations.values(): + var.roundDeltas() + variations[:] = list(mergedVariations.values()) + + return defaultVar.coordinates if defaultVar is not None else [] + + +def changeTupleVariationsAxisLimits(variations, axisLimits): + for axisTag, axisLimit in sorted(axisLimits.items()): + newVariations = [] + for var in variations: + newVariations.extend(changeTupleVariationAxisLimit(var, axisTag, axisLimit)) + variations = newVariations + return variations + + +def changeTupleVariationAxisLimit(var, axisTag, axisLimit): + assert isinstance(axisLimit, NormalizedAxisTripleAndDistances) + + # Skip when current axis is missing or peaks at 0 (i.e. doesn't participate) + lower, peak, upper = var.axes.get(axisTag, (-1, 0, 1)) + if peak == 0: + # explicitly defined, no-op axes can be omitted + # https://github.com/fonttools/fonttools/issues/3453 + if axisTag in var.axes: + del var.axes[axisTag] + return [var] + # Drop if the var 'tent' isn't well-formed + if not (lower <= peak <= upper) or (lower < 0 and upper > 0): + return [] + + if axisTag not in var.axes: + return [var] + + tent = var.axes[axisTag] + + solutions = solver.rebaseTent(tent, axisLimit) + + out = [] + for scalar, tent in solutions: + newVar = ( + TupleVariation(var.axes, var.coordinates) if len(solutions) > 1 else var + ) + if tent is None: + newVar.axes.pop(axisTag) + else: + assert tent[1] != 0, tent + newVar.axes[axisTag] = tent + newVar *= scalar + out.append(newVar) + + return out + + +def instantiateCFF2( + varfont, + axisLimits, + *, + round=round, + specialize=True, + generalize=False, + downgrade=False, +): + # The algorithm here is rather simple: + # + # Take all blend operations and store their deltas in the (otherwise empty) + # CFF2 VarStore. Then, instantiate the VarStore with the given axis limits, + # and read back the new deltas. This is done for both the CharStrings and + # the Private dicts. + # + # Then prune unused things and possibly drop the VarStore if it's empty. + # + # If the downgrade parameter is True, no actual downgrading is done, but + # the function returns True if the VarStore was empty after instantiation, + # and hence a downgrade to CFF is possible. In all other cases it returns + # False. + + log.info("Instantiating CFF2 table") + + fvarAxes = varfont["fvar"].axes + + cff = varfont["CFF2"].cff + topDict = cff.topDictIndex[0] + varStore = topDict.VarStore.otVarStore + if not varStore: + if downgrade: + from fontTools.cffLib.CFF2ToCFF import convertCFF2ToCFF + + convertCFF2ToCFF(varfont) + return + + cff.desubroutinize() + + def getNumRegions(vsindex): + return varStore.VarData[vsindex if vsindex is not None else 0].VarRegionCount + + charStrings = topDict.CharStrings.values() + + # Gather all unique private dicts + uniquePrivateDicts = set() + privateDicts = [] + for fd in topDict.FDArray: + if fd.Private not in uniquePrivateDicts: + uniquePrivateDicts.add(fd.Private) + privateDicts.append(fd.Private) + + allCommands = [] + allCommandPrivates = [] + for cs in charStrings: + assert cs.private.vstore.otVarStore is varStore # Or in many places!! + commands = programToCommands(cs.program, getNumRegions=getNumRegions) + if generalize: + commands = generalizeCommands(commands) + if specialize: + commands = specializeCommands(commands, generalizeFirst=not generalize) + allCommands.append(commands) + allCommandPrivates.append(cs.private) + + def storeBlendsToVarStore(arg): + if not isinstance(arg, list): + return + + if any(isinstance(subarg, list) for subarg in arg[:-1]): + raise NotImplementedError("Nested blend lists not supported (yet)") + + count = arg[-1] + assert (len(arg) - 1) % count == 0 + nRegions = (len(arg) - 1) // count - 1 + assert nRegions == getNumRegions(vsindex) + for i in range(count, len(arg) - 1, nRegions): + deltas = arg[i : i + nRegions] + assert len(deltas) == nRegions + varData = varStore.VarData[vsindex] + varData.Item.append(deltas) + varData.ItemCount += 1 + + def fetchBlendsFromVarStore(arg): + if not isinstance(arg, list): + return [arg] + + if any(isinstance(subarg, list) for subarg in arg[:-1]): + raise NotImplementedError("Nested blend lists not supported (yet)") + + count = arg[-1] + assert (len(arg) - 1) % count == 0 + numRegions = getNumRegions(vsindex) + newDefaults = [] + newDeltas = [] + for i in range(count): + defaultValue = arg[i] + + major = vsindex + minor = varDataCursor[major] + varDataCursor[major] += 1 + + defaultValue += round(defaultDeltas[major][minor]) + newDefaults.append(defaultValue) + + varData = varStore.VarData[major] + deltas = varData.Item[minor] + assert len(deltas) == numRegions + newDeltas.extend(deltas) + + if not numRegions: + return newDefaults # No deltas, just return the defaults + + return [newDefaults + newDeltas + [count]] + + # Check VarData's are empty + for varData in varStore.VarData: + assert varData.Item == [] + assert varData.ItemCount == 0 + + # Add charstring blend lists to VarStore so we can instantiate them + for commands, private in zip(allCommands, allCommandPrivates): + vsindex = getattr(private, "vsindex", 0) + for command in commands: + if command[0] == "vsindex": + vsindex = command[1][0] + continue + for arg in command[1]: + storeBlendsToVarStore(arg) + + # Add private blend lists to VarStore so we can instantiate values + for opcode, name, arg_type, default, converter in privateDictOperators2: + if arg_type not in ("number", "delta", "array"): + continue + + vsindex = 0 + for private in privateDicts: + if not hasattr(private, name): + continue + values = getattr(private, name) + + # This is safe here since "vsindex" is the first in the privateDictOperators2 + if name == "vsindex": + vsindex = values[0] + continue + + if arg_type == "number": + values = [values] + + for value in values: + if not isinstance(value, list): + continue + + assert len(value) % (getNumRegions(vsindex) + 1) == 0 + count = len(value) // (getNumRegions(vsindex) + 1) + storeBlendsToVarStore(value + [count]) + + # Instantiate VarStore + defaultDeltas = instantiateItemVariationStore( + varStore, fvarAxes, axisLimits, hierarchical=True + ) + + # Read back new charstring blends from the instantiated VarStore + varDataCursor = [0] * len(varStore.VarData) + for commands, private in zip(allCommands, allCommandPrivates): + vsindex = getattr(private, "vsindex", 0) + for command in commands: + if command[0] == "vsindex": + vsindex = command[1][0] + continue + newArgs = [] + for arg in command[1]: + newArgs.extend(fetchBlendsFromVarStore(arg)) + command[1][:] = newArgs + + # Read back new private blends from the instantiated VarStore + for opcode, name, arg_type, default, converter in privateDictOperators2: + if arg_type not in ("number", "delta", "array"): + continue + + vsindex = 0 + for private in privateDicts: + if not hasattr(private, name): + continue + + # This is safe here since "vsindex" is the first in the privateDictOperators2 + if name == "vsindex": + vsindex = values[0] + continue + + values = getattr(private, name) + if arg_type == "number": + values = [values] + + newValues = [] + for value in values: + if not isinstance(value, list): + newValues.append(value) + continue + + value.append(1) + value = fetchBlendsFromVarStore(value) + newValues.extend(v[:-1] if isinstance(v, list) else v for v in value) + + if arg_type == "number": + newValues = newValues[0] + + setattr(private, name, newValues) + + # Empty out the VarStore + for i, varData in enumerate(varStore.VarData): + assert varDataCursor[i] == varData.ItemCount, ( + varDataCursor[i], + varData.ItemCount, + ) + varData.Item = [] + varData.ItemCount = 0 + + # Collect surviving vsindexes + usedVsindex = set( + i for i in range(len(varStore.VarData)) if varStore.VarData[i].VarRegionCount + ) + # Remove vsindex commands that are no longer needed + for commands, private in zip(allCommands, allCommandPrivates): + if not any(isinstance(arg, list) for command in commands for arg in command[1]): + commands[:] = [command for command in commands if command[0] != "vsindex"] + + # Remove unused VarData and update vsindex values + vsindexMapping = {v: i for i, v in enumerate(sorted(usedVsindex))} + varStore.VarData = [ + varData for i, varData in enumerate(varStore.VarData) if i in usedVsindex + ] + varStore.VarDataCount = len(varStore.VarData) + for commands in allCommands: + for command in commands: + if command[0] == "vsindex": + command[1][0] = vsindexMapping[command[1][0]] + for private in privateDicts: + if hasattr(private, "vsindex"): + private.vsindex = vsindexMapping[private.vsindex] + + # Remove initial vsindex commands that are implied + for commands, private in zip(allCommands, allCommandPrivates): + vsindex = getattr(private, "vsindex", 0) + if commands and commands[0] == ("vsindex", [vsindex]): + commands.pop(0) + + # Ship the charstrings! + for cs, commands in zip(charStrings, allCommands): + cs.program = commandsToProgram(commands) + + # Remove empty VarStore + if not varStore.VarData: + if "VarStore" in topDict.rawDict: + del topDict.rawDict["VarStore"] + del topDict.VarStore + del topDict.CharStrings.varStore + for private in privateDicts: + del private.vstore + + if downgrade: + return True + + return False + + +def _instantiateGvarGlyph( + glyphname, glyf, gvar, hMetrics, vMetrics, axisLimits, optimize=True +): + coordinates, ctrl = glyf._getCoordinatesAndControls(glyphname, hMetrics, vMetrics) + endPts = ctrl.endPts + + # Not every glyph may have variations + tupleVarStore = gvar.variations.get(glyphname) + + if tupleVarStore: + defaultDeltas = instantiateTupleVariationStore( + tupleVarStore, axisLimits, coordinates, endPts + ) + + if defaultDeltas: + coordinates += _g_l_y_f.GlyphCoordinates(defaultDeltas) + + # _setCoordinates also sets the hmtx/vmtx advance widths and sidebearings from + # the four phantom points and glyph bounding boxes. + # We call it unconditionally even if a glyph has no variations or no deltas are + # applied at this location, in case the glyph's xMin and in turn its sidebearing + # have changed. E.g. a composite glyph has no deltas for the component's (x, y) + # offset nor for the 4 phantom points (e.g. it's monospaced). Thus its entry in + # gvar table is empty; however, the composite's base glyph may have deltas + # applied, hence the composite's bbox and left/top sidebearings may need updating + # in the instanced font. + glyf._setCoordinates(glyphname, coordinates, hMetrics, vMetrics) + + if not tupleVarStore: + if glyphname in gvar.variations: + del gvar.variations[glyphname] + return + + if optimize: + # IUP semantics depend on point equality, and so round prior to + # optimization to ensure that comparisons that happen now will be the + # same as those that happen at render time. This is especially needed + # when floating point deltas have been applied to the default position. + # See https://github.com/fonttools/fonttools/issues/3634 + # Rounding must happen only after calculating glyf metrics above, to + # preserve backwards compatibility. + # See 0010a3cd9aa25f84a3a6250dafb119743d32aa40 + coordinates.toInt() + + isComposite = glyf[glyphname].isComposite() + + for var in tupleVarStore: + var.optimize(coordinates, endPts, isComposite=isComposite) + + +def instantiateGvarGlyph(varfont, glyphname, axisLimits, optimize=True): + """Remove? + https://github.com/fonttools/fonttools/pull/2266""" + gvar = varfont["gvar"] + glyf = varfont["glyf"] + hMetrics = varfont["hmtx"].metrics + vMetrics = getattr(varfont.get("vmtx"), "metrics", None) + _instantiateGvarGlyph( + glyphname, glyf, gvar, hMetrics, vMetrics, axisLimits, optimize=optimize + ) + + +def instantiateGvar(varfont, axisLimits, optimize=True): + log.info("Instantiating glyf/gvar tables") + + gvar = varfont["gvar"] + glyf = varfont["glyf"] + hMetrics = varfont["hmtx"].metrics + vMetrics = getattr(varfont.get("vmtx"), "metrics", None) + # Get list of glyph names sorted by component depth. + # If a composite glyph is processed before its base glyph, the bounds may + # be calculated incorrectly because deltas haven't been applied to the + # base glyph yet. + glyphnames = sorted( + glyf.glyphOrder, + key=lambda name: ( + ( + glyf[name].getCompositeMaxpValues(glyf).maxComponentDepth + if glyf[name].isComposite() + else 0 + ), + name, + ), + ) + for glyphname in glyphnames: + _instantiateGvarGlyph( + glyphname, glyf, gvar, hMetrics, vMetrics, axisLimits, optimize=optimize + ) + + if not gvar.variations: + del varfont["gvar"] + + +def setCvarDeltas(cvt, deltas): + for i, delta in enumerate(deltas): + if delta: + cvt[i] += otRound(delta) + + +def instantiateCvar(varfont, axisLimits): + log.info("Instantiating cvt/cvar tables") + + cvar = varfont["cvar"] + + defaultDeltas = instantiateTupleVariationStore(cvar.variations, axisLimits) + + if defaultDeltas: + setCvarDeltas(varfont["cvt "], defaultDeltas) + + if not cvar.variations: + del varfont["cvar"] + + +def setMvarDeltas(varfont, deltas): + mvar = varfont["MVAR"].table + records = mvar.ValueRecord + for rec in records: + mvarTag = rec.ValueTag + if mvarTag not in MVAR_ENTRIES: + continue + tableTag, itemName = MVAR_ENTRIES[mvarTag] + delta = deltas[rec.VarIdx] + if delta != 0: + setattr( + varfont[tableTag], + itemName, + getattr(varfont[tableTag], itemName) + otRound(delta), + ) + + +@contextmanager +def verticalMetricsKeptInSync(varfont): + """Ensure hhea vertical metrics stay in sync with OS/2 ones after instancing. + + When applying MVAR deltas to the OS/2 table, if the ascender, descender and + line gap change but they were the same as the respective hhea metrics in the + original font, this context manager ensures that hhea metrcs also get updated + accordingly. + The MVAR spec only has tags for the OS/2 metrics, but it is common in fonts + to have the hhea metrics be equal to those for compat reasons. + + https://learn.microsoft.com/en-us/typography/opentype/spec/mvar + https://googlefonts.github.io/gf-guide/metrics.html#7-hhea-and-typo-metrics-should-be-equal + https://github.com/fonttools/fonttools/issues/3297 + """ + current_os2_vmetrics = [ + getattr(varfont["OS/2"], attr) + for attr in ("sTypoAscender", "sTypoDescender", "sTypoLineGap") + ] + metrics_are_synced = current_os2_vmetrics == [ + getattr(varfont["hhea"], attr) for attr in ("ascender", "descender", "lineGap") + ] + + yield metrics_are_synced + + if metrics_are_synced: + new_os2_vmetrics = [ + getattr(varfont["OS/2"], attr) + for attr in ("sTypoAscender", "sTypoDescender", "sTypoLineGap") + ] + if current_os2_vmetrics != new_os2_vmetrics: + for attr, value in zip( + ("ascender", "descender", "lineGap"), new_os2_vmetrics + ): + setattr(varfont["hhea"], attr, value) + + +def instantiateMVAR(varfont, axisLimits): + log.info("Instantiating MVAR table") + + mvar = varfont["MVAR"].table + fvarAxes = varfont["fvar"].axes + varStore = mvar.VarStore + defaultDeltas = instantiateItemVariationStore(varStore, fvarAxes, axisLimits) + + with verticalMetricsKeptInSync(varfont): + setMvarDeltas(varfont, defaultDeltas) + + if varStore.VarRegionList.Region: + varIndexMapping = varStore.optimize() + for rec in mvar.ValueRecord: + rec.VarIdx = varIndexMapping[rec.VarIdx] + else: + del varfont["MVAR"] + + +def _remapVarIdxMap(table, attrName, varIndexMapping, glyphOrder): + oldMapping = getattr(table, attrName).mapping + newMapping = [varIndexMapping[oldMapping[glyphName]] for glyphName in glyphOrder] + setattr(table, attrName, builder.buildVarIdxMap(newMapping, glyphOrder)) + + +# TODO(anthrotype) Add support for HVAR/VVAR in CFF2 +def _instantiateVHVAR(varfont, axisLimits, tableFields, *, round=round): + location = axisLimits.pinnedLocation() + tableTag = tableFields.tableTag + fvarAxes = varfont["fvar"].axes + + log.info("Instantiating %s table", tableTag) + vhvar = varfont[tableTag].table + varStore = vhvar.VarStore + + if "glyf" in varfont: + # Deltas from gvar table have already been applied to the hmtx/vmtx. For full + # instances (i.e. all axes pinned), we can simply drop HVAR/VVAR and return + if set(location).issuperset(axis.axisTag for axis in fvarAxes): + log.info("Dropping %s table", tableTag) + del varfont[tableTag] + return + + defaultDeltas = instantiateItemVariationStore(varStore, fvarAxes, axisLimits) + + if "glyf" not in varfont: + # CFF2 fonts need hmtx/vmtx updated here. For glyf fonts, the instantiateGvar + # function already updated the hmtx/vmtx from phantom points. Maybe remove + # that and do it here for both CFF2 and glyf fonts? + # + # Specially, if a font has glyf but not gvar, the hmtx/vmtx will not have been + # updated by instantiateGvar. Though one can call that a faulty font. + metricsTag = "vmtx" if tableTag == "VVAR" else "hmtx" + if metricsTag in varfont: + advMapping = getattr(vhvar, tableFields.advMapping) + metricsTable = varfont[metricsTag] + metrics = metricsTable.metrics + for glyphName, (advanceWidth, sb) in metrics.items(): + if advMapping: + varIdx = advMapping.mapping[glyphName] + else: + varIdx = varfont.getGlyphID(glyphName) + delta = round(defaultDeltas[varIdx]) + metrics[glyphName] = (max(0, advanceWidth + delta), sb) + + if ( + tableTag == "VVAR" + and getattr(vhvar, tableFields.vOrigMapping) is not None + ): + log.warning( + "VORG table not yet updated to reflect changes in VVAR table" + ) + + # For full instances (i.e. all axes pinned), we can simply drop HVAR/VVAR and return + if set(location).issuperset(axis.axisTag for axis in fvarAxes): + log.info("Dropping %s table", tableTag) + del varfont[tableTag] + return + + if varStore.VarRegionList.Region: + # Only re-optimize VarStore if the HVAR/VVAR already uses indirect AdvWidthMap + # or AdvHeightMap. If a direct, implicit glyphID->VariationIndex mapping is + # used for advances, skip re-optimizing and maintain original VariationIndex. + if getattr(vhvar, tableFields.advMapping): + varIndexMapping = varStore.optimize(use_NO_VARIATION_INDEX=False) + glyphOrder = varfont.getGlyphOrder() + _remapVarIdxMap(vhvar, tableFields.advMapping, varIndexMapping, glyphOrder) + if getattr(vhvar, tableFields.sb1): # left or top sidebearings + _remapVarIdxMap(vhvar, tableFields.sb1, varIndexMapping, glyphOrder) + if getattr(vhvar, tableFields.sb2): # right or bottom sidebearings + _remapVarIdxMap(vhvar, tableFields.sb2, varIndexMapping, glyphOrder) + if tableTag == "VVAR" and getattr(vhvar, tableFields.vOrigMapping): + _remapVarIdxMap( + vhvar, tableFields.vOrigMapping, varIndexMapping, glyphOrder + ) + + +def instantiateHVAR(varfont, axisLimits): + return _instantiateVHVAR(varfont, axisLimits, varLib.HVAR_FIELDS) + + +def instantiateVVAR(varfont, axisLimits): + return _instantiateVHVAR(varfont, axisLimits, varLib.VVAR_FIELDS) + + +class _TupleVarStoreAdapter(object): + def __init__(self, regions, axisOrder, tupleVarData, itemCounts): + self.regions = regions + self.axisOrder = axisOrder + self.tupleVarData = tupleVarData + self.itemCounts = itemCounts + + @classmethod + def fromItemVarStore(cls, itemVarStore, fvarAxes): + axisOrder = [axis.axisTag for axis in fvarAxes] + regions = [ + region.get_support(fvarAxes) for region in itemVarStore.VarRegionList.Region + ] + tupleVarData = [] + itemCounts = [] + for varData in itemVarStore.VarData: + variations = [] + varDataRegions = (regions[i] for i in varData.VarRegionIndex) + for axes, coordinates in zip(varDataRegions, zip(*varData.Item)): + variations.append(TupleVariation(axes, list(coordinates))) + tupleVarData.append(variations) + itemCounts.append(varData.ItemCount) + return cls(regions, axisOrder, tupleVarData, itemCounts) + + def rebuildRegions(self): + # Collect the set of all unique region axes from the current TupleVariations. + # We use an OrderedDict to de-duplicate regions while keeping the order. + uniqueRegions = collections.OrderedDict.fromkeys( + ( + frozenset(var.axes.items()) + for variations in self.tupleVarData + for var in variations + ) + ) + # Maintain the original order for the regions that pre-existed, appending + # the new regions at the end of the region list. + newRegions = [] + for region in self.regions: + regionAxes = frozenset(region.items()) + if regionAxes in uniqueRegions: + newRegions.append(region) + del uniqueRegions[regionAxes] + if uniqueRegions: + newRegions.extend(dict(region) for region in uniqueRegions) + self.regions = newRegions + + def instantiate(self, axisLimits): + defaultDeltaArray = [] + for variations, itemCount in zip(self.tupleVarData, self.itemCounts): + defaultDeltas = instantiateTupleVariationStore(variations, axisLimits) + if not defaultDeltas: + defaultDeltas = [0] * itemCount + defaultDeltaArray.append(defaultDeltas) + + # rebuild regions whose axes were dropped or limited + self.rebuildRegions() + + pinnedAxes = set(axisLimits.pinnedLocation()) + self.axisOrder = [ + axisTag for axisTag in self.axisOrder if axisTag not in pinnedAxes + ] + + return defaultDeltaArray + + def asItemVarStore(self): + regionOrder = [frozenset(axes.items()) for axes in self.regions] + varDatas = [] + for variations, itemCount in zip(self.tupleVarData, self.itemCounts): + if variations: + assert len(variations[0].coordinates) == itemCount + varRegionIndices = [ + regionOrder.index(frozenset(var.axes.items())) for var in variations + ] + varDataItems = list(zip(*(var.coordinates for var in variations))) + varDatas.append( + builder.buildVarData(varRegionIndices, varDataItems, optimize=False) + ) + else: + varDatas.append( + builder.buildVarData([], [[] for _ in range(itemCount)]) + ) + regionList = builder.buildVarRegionList(self.regions, self.axisOrder) + itemVarStore = builder.buildVarStore(regionList, varDatas) + # remove unused regions from VarRegionList + itemVarStore.prune_regions() + return itemVarStore + + +def instantiateItemVariationStore( + itemVarStore, fvarAxes, axisLimits, hierarchical=False +): + """Compute deltas at partial location, and update varStore in-place. + + Remove regions in which all axes were instanced, or fall outside the new axis + limits. Scale the deltas of the remaining regions where only some of the axes + were instanced. + + The number of VarData subtables, and the number of items within each, are + not modified, in order to keep the existing VariationIndex valid. + One may call VarStore.optimize() method after this to further optimize those. + + Args: + varStore: An otTables.VarStore object (Item Variation Store) + fvarAxes: list of fvar's Axis objects + axisLimits: NormalizedAxisLimits: mapping axis tags to normalized + min/default/max axis coordinates. May not specify coordinates/ranges for + all the fvar axes. + + Returns: + defaultDeltas: to be added to the default instance, of type dict of floats + keyed by VariationIndex compound values: i.e. (outer << 16) + inner. + """ + tupleVarStore = _TupleVarStoreAdapter.fromItemVarStore(itemVarStore, fvarAxes) + defaultDeltaArray = tupleVarStore.instantiate(axisLimits) + newItemVarStore = tupleVarStore.asItemVarStore() + + itemVarStore.VarRegionList = newItemVarStore.VarRegionList + if not hasattr(itemVarStore, "VarDataCount"): # Happens fromXML + itemVarStore.VarDataCount = len(newItemVarStore.VarData) + assert itemVarStore.VarDataCount == newItemVarStore.VarDataCount + itemVarStore.VarData = newItemVarStore.VarData + + if not hierarchical: + defaultDeltas = { + ((major << 16) + minor): delta + for major, deltas in enumerate(defaultDeltaArray) + for minor, delta in enumerate(deltas) + } + defaultDeltas[itemVarStore.NO_VARIATION_INDEX] = 0 + else: + defaultDeltas = {0xFFFF: {0xFFFF: 0}} # NO_VARIATION_INDEX + for major, deltas in enumerate(defaultDeltaArray): + defaultDeltasForMajor = defaultDeltas.setdefault(major, {}) + for minor, delta in enumerate(deltas): + defaultDeltasForMajor[minor] = delta + return defaultDeltas + + +def instantiateOTL(varfont, axisLimits): + # TODO(anthrotype) Support partial instancing of JSTF and BASE tables + + if ( + "GDEF" not in varfont + or varfont["GDEF"].table.Version < 0x00010003 + or not varfont["GDEF"].table.VarStore + ): + return + + if "GPOS" in varfont: + msg = "Instantiating GDEF and GPOS tables" + else: + msg = "Instantiating GDEF table" + log.info(msg) + + gdef = varfont["GDEF"].table + varStore = gdef.VarStore + fvarAxes = varfont["fvar"].axes + + defaultDeltas = instantiateItemVariationStore(varStore, fvarAxes, axisLimits) + + # When VF are built, big lookups may overflow and be broken into multiple + # subtables. MutatorMerger (which inherits from AligningMerger) reattaches + # them upon instancing, in case they can now fit a single subtable (if not, + # they will be split again upon compilation). + # This 'merger' also works as a 'visitor' that traverses the OTL tables and + # calls specific methods when instances of a given type are found. + # Specifically, it adds default deltas to GPOS Anchors/ValueRecords and GDEF + # LigatureCarets, and optionally deletes all VariationIndex tables if the + # VarStore is fully instanced. + merger = MutatorMerger( + varfont, defaultDeltas, deleteVariations=(not varStore.VarRegionList.Region) + ) + merger.mergeTables(varfont, [varfont], ["GDEF", "GPOS"]) + + if varStore.VarRegionList.Region: + varIndexMapping = varStore.optimize() + gdef.remap_device_varidxes(varIndexMapping) + if "GPOS" in varfont: + varfont["GPOS"].table.remap_device_varidxes(varIndexMapping) + else: + # Downgrade GDEF. + del gdef.VarStore + gdef.Version = 0x00010002 + if gdef.MarkGlyphSetsDef is None: + del gdef.MarkGlyphSetsDef + gdef.Version = 0x00010000 + + if not ( + gdef.LigCaretList + or gdef.MarkAttachClassDef + or gdef.GlyphClassDef + or gdef.AttachList + or (gdef.Version >= 0x00010002 and gdef.MarkGlyphSetsDef) + ): + del varfont["GDEF"] + + +def _isValidAvarSegmentMap(axisTag, segmentMap): + if not segmentMap: + return True + if not {(-1.0, -1.0), (0, 0), (1.0, 1.0)}.issubset(segmentMap.items()): + log.warning( + f"Invalid avar SegmentMap record for axis '{axisTag}': does not " + "include all required value maps {-1.0: -1.0, 0: 0, 1.0: 1.0}" + ) + return False + previousValue = None + for fromCoord, toCoord in sorted(segmentMap.items()): + if previousValue is not None and previousValue > toCoord: + log.warning( + f"Invalid avar AxisValueMap({fromCoord}, {toCoord}) record " + f"for axis '{axisTag}': the toCoordinate value must be >= to " + f"the toCoordinate value of the preceding record ({previousValue})." + ) + return False + previousValue = toCoord + return True + + +def downgradeCFF2ToCFF(varfont): + # Save these properties + recalcTimestamp = varfont.recalcTimestamp + recalcBBoxes = varfont.recalcBBoxes + + # Disable them + varfont.recalcTimestamp = False + varfont.recalcBBoxes = False + + # Save to memory, reload, downgrade and save again, reload. + # We do this dance because the convertCFF2ToCFF changes glyph + # names, so following save would fail if any other table was + # loaded and referencing glyph names. + # + # The second save+load is unfortunate but also necessary. + + stream = io.BytesIO() + log.info("Saving CFF2 font to memory for downgrade") + varfont.save(stream) + stream.seek(0) + varfont = TTFont(stream, recalcTimestamp=False, recalcBBoxes=False) + + convertCFF2ToCFF(varfont) + + stream = io.BytesIO() + log.info("Saving downgraded CFF font to memory") + varfont.save(stream) + stream.seek(0) + varfont = TTFont(stream, recalcTimestamp=False, recalcBBoxes=False) + + # Uncomment, to see test all tables can be loaded. This fails without + # the extra save+load above. + """ + for tag in varfont.keys(): + print("Loading", tag) + varfont[tag] + """ + + # Restore them + varfont.recalcTimestamp = recalcTimestamp + varfont.recalcBBoxes = recalcBBoxes + + return varfont + + +def instantiateAvar(varfont, axisLimits): + # 'axisLimits' dict must contain user-space (non-normalized) coordinates. + + avar = varfont["avar"] + + segments = avar.segments + + # drop table if we instantiate all the axes + pinnedAxes = set(axisLimits.pinnedLocation()) + if pinnedAxes.issuperset(segments): + log.info("Dropping avar table") + del varfont["avar"] + return + + if getattr(avar, "majorVersion", 1) >= 2 and avar.table.VarStore: + raise NotImplementedError("avar table with VarStore is not supported") + + log.info("Instantiating avar table") + for axis in pinnedAxes: + if axis in segments: + del segments[axis] + + # First compute the default normalization for axisLimits coordinates: i.e. + # min = -1.0, default = 0, max = +1.0, and in between values interpolated linearly, + # without using the avar table's mappings. + # Then, for each SegmentMap, if we are restricting its axis, compute the new + # mappings by dividing the key/value pairs by the desired new min/max values, + # dropping any mappings that fall outside the restricted range. + # The keys ('fromCoord') are specified in default normalized coordinate space, + # whereas the values ('toCoord') are "mapped forward" using the SegmentMap. + normalizedRanges = axisLimits.normalize(varfont, usingAvar=False) + newSegments = {} + for axisTag, mapping in segments.items(): + if not _isValidAvarSegmentMap(axisTag, mapping): + continue + if mapping and axisTag in normalizedRanges: + axisRange = normalizedRanges[axisTag] + mappedMin = floatToFixedToFloat( + piecewiseLinearMap(axisRange.minimum, mapping), 14 + ) + mappedDef = floatToFixedToFloat( + piecewiseLinearMap(axisRange.default, mapping), 14 + ) + mappedMax = floatToFixedToFloat( + piecewiseLinearMap(axisRange.maximum, mapping), 14 + ) + mappedAxisLimit = NormalizedAxisTripleAndDistances( + mappedMin, + mappedDef, + mappedMax, + axisRange.distanceNegative, + axisRange.distancePositive, + ) + newMapping = {} + for fromCoord, toCoord in mapping.items(): + if fromCoord < axisRange.minimum or fromCoord > axisRange.maximum: + continue + fromCoord = axisRange.renormalizeValue(fromCoord) + + assert mappedMin <= toCoord <= mappedMax + toCoord = mappedAxisLimit.renormalizeValue(toCoord) + + fromCoord = floatToFixedToFloat(fromCoord, 14) + toCoord = floatToFixedToFloat(toCoord, 14) + newMapping[fromCoord] = toCoord + newMapping.update({-1.0: -1.0, 0.0: 0.0, 1.0: 1.0}) + newSegments[axisTag] = newMapping + else: + newSegments[axisTag] = mapping + avar.segments = newSegments + + +def isInstanceWithinAxisRanges(location, axisRanges): + for axisTag, coord in location.items(): + if axisTag in axisRanges: + axisRange = axisRanges[axisTag] + if coord < axisRange.minimum or coord > axisRange.maximum: + return False + return True + + +def instantiateFvar(varfont, axisLimits): + # 'axisLimits' dict must contain user-space (non-normalized) coordinates + + location = axisLimits.pinnedLocation() + + fvar = varfont["fvar"] + + # drop table if we instantiate all the axes + if set(location).issuperset(axis.axisTag for axis in fvar.axes): + log.info("Dropping fvar table") + del varfont["fvar"] + return + + log.info("Instantiating fvar table") + + axes = [] + for axis in fvar.axes: + axisTag = axis.axisTag + if axisTag in location: + continue + if axisTag in axisLimits: + triple = axisLimits[axisTag] + if triple.default is None: + triple = (triple.minimum, axis.defaultValue, triple.maximum) + axis.minValue, axis.defaultValue, axis.maxValue = triple + axes.append(axis) + fvar.axes = axes + + # only keep NamedInstances whose coordinates == pinned axis location + instances = [] + for instance in fvar.instances: + if any(instance.coordinates[axis] != value for axis, value in location.items()): + continue + for axisTag in location: + del instance.coordinates[axisTag] + if not isInstanceWithinAxisRanges(instance.coordinates, axisLimits): + continue + instances.append(instance) + fvar.instances = instances + + +def instantiateSTAT(varfont, axisLimits): + # 'axisLimits' dict must contain user-space (non-normalized) coordinates + + stat = varfont["STAT"].table + if not stat.DesignAxisRecord or not ( + stat.AxisValueArray and stat.AxisValueArray.AxisValue + ): + return # STAT table empty, nothing to do + + log.info("Instantiating STAT table") + newAxisValueTables = axisValuesFromAxisLimits(stat, axisLimits) + stat.AxisValueCount = len(newAxisValueTables) + if stat.AxisValueCount: + stat.AxisValueArray.AxisValue = newAxisValueTables + else: + stat.AxisValueArray = None + + +def axisValuesFromAxisLimits(stat, axisLimits): + def isAxisValueOutsideLimits(axisTag, axisValue): + if axisTag in axisLimits: + triple = axisLimits[axisTag] + if axisValue < triple.minimum or axisValue > triple.maximum: + return True + return False + + # only keep AxisValues whose axis is not pinned nor restricted, or is pinned at the + # exact (nominal) value, or is restricted but the value is within the new range + designAxes = stat.DesignAxisRecord.Axis + newAxisValueTables = [] + for axisValueTable in stat.AxisValueArray.AxisValue: + axisValueFormat = axisValueTable.Format + if axisValueFormat in (1, 2, 3): + axisTag = designAxes[axisValueTable.AxisIndex].AxisTag + if axisValueFormat == 2: + axisValue = axisValueTable.NominalValue + else: + axisValue = axisValueTable.Value + if isAxisValueOutsideLimits(axisTag, axisValue): + continue + elif axisValueFormat == 4: + # drop 'non-analytic' AxisValue if _any_ AxisValueRecord doesn't match + # the pinned location or is outside range + dropAxisValueTable = False + for rec in axisValueTable.AxisValueRecord: + axisTag = designAxes[rec.AxisIndex].AxisTag + axisValue = rec.Value + if isAxisValueOutsideLimits(axisTag, axisValue): + dropAxisValueTable = True + break + if dropAxisValueTable: + continue + else: + log.warning("Unknown AxisValue table format (%s); ignored", axisValueFormat) + newAxisValueTables.append(axisValueTable) + return newAxisValueTables + + +def setMacOverlapFlags(glyfTable): + flagOverlapCompound = _g_l_y_f.OVERLAP_COMPOUND + flagOverlapSimple = _g_l_y_f.flagOverlapSimple + for glyphName in glyfTable.keys(): + glyph = glyfTable[glyphName] + # Set OVERLAP_COMPOUND bit for compound glyphs + if glyph.isComposite(): + glyph.components[0].flags |= flagOverlapCompound + # Set OVERLAP_SIMPLE bit for simple glyphs + elif glyph.numberOfContours > 0: + glyph.flags[0] |= flagOverlapSimple + + +def normalize(value, triple, avarMapping): + value = normalizeValue(value, triple) + if avarMapping: + value = piecewiseLinearMap(value, avarMapping) + # Quantize to F2Dot14, to avoid surprise interpolations. + return floatToFixedToFloat(value, 14) + + +def sanityCheckVariableTables(varfont): + if "fvar" not in varfont: + raise ValueError("Missing required table fvar") + if "gvar" in varfont: + if "glyf" not in varfont: + raise ValueError("Can't have gvar without glyf") + + +def instantiateVariableFont( + varfont, + axisLimits, + inplace=False, + optimize=True, + overlap=OverlapMode.KEEP_AND_SET_FLAGS, + updateFontNames=False, + *, + downgradeCFF2=False, + static=False, +): + """Instantiate variable font, either fully or partially. + + Depending on whether the `axisLimits` dictionary references all or some of the + input varfont's axes, the output font will either be a full instance (static + font) or a variable font with possibly less variation data. + + Args: + varfont: a TTFont instance, which must contain at least an 'fvar' table. + axisLimits: a dict keyed by axis tags (str) containing the coordinates (float) + along one or more axes where the desired instance will be located. + If the value is `None`, the default coordinate as per 'fvar' table for + that axis is used. + The limit values can also be (min, max) tuples for restricting an + axis's variation range. The default axis value must be included in + the new range. + inplace (bool): whether to modify input TTFont object in-place instead of + returning a distinct object. + optimize (bool): if False, do not perform IUP-delta optimization on the + remaining 'gvar' table's deltas. Possibly faster, and might work around + rendering issues in some buggy environments, at the cost of a slightly + larger file size. + overlap (OverlapMode): variable fonts usually contain overlapping contours, and + some font rendering engines on Apple platforms require that the + `OVERLAP_SIMPLE` and `OVERLAP_COMPOUND` flags in the 'glyf' table be set to + force rendering using a non-zero fill rule. Thus we always set these flags + on all glyphs to maximise cross-compatibility of the generated instance. + You can disable this by passing OverlapMode.KEEP_AND_DONT_SET_FLAGS. + If you want to remove the overlaps altogether and merge overlapping + contours and components, you can pass OverlapMode.REMOVE (or + REMOVE_AND_IGNORE_ERRORS to not hard-fail on tricky glyphs). Note that this + requires the skia-pathops package (available to pip install). + The overlap parameter only has effect when generating full static instances. + updateFontNames (bool): if True, update the instantiated font's name table using + the Axis Value Tables from the STAT table. The name table and the style bits + in the head and OS/2 table will be updated so they conform to the R/I/B/BI + model. If the STAT table is missing or an Axis Value table is missing for + a given axis coordinate, a ValueError will be raised. + downgradeCFF2 (bool): if True, downgrade the CFF2 table to CFF table when possible + ie. full instancing of all axes. This is useful for compatibility with older + software that does not support CFF2. Defaults to False. Note that this + operation also removes overlaps within glyph shapes, as CFF does not support + overlaps but CFF2 does. + static (bool): if True, generate a full instance (static font) instead of a partial + instance (variable font). + """ + # 'overlap' used to be bool and is now enum; for backward compat keep accepting bool + overlap = OverlapMode(int(overlap)) + + sanityCheckVariableTables(varfont) + + if static: + unspecified = [] + for axis in varfont["fvar"].axes: + if axis.axisTag not in axisLimits: + axisLimits[axis.axisTag] = None + unspecified.append(axis.axisTag) + if unspecified: + log.info("Pinning unspecified axes to default: %s", unspecified) + + axisLimits = AxisLimits(axisLimits).limitAxesAndPopulateDefaults(varfont) + + log.info("Restricted limits: %s", axisLimits) + + normalizedLimits = axisLimits.normalize(varfont) + + log.info("Normalized limits: %s", normalizedLimits) + + if not inplace: + varfont = deepcopy(varfont) + + if "DSIG" in varfont: + del varfont["DSIG"] + + if updateFontNames: + log.info("Updating name table") + names.updateNameTable(varfont, axisLimits) + + if "VARC" in varfont: + instantiateVARC(varfont, normalizedLimits) + + if "CFF2" in varfont: + downgradeCFF2 = instantiateCFF2( + varfont, normalizedLimits, downgrade=downgradeCFF2 + ) + + if "gvar" in varfont: + instantiateGvar(varfont, normalizedLimits, optimize=optimize) + + if "cvar" in varfont: + instantiateCvar(varfont, normalizedLimits) + + if "MVAR" in varfont: + instantiateMVAR(varfont, normalizedLimits) + + if "HVAR" in varfont: + instantiateHVAR(varfont, normalizedLimits) + + if "VVAR" in varfont: + instantiateVVAR(varfont, normalizedLimits) + + instantiateOTL(varfont, normalizedLimits) + + instantiateFeatureVariations(varfont, normalizedLimits) + + if "avar" in varfont: + instantiateAvar(varfont, axisLimits) + + with names.pruningUnusedNames(varfont): + if "STAT" in varfont: + instantiateSTAT(varfont, axisLimits) + + instantiateFvar(varfont, axisLimits) + + if "OS/2" in varfont: + varfont["OS/2"].recalcAvgCharWidth(varfont) + + varLib.set_default_weight_width_slant( + varfont, location=axisLimits.defaultLocation() + ) + + if updateFontNames: + # Set Regular/Italic/Bold/Bold Italic bits as appropriate, after the + # name table has been updated. + setRibbiBits(varfont) + + if downgradeCFF2: + origVarfont = varfont + varfont = downgradeCFF2ToCFF(varfont) + if inplace: + origVarfont.__dict__ = varfont.__dict__.copy() + + if "fvar" not in varfont: + if overlap == OverlapMode.KEEP_AND_SET_FLAGS: + if "glyf" in varfont: + setMacOverlapFlags(varfont["glyf"]) + elif overlap in (OverlapMode.REMOVE, OverlapMode.REMOVE_AND_IGNORE_ERRORS): + from fontTools.ttLib.removeOverlaps import removeOverlaps + + log.info("Removing glyph outlines overlaps") + removeOverlaps( + varfont, + ignoreErrors=(overlap == OverlapMode.REMOVE_AND_IGNORE_ERRORS), + ) + + return varfont + + +def setRibbiBits(font): + """Set the `head.macStyle` and `OS/2.fsSelection` style bits + appropriately.""" + + english_ribbi_style = font["name"].getName(names.NameID.SUBFAMILY_NAME, 3, 1, 0x409) + if english_ribbi_style is None: + return + + styleMapStyleName = english_ribbi_style.toStr().lower() + if styleMapStyleName not in {"regular", "bold", "italic", "bold italic"}: + return + + if styleMapStyleName == "bold": + font["head"].macStyle = 0b01 + elif styleMapStyleName == "bold italic": + font["head"].macStyle = 0b11 + elif styleMapStyleName == "italic": + font["head"].macStyle = 0b10 + + selection = font["OS/2"].fsSelection + # First clear... + selection &= ~(1 << 0) + selection &= ~(1 << 5) + selection &= ~(1 << 6) + # ...then re-set the bits. + if styleMapStyleName == "regular": + selection |= 1 << 6 + elif styleMapStyleName == "bold": + selection |= 1 << 5 + elif styleMapStyleName == "italic": + selection |= 1 << 0 + elif styleMapStyleName == "bold italic": + selection |= 1 << 0 + selection |= 1 << 5 + font["OS/2"].fsSelection = selection + + +def parseLimits(limits: Iterable[str]) -> Dict[str, Optional[AxisTriple]]: + result = {} + for limitString in limits: + match = re.match( + r"^(\w{1,4})=(?:(drop)|(?:([^:]*)(?:[:]([^:]*))?(?:[:]([^:]*))?))$", + limitString, + ) + if not match: + raise ValueError("invalid location format: %r" % limitString) + tag = match.group(1).ljust(4) + + if match.group(2): # 'drop' + result[tag] = None + continue + + triple = match.group(3, 4, 5) + + if triple[1] is None: # "value" syntax + triple = (triple[0], triple[0], triple[0]) + elif triple[2] is None: # "min:max" syntax + triple = (triple[0], None, triple[1]) + + triple = tuple(float(v) if v else None for v in triple) + + result[tag] = AxisTriple(*triple) + + return result + + +def parseArgs(args): + """Parse argv. + + Returns: + 3-tuple (infile, axisLimits, options) + axisLimits is either a Dict[str, Optional[float]], for pinning variation axes + to specific coordinates along those axes (with `None` as a placeholder for an + axis' default value); or a Dict[str, Tuple(float, float)], meaning limit this + axis to min/max range. + Axes locations are in user-space coordinates, as defined in the "fvar" table. + """ + from fontTools import configLogger + import argparse + + parser = argparse.ArgumentParser( + "fonttools varLib.instancer", + description="Partially instantiate a variable font", + ) + parser.add_argument("input", metavar="INPUT.ttf", help="Input variable TTF file.") + parser.add_argument( + "locargs", + metavar="AXIS=LOC", + nargs="*", + help="List of space separated locations. A location consists of " + "the tag of a variation axis, followed by '=' and the literal, " + "string 'drop', or colon-separated list of one to three values, " + "each of which is the empty string, or a number. " + "E.g.: wdth=100 or wght=75.0:125.0 or wght=100:400:700 or wght=:500: " + "or wght=drop", + ) + parser.add_argument( + "-o", + "--output", + metavar="OUTPUT.ttf", + default=None, + help="Output instance TTF file (default: INPUT-instance.ttf).", + ) + parser.add_argument( + "--static", + dest="static", + action="store_true", + help="Make a static font: pin unspecified axes to their default location.", + ) + parser.add_argument( + "--no-optimize", + dest="optimize", + action="store_false", + help="Don't perform IUP optimization on the remaining gvar TupleVariations", + ) + parser.add_argument( + "--no-overlap-flag", + dest="overlap", + action="store_false", + help="Don't set OVERLAP_SIMPLE/OVERLAP_COMPOUND glyf flags (only applicable " + "when generating a full instance)", + ) + parser.add_argument( + "--remove-overlaps", + dest="remove_overlaps", + action="store_true", + help="Merge overlapping contours and components (only applicable " + "when generating a full instance). Requires skia-pathops", + ) + parser.add_argument( + "--ignore-overlap-errors", + dest="ignore_overlap_errors", + action="store_true", + help="Don't crash if the remove-overlaps operation fails for some glyphs.", + ) + parser.add_argument( + "--update-name-table", + action="store_true", + help="Update the instantiated font's `name` table. Input font must have " + "a STAT table with Axis Value Tables", + ) + parser.add_argument( + "--downgrade-cff2", + action="store_true", + help="If all axes are pinned, downgrade CFF2 to CFF table format", + ) + parser.add_argument( + "--no-recalc-timestamp", + dest="recalc_timestamp", + action="store_false", + help="Don't set the output font's timestamp to the current time.", + ) + parser.add_argument( + "--no-recalc-bounds", + dest="recalc_bounds", + action="store_false", + help="Don't recalculate font bounding boxes", + ) + loggingGroup = parser.add_mutually_exclusive_group(required=False) + loggingGroup.add_argument( + "-v", "--verbose", action="store_true", help="Run more verbosely." + ) + loggingGroup.add_argument( + "-q", "--quiet", action="store_true", help="Turn verbosity off." + ) + options = parser.parse_args(args) + + if options.remove_overlaps: + if options.ignore_overlap_errors: + options.overlap = OverlapMode.REMOVE_AND_IGNORE_ERRORS + else: + options.overlap = OverlapMode.REMOVE + else: + options.overlap = OverlapMode(int(options.overlap)) + + infile = options.input + if not os.path.isfile(infile): + parser.error("No such file '{}'".format(infile)) + + configLogger( + level=("DEBUG" if options.verbose else "ERROR" if options.quiet else "INFO") + ) + + try: + axisLimits = parseLimits(options.locargs) + except ValueError as e: + parser.error(str(e)) + + if len(axisLimits) != len(options.locargs): + parser.error("Specified multiple limits for the same axis") + + return (infile, axisLimits, options) + + +def main(args=None): + """Partially instantiate a variable font""" + infile, axisLimits, options = parseArgs(args) + log.info("Restricting axes: %s", axisLimits) + + log.info("Loading variable font") + varfont = TTFont( + infile, + recalcTimestamp=options.recalc_timestamp, + recalcBBoxes=options.recalc_bounds, + ) + + isFullInstance = options.static or { + axisTag + for axisTag, limit in axisLimits.items() + if limit is None or limit[0] == limit[2] + }.issuperset(axis.axisTag for axis in varfont["fvar"].axes) + + varfont = instantiateVariableFont( + varfont, + axisLimits, + inplace=True, + optimize=options.optimize, + overlap=options.overlap, + updateFontNames=options.update_name_table, + downgradeCFF2=options.downgrade_cff2, + static=options.static, + ) + + suffix = "-instance" if isFullInstance else "-partial" + outfile = ( + makeOutputFileName(infile, overWrite=True, suffix=suffix) + if not options.output + else options.output + ) + + log.info( + "Saving %s font %s", + "instance" if isFullInstance else "partial variable", + outfile, + ) + varfont.save(outfile) diff --git a/.venv/lib/python3.13/site-packages/fontTools/varLib/instancer/__main__.py b/.venv/lib/python3.13/site-packages/fontTools/varLib/instancer/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..64ffff2b9fdf58d8a557de7c1ae631b5c6fb4b6f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/varLib/instancer/__main__.py @@ -0,0 +1,5 @@ +import sys +from fontTools.varLib.instancer import main + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.venv/lib/python3.13/site-packages/fontTools/varLib/instancer/featureVars.py b/.venv/lib/python3.13/site-packages/fontTools/varLib/instancer/featureVars.py new file mode 100644 index 0000000000000000000000000000000000000000..d9370d9d653aa847a0ada1fae2c3869b66fa27af --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/varLib/instancer/featureVars.py @@ -0,0 +1,190 @@ +from fontTools.ttLib.tables import otTables as ot +from copy import deepcopy +import logging + + +log = logging.getLogger("fontTools.varLib.instancer") + + +def _featureVariationRecordIsUnique(rec, seen): + conditionSet = [] + conditionSets = ( + rec.ConditionSet.ConditionTable if rec.ConditionSet is not None else [] + ) + for cond in conditionSets: + if cond.Format != 1: + # can't tell whether this is duplicate, assume is unique + return True + conditionSet.append( + (cond.AxisIndex, cond.FilterRangeMinValue, cond.FilterRangeMaxValue) + ) + # besides the set of conditions, we also include the FeatureTableSubstitution + # version to identify unique FeatureVariationRecords, even though only one + # version is currently defined. It's theoretically possible that multiple + # records with same conditions but different substitution table version be + # present in the same font for backward compatibility. + recordKey = frozenset([rec.FeatureTableSubstitution.Version] + conditionSet) + if recordKey in seen: + return False + else: + seen.add(recordKey) # side effect + return True + + +def _limitFeatureVariationConditionRange(condition, axisLimit): + minValue = condition.FilterRangeMinValue + maxValue = condition.FilterRangeMaxValue + + if ( + minValue > maxValue + or minValue > axisLimit.maximum + or maxValue < axisLimit.minimum + ): + # condition invalid or out of range + return + + return tuple( + axisLimit.renormalizeValue(v, extrapolate=False) for v in (minValue, maxValue) + ) + + +def _instantiateFeatureVariationRecord( + record, recIdx, axisLimits, fvarAxes, axisIndexMap +): + applies = True + shouldKeep = False + newConditions = [] + from fontTools.varLib.instancer import NormalizedAxisTripleAndDistances + + default_triple = NormalizedAxisTripleAndDistances(-1, 0, +1) + if record.ConditionSet is None: + record.ConditionSet = ot.ConditionSet() + record.ConditionSet.ConditionTable = [] + record.ConditionSet.ConditionCount = 0 + for i, condition in enumerate(record.ConditionSet.ConditionTable): + if condition.Format == 1: + axisIdx = condition.AxisIndex + axisTag = fvarAxes[axisIdx].axisTag + + minValue = condition.FilterRangeMinValue + maxValue = condition.FilterRangeMaxValue + triple = axisLimits.get(axisTag, default_triple) + + if not (minValue <= triple.default <= maxValue): + applies = False + + # if condition not met, remove entire record + if triple.minimum > maxValue or triple.maximum < minValue: + newConditions = None + break + + if axisTag in axisIndexMap: + # remap axis index + condition.AxisIndex = axisIndexMap[axisTag] + + # remap condition limits + newRange = _limitFeatureVariationConditionRange(condition, triple) + if newRange: + # keep condition with updated limits + minimum, maximum = newRange + condition.FilterRangeMinValue = minimum + condition.FilterRangeMaxValue = maximum + shouldKeep = True + if minimum != -1 or maximum != +1: + newConditions.append(condition) + else: + # condition out of range, remove entire record + newConditions = None + break + + else: + log.warning( + "Condition table {0} of FeatureVariationRecord {1} has " + "unsupported format ({2}); ignored".format(i, recIdx, condition.Format) + ) + applies = False + newConditions.append(condition) + + if newConditions is not None and shouldKeep: + record.ConditionSet.ConditionTable = newConditions + if not newConditions: + record.ConditionSet = None + shouldKeep = True + else: + shouldKeep = False + + # Does this *always* apply? + universal = shouldKeep and not newConditions + + return applies, shouldKeep, universal + + +def _instantiateFeatureVariations(table, fvarAxes, axisLimits): + pinnedAxes = set(axisLimits.pinnedLocation()) + axisOrder = [axis.axisTag for axis in fvarAxes if axis.axisTag not in pinnedAxes] + axisIndexMap = {axisTag: axisOrder.index(axisTag) for axisTag in axisOrder} + + featureVariationApplied = False + uniqueRecords = set() + newRecords = [] + defaultsSubsts = None + + for i, record in enumerate(table.FeatureVariations.FeatureVariationRecord): + applies, shouldKeep, universal = _instantiateFeatureVariationRecord( + record, i, axisLimits, fvarAxes, axisIndexMap + ) + + if shouldKeep and _featureVariationRecordIsUnique(record, uniqueRecords): + newRecords.append(record) + + if applies and not featureVariationApplied: + assert record.FeatureTableSubstitution.Version == 0x00010000 + defaultsSubsts = deepcopy(record.FeatureTableSubstitution) + for default, rec in zip( + defaultsSubsts.SubstitutionRecord, + record.FeatureTableSubstitution.SubstitutionRecord, + ): + default.Feature = deepcopy( + table.FeatureList.FeatureRecord[rec.FeatureIndex].Feature + ) + table.FeatureList.FeatureRecord[rec.FeatureIndex].Feature = deepcopy( + rec.Feature + ) + # Set variations only once + featureVariationApplied = True + + # Further records don't have a chance to apply after a universal record + if universal: + break + + # Insert a catch-all record to reinstate the old features if necessary + if featureVariationApplied and newRecords and not universal: + defaultRecord = ot.FeatureVariationRecord() + defaultRecord.ConditionSet = ot.ConditionSet() + defaultRecord.ConditionSet.ConditionTable = [] + defaultRecord.ConditionSet.ConditionCount = 0 + defaultRecord.FeatureTableSubstitution = defaultsSubsts + + newRecords.append(defaultRecord) + + if newRecords: + table.FeatureVariations.FeatureVariationRecord = newRecords + table.FeatureVariations.FeatureVariationCount = len(newRecords) + else: + del table.FeatureVariations + # downgrade table version if there are no FeatureVariations left + table.Version = 0x00010000 + + +def instantiateFeatureVariations(varfont, axisLimits): + for tableTag in ("GPOS", "GSUB"): + if tableTag not in varfont or not getattr( + varfont[tableTag].table, "FeatureVariations", None + ): + continue + log.info("Instantiating FeatureVariations of %s table", tableTag) + _instantiateFeatureVariations( + varfont[tableTag].table, varfont["fvar"].axes, axisLimits + ) + # remove unreferenced lookups + varfont[tableTag].prune_lookups() diff --git a/.venv/lib/python3.13/site-packages/fontTools/varLib/instancer/names.py b/.venv/lib/python3.13/site-packages/fontTools/varLib/instancer/names.py new file mode 100644 index 0000000000000000000000000000000000000000..f9454688e06597b8eb984b658cd0d5d19eece601 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/varLib/instancer/names.py @@ -0,0 +1,388 @@ +"""Helpers for instantiating name table records.""" + +from contextlib import contextmanager +from copy import deepcopy +from enum import IntEnum +import re + + +class NameID(IntEnum): + FAMILY_NAME = 1 + SUBFAMILY_NAME = 2 + UNIQUE_FONT_IDENTIFIER = 3 + FULL_FONT_NAME = 4 + VERSION_STRING = 5 + POSTSCRIPT_NAME = 6 + TYPOGRAPHIC_FAMILY_NAME = 16 + TYPOGRAPHIC_SUBFAMILY_NAME = 17 + VARIATIONS_POSTSCRIPT_NAME_PREFIX = 25 + + +ELIDABLE_AXIS_VALUE_NAME = 2 + + +def getVariationNameIDs(varfont): + used = [] + if "fvar" in varfont: + fvar = varfont["fvar"] + for axis in fvar.axes: + used.append(axis.axisNameID) + for instance in fvar.instances: + used.append(instance.subfamilyNameID) + if instance.postscriptNameID != 0xFFFF: + used.append(instance.postscriptNameID) + if "STAT" in varfont: + stat = varfont["STAT"].table + for axis in stat.DesignAxisRecord.Axis if stat.DesignAxisRecord else (): + used.append(axis.AxisNameID) + for value in stat.AxisValueArray.AxisValue if stat.AxisValueArray else (): + used.append(value.ValueNameID) + elidedFallbackNameID = getattr(stat, "ElidedFallbackNameID", None) + if elidedFallbackNameID is not None: + used.append(elidedFallbackNameID) + # nameIDs <= 255 are reserved by OT spec so we don't touch them + return {nameID for nameID in used if nameID > 255} + + +@contextmanager +def pruningUnusedNames(varfont): + from . import log + + origNameIDs = getVariationNameIDs(varfont) + + yield + + log.info("Pruning name table") + exclude = origNameIDs - getVariationNameIDs(varfont) + varfont["name"].names[:] = [ + record for record in varfont["name"].names if record.nameID not in exclude + ] + if "ltag" in varfont: + # Drop the whole 'ltag' table if all the language-dependent Unicode name + # records that reference it have been dropped. + # TODO: Only prune unused ltag tags, renumerating langIDs accordingly. + # Note ltag can also be used by feat or morx tables, so check those too. + if not any( + record + for record in varfont["name"].names + if record.platformID == 0 and record.langID != 0xFFFF + ): + del varfont["ltag"] + + +def updateNameTable(varfont, axisLimits): + """Update instatiated variable font's name table using STAT AxisValues. + + Raises ValueError if the STAT table is missing or an Axis Value table is + missing for requested axis locations. + + First, collect all STAT AxisValues that match the new default axis locations + (excluding "elided" ones); concatenate the strings in design axis order, + while giving priority to "synthetic" values (Format 4), to form the + typographic subfamily name associated with the new default instance. + Finally, update all related records in the name table, making sure that + legacy family/sub-family names conform to the the R/I/B/BI (Regular, Italic, + Bold, Bold Italic) naming model. + + Example: Updating a partial variable font: + | >>> ttFont = TTFont("OpenSans[wdth,wght].ttf") + | >>> updateNameTable(ttFont, {"wght": (400, 900), "wdth": 75}) + + The name table records will be updated in the following manner: + NameID 1 familyName: "Open Sans" --> "Open Sans Condensed" + NameID 2 subFamilyName: "Regular" --> "Regular" + NameID 3 Unique font identifier: "3.000;GOOG;OpenSans-Regular" --> \ + "3.000;GOOG;OpenSans-Condensed" + NameID 4 Full font name: "Open Sans Regular" --> "Open Sans Condensed" + NameID 6 PostScript name: "OpenSans-Regular" --> "OpenSans-Condensed" + NameID 16 Typographic Family name: None --> "Open Sans" + NameID 17 Typographic Subfamily name: None --> "Condensed" + + References: + https://docs.microsoft.com/en-us/typography/opentype/spec/stat + https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-ids + """ + from . import AxisLimits, axisValuesFromAxisLimits + + if "STAT" not in varfont: + raise ValueError("Cannot update name table since there is no STAT table.") + stat = varfont["STAT"].table + if not stat.AxisValueArray: + raise ValueError("Cannot update name table since there are no STAT Axis Values") + fvar = varfont["fvar"] + + # The updated name table will reflect the new 'zero origin' of the font. + # If we're instantiating a partial font, we will populate the unpinned + # axes with their default axis values from fvar. + axisLimits = AxisLimits(axisLimits).limitAxesAndPopulateDefaults(varfont) + partialDefaults = axisLimits.defaultLocation() + fvarDefaults = {a.axisTag: a.defaultValue for a in fvar.axes} + defaultAxisCoords = AxisLimits({**fvarDefaults, **partialDefaults}) + assert all(v.minimum == v.maximum for v in defaultAxisCoords.values()) + + axisValueTables = axisValuesFromAxisLimits(stat, defaultAxisCoords) + checkAxisValuesExist(stat, axisValueTables, defaultAxisCoords.pinnedLocation()) + + # ignore "elidable" axis values, should be omitted in application font menus. + axisValueTables = [ + v for v in axisValueTables if not v.Flags & ELIDABLE_AXIS_VALUE_NAME + ] + axisValueTables = _sortAxisValues(axisValueTables) + _updateNameRecords(varfont, axisValueTables) + + +def checkAxisValuesExist(stat, axisValues, axisCoords): + seen = set() + designAxes = stat.DesignAxisRecord.Axis + hasValues = set() + for value in stat.AxisValueArray.AxisValue: + if value.Format in (1, 2, 3): + hasValues.add(designAxes[value.AxisIndex].AxisTag) + elif value.Format == 4: + for rec in value.AxisValueRecord: + hasValues.add(designAxes[rec.AxisIndex].AxisTag) + + for axisValueTable in axisValues: + axisValueFormat = axisValueTable.Format + if axisValueTable.Format in (1, 2, 3): + axisTag = designAxes[axisValueTable.AxisIndex].AxisTag + if axisValueFormat == 2: + axisValue = axisValueTable.NominalValue + else: + axisValue = axisValueTable.Value + if axisTag in axisCoords and axisValue == axisCoords[axisTag]: + seen.add(axisTag) + elif axisValueTable.Format == 4: + for rec in axisValueTable.AxisValueRecord: + axisTag = designAxes[rec.AxisIndex].AxisTag + if axisTag in axisCoords and rec.Value == axisCoords[axisTag]: + seen.add(axisTag) + + missingAxes = (set(axisCoords) - seen) & hasValues + if missingAxes: + missing = ", ".join(f"'{i}': {axisCoords[i]}" for i in missingAxes) + raise ValueError(f"Cannot find Axis Values {{{missing}}}") + + +def _sortAxisValues(axisValues): + # Sort by axis index, remove duplicates and ensure that format 4 AxisValues + # are dominant. + # The MS Spec states: "if a format 1, format 2 or format 3 table has a + # (nominal) value used in a format 4 table that also has values for + # other axes, the format 4 table, being the more specific match, is used", + # https://docs.microsoft.com/en-us/typography/opentype/spec/stat#axis-value-table-format-4 + results = [] + seenAxes = set() + # Sort format 4 axes so the tables with the most AxisValueRecords are first + format4 = sorted( + [v for v in axisValues if v.Format == 4], + key=lambda v: len(v.AxisValueRecord), + reverse=True, + ) + + for val in format4: + axisIndexes = set(r.AxisIndex for r in val.AxisValueRecord) + minIndex = min(axisIndexes) + if not seenAxes & axisIndexes: + seenAxes |= axisIndexes + results.append((minIndex, val)) + + for val in axisValues: + if val in format4: + continue + axisIndex = val.AxisIndex + if axisIndex not in seenAxes: + seenAxes.add(axisIndex) + results.append((axisIndex, val)) + + return [axisValue for _, axisValue in sorted(results)] + + +def _updateNameRecords(varfont, axisValues): + # Update nametable based on the axisValues using the R/I/B/BI model. + nametable = varfont["name"] + stat = varfont["STAT"].table + + axisValueNameIDs = [a.ValueNameID for a in axisValues] + ribbiNameIDs = [n for n in axisValueNameIDs if _isRibbi(nametable, n)] + nonRibbiNameIDs = [n for n in axisValueNameIDs if n not in ribbiNameIDs] + elidedNameID = stat.ElidedFallbackNameID + elidedNameIsRibbi = _isRibbi(nametable, elidedNameID) + + getName = nametable.getName + platforms = set((r.platformID, r.platEncID, r.langID) for r in nametable.names) + for platform in platforms: + if not all(getName(i, *platform) for i in (1, 2, elidedNameID)): + # Since no family name and subfamily name records were found, + # we cannot update this set of name Records. + continue + + subFamilyName = " ".join( + getName(n, *platform).toUnicode() for n in ribbiNameIDs + ) + if nonRibbiNameIDs: + typoSubFamilyName = " ".join( + getName(n, *platform).toUnicode() for n in axisValueNameIDs + ) + else: + typoSubFamilyName = None + + # If neither subFamilyName and typographic SubFamilyName exist, + # we will use the STAT's elidedFallbackName + if not typoSubFamilyName and not subFamilyName: + if elidedNameIsRibbi: + subFamilyName = getName(elidedNameID, *platform).toUnicode() + else: + typoSubFamilyName = getName(elidedNameID, *platform).toUnicode() + + familyNameSuffix = " ".join( + getName(n, *platform).toUnicode() for n in nonRibbiNameIDs + ) + + _updateNameTableStyleRecords( + varfont, + familyNameSuffix, + subFamilyName, + typoSubFamilyName, + *platform, + ) + + +def _isRibbi(nametable, nameID): + englishRecord = nametable.getName(nameID, 3, 1, 0x409) + return ( + True + if englishRecord is not None + and englishRecord.toUnicode() in ("Regular", "Italic", "Bold", "Bold Italic") + else False + ) + + +def _updateNameTableStyleRecords( + varfont, + familyNameSuffix, + subFamilyName, + typoSubFamilyName, + platformID=3, + platEncID=1, + langID=0x409, +): + # TODO (Marc F) It may be nice to make this part a standalone + # font renamer in the future. + nametable = varfont["name"] + platform = (platformID, platEncID, langID) + + currentFamilyName = nametable.getName( + NameID.TYPOGRAPHIC_FAMILY_NAME, *platform + ) or nametable.getName(NameID.FAMILY_NAME, *platform) + + currentStyleName = nametable.getName( + NameID.TYPOGRAPHIC_SUBFAMILY_NAME, *platform + ) or nametable.getName(NameID.SUBFAMILY_NAME, *platform) + + if not all([currentFamilyName, currentStyleName]): + raise ValueError(f"Missing required NameIDs 1 and 2 for platform {platform}") + + currentFamilyName = currentFamilyName.toUnicode() + currentStyleName = currentStyleName.toUnicode() + + nameIDs = { + NameID.FAMILY_NAME: currentFamilyName, + NameID.SUBFAMILY_NAME: subFamilyName or "Regular", + } + if typoSubFamilyName: + nameIDs[NameID.FAMILY_NAME] = f"{currentFamilyName} {familyNameSuffix}".strip() + nameIDs[NameID.TYPOGRAPHIC_FAMILY_NAME] = currentFamilyName + nameIDs[NameID.TYPOGRAPHIC_SUBFAMILY_NAME] = typoSubFamilyName + else: + # Remove previous Typographic Family and SubFamily names since they're + # no longer required + for nameID in ( + NameID.TYPOGRAPHIC_FAMILY_NAME, + NameID.TYPOGRAPHIC_SUBFAMILY_NAME, + ): + nametable.removeNames(nameID=nameID) + + newFamilyName = ( + nameIDs.get(NameID.TYPOGRAPHIC_FAMILY_NAME) or nameIDs[NameID.FAMILY_NAME] + ) + newStyleName = ( + nameIDs.get(NameID.TYPOGRAPHIC_SUBFAMILY_NAME) or nameIDs[NameID.SUBFAMILY_NAME] + ) + + nameIDs[NameID.FULL_FONT_NAME] = f"{newFamilyName} {newStyleName}" + nameIDs[NameID.POSTSCRIPT_NAME] = _updatePSNameRecord( + varfont, newFamilyName, newStyleName, platform + ) + + uniqueID = _updateUniqueIdNameRecord(varfont, nameIDs, platform) + if uniqueID: + nameIDs[NameID.UNIQUE_FONT_IDENTIFIER] = uniqueID + + for nameID, string in nameIDs.items(): + assert string, nameID + nametable.setName(string, nameID, *platform) + + if "fvar" not in varfont: + nametable.removeNames(NameID.VARIATIONS_POSTSCRIPT_NAME_PREFIX) + + +def _updatePSNameRecord(varfont, familyName, styleName, platform): + # Implementation based on Adobe Technical Note #5902 : + # https://wwwimages2.adobe.com/content/dam/acom/en/devnet/font/pdfs/5902.AdobePSNameGeneration.pdf + nametable = varfont["name"] + + family_prefix = nametable.getName( + NameID.VARIATIONS_POSTSCRIPT_NAME_PREFIX, *platform + ) + if family_prefix: + family_prefix = family_prefix.toUnicode() + else: + family_prefix = familyName + + psName = f"{family_prefix}-{styleName}" + # Remove any characters other than uppercase Latin letters, lowercase + # Latin letters, digits and hyphens. + psName = re.sub(r"[^A-Za-z0-9-]", r"", psName) + + if len(psName) > 127: + # Abbreviating the stylename so it fits within 127 characters whilst + # conforming to every vendor's specification is too complex. Instead + # we simply truncate the psname and add the required "..." + return f"{psName[:124]}..." + return psName + + +def _updateUniqueIdNameRecord(varfont, nameIDs, platform): + nametable = varfont["name"] + currentRecord = nametable.getName(NameID.UNIQUE_FONT_IDENTIFIER, *platform) + if not currentRecord: + return None + + # Check if full name and postscript name are a substring of currentRecord + for nameID in (NameID.FULL_FONT_NAME, NameID.POSTSCRIPT_NAME): + nameRecord = nametable.getName(nameID, *platform) + if not nameRecord: + continue + if nameRecord.toUnicode() in currentRecord.toUnicode(): + return currentRecord.toUnicode().replace( + nameRecord.toUnicode(), nameIDs[nameRecord.nameID] + ) + + # Create a new string since we couldn't find any substrings. + fontVersion = _fontVersion(varfont, platform) + achVendID = varfont["OS/2"].achVendID + # Remove non-ASCII characers and trailing spaces + vendor = re.sub(r"[^\x00-\x7F]", "", achVendID).strip() + psName = nameIDs[NameID.POSTSCRIPT_NAME] + return f"{fontVersion};{vendor};{psName}" + + +def _fontVersion(font, platform=(3, 1, 0x409)): + nameRecord = font["name"].getName(NameID.VERSION_STRING, *platform) + if nameRecord is None: + return f'{font["head"].fontRevision:.3f}' + # "Version 1.101; ttfautohint (v1.8.1.43-b0c9)" --> "1.101" + # Also works fine with inputs "Version 1.101" or "1.101" etc + versionNumber = nameRecord.toUnicode().split(";")[0] + return versionNumber.lstrip("Version ").strip() diff --git a/.venv/lib/python3.13/site-packages/fontTools/varLib/instancer/solver.py b/.venv/lib/python3.13/site-packages/fontTools/varLib/instancer/solver.py new file mode 100644 index 0000000000000000000000000000000000000000..ba5231b796795259f9b7a471242e142d48623b0e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/varLib/instancer/solver.py @@ -0,0 +1,309 @@ +from fontTools.varLib.models import supportScalar +from fontTools.misc.fixedTools import MAX_F2DOT14 +from functools import lru_cache + +__all__ = ["rebaseTent"] + +EPSILON = 1 / (1 << 14) + + +def _reverse_negate(v): + return (-v[2], -v[1], -v[0]) + + +def _solve(tent, axisLimit, negative=False): + axisMin, axisDef, axisMax, _distanceNegative, _distancePositive = axisLimit + lower, peak, upper = tent + + # Mirror the problem such that axisDef <= peak + if axisDef > peak: + return [ + (scalar, _reverse_negate(t) if t is not None else None) + for scalar, t in _solve( + _reverse_negate(tent), + axisLimit.reverse_negate(), + not negative, + ) + ] + # axisDef <= peak + + # case 1: The whole deltaset falls outside the new limit; we can drop it + # + # peak + # 1.........................................o.......... + # / \ + # / \ + # / \ + # / \ + # 0---|-----------|----------|-------- o o----1 + # axisMin axisDef axisMax lower upper + # + if axisMax <= lower and axisMax < peak: + return [] # No overlap + + # case 2: Only the peak and outermost bound fall outside the new limit; + # we keep the deltaset, update peak and outermost bound and and scale deltas + # by the scalar value for the restricted axis at the new limit, and solve + # recursively. + # + # |peak + # 1...............................|.o.......... + # |/ \ + # / \ + # /| \ + # / | \ + # 0--------------------------- o | o----1 + # lower | upper + # | + # axisMax + # + # Convert to: + # + # 1............................................ + # | + # o peak + # /| + # /x| + # 0--------------------------- o o upper ----1 + # lower | + # | + # axisMax + if axisMax < peak: + mult = supportScalar({"tag": axisMax}, {"tag": tent}) + tent = (lower, axisMax, axisMax) + return [(scalar * mult, t) for scalar, t in _solve(tent, axisLimit)] + + # lower <= axisDef <= peak <= axisMax + + gain = supportScalar({"tag": axisDef}, {"tag": tent}) + out = [(gain, None)] + + # First, the positive side + + # outGain is the scalar of axisMax at the tent. + outGain = supportScalar({"tag": axisMax}, {"tag": tent}) + + # Case 3a: Gain is more than outGain. The tent down-slope crosses + # the axis into negative. We have to split it into multiples. + # + # | peak | + # 1...................|.o.....|.............. + # |/x\_ | + # gain................+....+_.|.............. + # /| |y\| + # ................../.|....|..+_......outGain + # / | | | \ + # 0---|-----------o | | | o----------1 + # axisMin lower | | | upper + # | | | + # axisDef | axisMax + # | + # crossing + if gain >= outGain: + # Note that this is the branch taken if both gain and outGain are 0. + + # Crossing point on the axis. + crossing = peak + (1 - gain) * (upper - peak) + + loc = (max(lower, axisDef), peak, crossing) + scalar = 1 + + # The part before the crossing point. + out.append((scalar - gain, loc)) + + # The part after the crossing point may use one or two tents, + # depending on whether upper is before axisMax or not, in one + # case we need to keep it down to eternity. + + # Case 3a1, similar to case 1neg; just one tent needed, as in + # the drawing above. + if upper >= axisMax: + loc = (crossing, axisMax, axisMax) + scalar = outGain + + out.append((scalar - gain, loc)) + + # Case 3a2: Similar to case 2neg; two tents needed, to keep + # down to eternity. + # + # | peak | + # 1...................|.o................|... + # |/ \_ | + # gain................+....+_............|... + # /| | \xxxxxxxxxxy| + # / | | \_xxxxxyyyy| + # / | | \xxyyyyyy| + # 0---|-----------o | | o-------|--1 + # axisMin lower | | upper | + # | | | + # axisDef | axisMax + # | + # crossing + else: + # A tent's peak cannot fall on axis default. Nudge it. + if upper == axisDef: + upper += EPSILON + + # Downslope. + loc1 = (crossing, upper, axisMax) + scalar1 = 0 + + # Eternity justify. + loc2 = (upper, axisMax, axisMax) + scalar2 = 0 + + out.append((scalar1 - gain, loc1)) + out.append((scalar2 - gain, loc2)) + + else: + # Special-case if peak is at axisMax. + if axisMax == peak: + upper = peak + + # Case 3: + # We keep delta as is and only scale the axis upper to achieve + # the desired new tent if feasible. + # + # peak + # 1.....................o.................... + # / \_| + # ..................../....+_.........outGain + # / | \ + # gain..............+......|..+_............. + # /| | | \ + # 0---|-----------o | | | o----------1 + # axisMin lower| | | upper + # | | newUpper + # axisDef axisMax + # + newUpper = peak + (1 - gain) * (upper - peak) + assert axisMax <= newUpper # Because outGain > gain + # Disabled because ots doesn't like us: + # https://github.com/fonttools/fonttools/issues/3350 + if False and newUpper <= axisDef + (axisMax - axisDef) * 2: + upper = newUpper + if not negative and axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper: + # we clamp +2.0 to the max F2Dot14 (~1.99994) for convenience + upper = axisDef + (axisMax - axisDef) * MAX_F2DOT14 + assert peak < upper + + loc = (max(axisDef, lower), peak, upper) + scalar = 1 + + out.append((scalar - gain, loc)) + + # Case 4: New limit doesn't fit; we need to chop into two tents, + # because the shape of a triangle with part of one side cut off + # cannot be represented as a triangle itself. + # + # | peak | + # 1.........|......o.|.................... + # ..........|...../x\|.............outGain + # | |xxy|\_ + # | /xxxy| \_ + # | |xxxxy| \_ + # | /xxxxy| \_ + # 0---|-----|-oxxxxxx| o----------1 + # axisMin | lower | upper + # | | + # axisDef axisMax + # + else: + loc1 = (max(axisDef, lower), peak, axisMax) + scalar1 = 1 + + loc2 = (peak, axisMax, axisMax) + scalar2 = outGain + + out.append((scalar1 - gain, loc1)) + # Don't add a dirac delta! + if peak < axisMax: + out.append((scalar2 - gain, loc2)) + + # Now, the negative side + + # Case 1neg: Lower extends beyond axisMin: we chop. Simple. + # + # | |peak + # 1..................|...|.o................. + # | |/ \ + # gain...............|...+...\............... + # |x_/| \ + # |/ | \ + # _/| | \ + # 0---------------o | | o----------1 + # lower | | upper + # | | + # axisMin axisDef + # + if lower <= axisMin: + loc = (axisMin, axisMin, axisDef) + scalar = supportScalar({"tag": axisMin}, {"tag": tent}) + + out.append((scalar - gain, loc)) + + # Case 2neg: Lower is betwen axisMin and axisDef: we add two + # tents to keep it down all the way to eternity. + # + # | |peak + # 1...|...............|.o................. + # | |/ \ + # gain|...............+...\............... + # |yxxxxxxxxxxxxx/| \ + # |yyyyyyxxxxxxx/ | \ + # |yyyyyyyyyyyx/ | \ + # 0---|-----------o | o----------1 + # axisMin lower | upper + # | + # axisDef + # + else: + # A tent's peak cannot fall on axis default. Nudge it. + if lower == axisDef: + lower -= EPSILON + + # Downslope. + loc1 = (axisMin, lower, axisDef) + scalar1 = 0 + + # Eternity justify. + loc2 = (axisMin, axisMin, lower) + scalar2 = 0 + + out.append((scalar1 - gain, loc1)) + out.append((scalar2 - gain, loc2)) + + return out + + +@lru_cache(128) +def rebaseTent(tent, axisLimit): + """Given a tuple (lower,peak,upper) "tent" and new axis limits + (axisMin,axisDefault,axisMax), solves how to represent the tent + under the new axis configuration. All values are in normalized + -1,0,+1 coordinate system. Tent values can be outside this range. + + Return value is a list of tuples. Each tuple is of the form + (scalar,tent), where scalar is a multipler to multiply any + delta-sets by, and tent is a new tent for that output delta-set. + If tent value is None, that is a special deltaset that should + be always-enabled (called "gain").""" + + axisMin, axisDef, axisMax, _distanceNegative, _distancePositive = axisLimit + assert -1 <= axisMin <= axisDef <= axisMax <= +1 + + lower, peak, upper = tent + assert -2 <= lower <= peak <= upper <= +2 + + assert peak != 0 + + sols = _solve(tent, axisLimit) + + n = lambda v: axisLimit.renormalizeValue(v) + sols = [ + (scalar, (n(v[0]), n(v[1]), n(v[2])) if v is not None else None) + for scalar, v in sols + if scalar + ] + + return sols diff --git a/.venv/lib/python3.13/site-packages/fontTools/varLib/interpolatableTestStartingPoint.py b/.venv/lib/python3.13/site-packages/fontTools/varLib/interpolatableTestStartingPoint.py new file mode 100644 index 0000000000000000000000000000000000000000..e91dacf288b11f0100ab31f44ce306d5d8fba69f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/fontTools/varLib/interpolatableTestStartingPoint.py @@ -0,0 +1,107 @@ +from .interpolatableHelpers import * + + +def test_starting_point(glyph0, glyph1, ix, tolerance, matching): + if matching is None: + matching = list(range(len(glyph0.isomorphisms))) + contour0 = glyph0.isomorphisms[ix] + contour1 = glyph1.isomorphisms[matching[ix]] + m0Vectors = glyph0.greenVectors + m1Vectors = [glyph1.greenVectors[i] for i in matching] + + c0 = contour0[0] + # Next few lines duplicated below. + costs = [vdiff_hypot2_complex(c0[0], c1[0]) for c1 in contour1] + min_cost_idx, min_cost = min(enumerate(costs), key=lambda x: x[1]) + first_cost = costs[0] + proposed_point = contour1[min_cost_idx][1] + reverse = contour1[min_cost_idx][2] + + if min_cost < first_cost * tolerance: + # c0 is the first isomorphism of the m0 master + # contour1 is list of all isomorphisms of the m1 master + # + # If the two shapes are both circle-ish and slightly + # rotated, we detect wrong start point. This is for + # example the case hundreds of times in + # RobotoSerif-Italic[GRAD,opsz,wdth,wght].ttf + # + # If the proposed point is only one off from the first + # point (and not reversed), try harder: + # + # Find the major eigenvector of the covariance matrix, + # and rotate the contours by that angle. Then find the + # closest point again. If it matches this time, let it + # pass. + + num_points = len(glyph1.points[ix]) + leeway = 3 + if not reverse and ( + proposed_point <= leeway or proposed_point >= num_points - leeway + ): + # Try harder + + # Recover the covariance matrix from the GreenVectors. + # This is a 2x2 matrix. + transforms = [] + for vector in (m0Vectors[ix], m1Vectors[ix]): + meanX = vector[1] + meanY = vector[2] + stddevX = vector[3] * 0.5 + stddevY = vector[4] * 0.5 + correlation = vector[5] + if correlation: + correlation /= abs(vector[0]) + + # https://cookierobotics.com/007/ + a = stddevX * stddevX # VarianceX + c = stddevY * stddevY # VarianceY + b = correlation * stddevX * stddevY # Covariance + + delta = (((a - c) * 0.5) ** 2 + b * b) ** 0.5 + lambda1 = (a + c) * 0.5 + delta # Major eigenvalue + lambda2 = (a + c) * 0.5 - delta # Minor eigenvalue + theta = atan2(lambda1 - a, b) if b != 0 else (pi * 0.5 if a < c else 0) + trans = Transform() + # Don't translate here. We are working on the complex-vector + # that includes more than just the points. It's horrible what + # we are doing anyway... + # trans = trans.translate(meanX, meanY) + trans = trans.rotate(theta) + trans = trans.scale(sqrt(lambda1), sqrt(lambda2)) + transforms.append(trans) + + trans = transforms[0] + new_c0 = ( + [complex(*trans.transformPoint((pt.real, pt.imag))) for pt in c0[0]], + ) + c0[1:] + trans = transforms[1] + new_contour1 = [] + for c1 in contour1: + new_c1 = ( + [ + complex(*trans.transformPoint((pt.real, pt.imag))) + for pt in c1[0] + ], + ) + c1[1:] + new_contour1.append(new_c1) + + # Next few lines duplicate from above. + costs = [ + vdiff_hypot2_complex(new_c0[0], new_c1[0]) for new_c1 in new_contour1 + ] + min_cost_idx, min_cost = min(enumerate(costs), key=lambda x: x[1]) + first_cost = costs[0] + if min_cost < first_cost * tolerance: + # Don't report this + # min_cost = first_cost + # reverse = False + # proposed_point = 0 # new_contour1[min_cost_idx][1] + pass + + this_tolerance = min_cost / first_cost if first_cost else 1 + log.debug( + "test-starting-point: tolerance %g", + this_tolerance, + ) + return this_tolerance, proposed_point, reverse diff --git a/.venv/lib/python3.13/site-packages/google_generativeai-0.8.6-py3.13-nspkg.pth b/.venv/lib/python3.13/site-packages/google_generativeai-0.8.6-py3.13-nspkg.pth new file mode 100644 index 0000000000000000000000000000000000000000..e01f0bedec6e7bb009ca58b678fb86bc3cd37e3c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/google_generativeai-0.8.6-py3.13-nspkg.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:492187369ed89466a43eca61c645a6d1f2a0de9ceb7d0611438d993ed88f17ee +size 467 diff --git a/.venv/lib/python3.13/site-packages/lupa/lua51.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/lupa/lua51.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..2d8c98ac84e57fb0b23384f51b4ffae8cac0e6ed --- /dev/null +++ b/.venv/lib/python3.13/site-packages/lupa/lua51.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9fa2883e4ea22d45e1ecefe39d2461fa5daef1ce5efeef902dece638dba39eb9 +size 578328 diff --git a/.venv/lib/python3.13/site-packages/lupa/lua52.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/lupa/lua52.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..ecc92aabca847d843c2f8e5c14c86d463639ae18 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/lupa/lua52.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56c825e1b95d182ad7a1d6068eb8b1390799db8f90f7c8a641b34db10ad40d7f +size 603032 diff --git a/.venv/lib/python3.13/site-packages/lupa/lua53.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/lupa/lua53.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..a7644ff0e48def4fcbb2788ef7737a4e5fd56dad --- /dev/null +++ b/.venv/lib/python3.13/site-packages/lupa/lua53.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0bf57e1ce41a974ed22bc5802522b22ed73c4dc0d0a162225e3fd6c3fbf7d5a +size 639864 diff --git a/.venv/lib/python3.13/site-packages/lupa/lua54.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/lupa/lua54.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..c0edef6a307574025a7bc9776ce7c029dd4691d6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/lupa/lua54.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ff18f2b7101a8bec5f302e004f78ff751e7d291d6fa453a4d04f767297553fa +size 693144 diff --git a/.venv/lib/python3.13/site-packages/lupa/luajit20.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/lupa/luajit20.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..61143e555b6c5c6becb0a3cc53c0dbcf35b14b26 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/lupa/luajit20.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba9ba20531352a891f928fda333ffe3df9f3bf0ba76ec71bac70d217dfa729c6 +size 1008360 diff --git a/.venv/lib/python3.13/site-packages/lupa/luajit21.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/lupa/luajit21.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..c6ae92792309635d176b8677648004623d805143 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/lupa/luajit21.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:732e1065376410f44fcdba04b191baca04883a7b130536761278a9c7bbc0c75e +size 1127400 diff --git a/.venv/lib/python3.13/site-packages/lxml/_elementpath.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/lxml/_elementpath.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..2c85386b770429fde9916c2e76b75689948ccfbc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/lxml/_elementpath.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74ac34e3d564f6ce111307cad2c9f0fc6b354c2c2d7d9d9757e2c5d0e232394e +size 217352 diff --git a/.venv/lib/python3.13/site-packages/lxml/builder.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/lxml/builder.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..fed964416a2d4175ce3ce52b9134333a8bec6c5a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/lxml/builder.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea1db3822e9c8845d09f33cf5548382cea47995c58bc3717745a9c7ef72e5684 +size 129112 diff --git a/.venv/lib/python3.13/site-packages/lxml/etree.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/lxml/etree.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..fac264222e06fb4a8ff0552b4d79ab169cf5654a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/lxml/etree.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc6a3cdc5d7768b5a7a6b75890ad88612ed8646ed4df49fa4289517a81f427bc +size 5362288 diff --git a/.venv/lib/python3.13/site-packages/lxml/objectify.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/lxml/objectify.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..0eddae12bd87779db9de83eb70f3154c3a32c004 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/lxml/objectify.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cef29d07a4eeb341e55b30a3e8667867f963dd3ee209648ac64dc395abf2dac7 +size 2937240 diff --git a/.venv/lib/python3.13/site-packages/lxml/sax.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/lxml/sax.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..5bf9d3793ef0bfe57f891dc905aa8d43449c73f4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/lxml/sax.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2156e8823559eb72313dc564b5f1f288040627b6961b7426b4c239a982eed4e +size 186176 diff --git a/.venv/lib/python3.13/site-packages/matplotlib/_c_internal_utils.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/matplotlib/_c_internal_utils.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..74f142f569996d0a685200a1354923ec983fc6b9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/matplotlib/_c_internal_utils.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3b3aae950391cc30edd6717359e2c2a4a2f082bb771c68cb199c80580aa9bdf1 +size 277520 diff --git a/.venv/lib/python3.13/site-packages/matplotlib/_image.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/matplotlib/_image.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..47dede30741ba53929c7e9c75369aa70ecea6ad7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/matplotlib/_image.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:385e253ef168d022b60bb405171a6994bb5d5cded2ad5de05e13da770e84cfe8 +size 587408 diff --git a/.venv/lib/python3.13/site-packages/matplotlib/_path.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/matplotlib/_path.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..5ac60cc0aec80c98647d934ddde19c06b23bf0b0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/matplotlib/_path.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:770c6f294ef2762931d3e36b7a13b1608f1a0d217e753af8f9db3c3301f6299a +size 512968 diff --git a/.venv/lib/python3.13/site-packages/matplotlib/_qhull.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/matplotlib/_qhull.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..96801ea5acaf8c6f2f2de0c89c289d5b7aefa5ff --- /dev/null +++ b/.venv/lib/python3.13/site-packages/matplotlib/_qhull.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f331795d02e715317d0ff9d48d0c27fc8ea9028f4831763cc2c4232b99899cb +size 774656 diff --git a/.venv/lib/python3.13/site-packages/matplotlib/_tri.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/matplotlib/_tri.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..c08ef44937d9f65a3ef01489d4856161b4639ade --- /dev/null +++ b/.venv/lib/python3.13/site-packages/matplotlib/_tri.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e579d7545c57e84ad3819d5c71528a4bdaa2e25e4b38296d5891ccbfd8af740 +size 442920 diff --git a/.venv/lib/python3.13/site-packages/matplotlib/ft2font.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/matplotlib/ft2font.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..8c00146b2bcec2f6e36d5a695ebcb3b5a495d893 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/matplotlib/ft2font.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b306f8e71804cdeb2a3c658e1320c6e1a5e6d149ae8c2f3545fd5dae3c0fb24a +size 1435472 diff --git a/.venv/lib/python3.13/site-packages/pillow.libs/libavif-01e67780.so.16.3.0 b/.venv/lib/python3.13/site-packages/pillow.libs/libavif-01e67780.so.16.3.0 new file mode 100644 index 0000000000000000000000000000000000000000..03731923ccfebc6f840404c3e11fbb1a01b03ea5 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pillow.libs/libavif-01e67780.so.16.3.0 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c425e503cfeb820cec080fc4b16285ce0a8f0664f58a1a590a8de2332bc3d4fd +size 5142057 diff --git a/.venv/lib/python3.13/site-packages/pillow.libs/libbrotlicommon-c55a5f7a.so.1.1.0 b/.venv/lib/python3.13/site-packages/pillow.libs/libbrotlicommon-c55a5f7a.so.1.1.0 new file mode 100644 index 0000000000000000000000000000000000000000..0ef430e693219748841bfcc2f182573048786f1a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pillow.libs/libbrotlicommon-c55a5f7a.so.1.1.0 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1da2db326dd87a15fbe7dc2017b654d2457085d817e2e91fbd034acada1aaf0f +size 144425 diff --git a/.venv/lib/python3.13/site-packages/pillow.libs/libfreetype-083ff72c.so.6.20.2 b/.venv/lib/python3.13/site-packages/pillow.libs/libfreetype-083ff72c.so.6.20.2 new file mode 100644 index 0000000000000000000000000000000000000000..bacdbede163f1188ca1a6f5931dff95fe5b2ed8c --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pillow.libs/libfreetype-083ff72c.so.6.20.2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d1ed08fcbc7998985a8f2ae755fee5888c6dcda18dd91081aac92b81dc5c62d +size 1430825 diff --git a/.venv/lib/python3.13/site-packages/pillow.libs/libharfbuzz-fe5b8f8d.so.0.61121.0 b/.venv/lib/python3.13/site-packages/pillow.libs/libharfbuzz-fe5b8f8d.so.0.61121.0 new file mode 100644 index 0000000000000000000000000000000000000000..ae6d2a580a5a7d071a432e78a40185fd26f7696f --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pillow.libs/libharfbuzz-fe5b8f8d.so.0.61121.0 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ec1618623334334acdc44a35775caaa92a0e18b09c6ecf89aa2d4a5aac6fa263 +size 908081 diff --git a/.venv/lib/python3.13/site-packages/pillow.libs/libjpeg-8a13c6e0.so.62.4.0 b/.venv/lib/python3.13/site-packages/pillow.libs/libjpeg-8a13c6e0.so.62.4.0 new file mode 100644 index 0000000000000000000000000000000000000000..a7ccb12c68691e641d0fdfcd1d0ccb32bdd2d12e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pillow.libs/libjpeg-8a13c6e0.so.62.4.0 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2fd2cd3b79617a40ff920815e83ae0b25788fe05df97711f5b0029891c31cbd9 +size 832177 diff --git a/.venv/lib/python3.13/site-packages/pillow.libs/liblcms2-cc10e42f.so.2.0.17 b/.venv/lib/python3.13/site-packages/pillow.libs/liblcms2-cc10e42f.so.2.0.17 new file mode 100644 index 0000000000000000000000000000000000000000..14890ce029d018e642384ff45769f23e206ecd86 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pillow.libs/liblcms2-cc10e42f.so.2.0.17 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e4932310354a330c5c8a785b425eaa8512da7b30224056043d2cfe2ae96d1ded +size 519073 diff --git a/.venv/lib/python3.13/site-packages/pillow.libs/liblzma-64b7ab39.so.5.8.1 b/.venv/lib/python3.13/site-packages/pillow.libs/liblzma-64b7ab39.so.5.8.1 new file mode 100644 index 0000000000000000000000000000000000000000..ae7fa8d9cc6056ed01fa9027ae016ec300bef3b2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pillow.libs/liblzma-64b7ab39.so.5.8.1 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84dd81d913c433ac0e82f111fe0e377cd8db350fd2b2b7a75f6c2501f1d6fa70 +size 266369 diff --git a/.venv/lib/python3.13/site-packages/pillow.libs/libopenjp2-56811f71.so.2.5.3 b/.venv/lib/python3.13/site-packages/pillow.libs/libopenjp2-56811f71.so.2.5.3 new file mode 100644 index 0000000000000000000000000000000000000000..9b76f1e56aac052f8e797ab420dac563359fc4e1 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pillow.libs/libopenjp2-56811f71.so.2.5.3 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:686f62cbed321379e3e38be7ae94c56411d4345bde8d54e557b40472d9a7693a +size 585849 diff --git a/.venv/lib/python3.13/site-packages/pillow.libs/libpng16-d00bd151.so.16.49.0 b/.venv/lib/python3.13/site-packages/pillow.libs/libpng16-d00bd151.so.16.49.0 new file mode 100644 index 0000000000000000000000000000000000000000..72bc1097c1ff23ca88b863d9fc0bd6e3653f98d4 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pillow.libs/libpng16-d00bd151.so.16.49.0 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:558882880a0307a7675a595b712a4ebbd0eb1ca4374e1e2d7a9896761760fe6c +size 278001 diff --git a/.venv/lib/python3.13/site-packages/pillow.libs/libtiff-13a02c81.so.6.1.0 b/.venv/lib/python3.13/site-packages/pillow.libs/libtiff-13a02c81.so.6.1.0 new file mode 100644 index 0000000000000000000000000000000000000000..ed5803bd15b9edccbb282f05b3ab2a0f7f93056e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pillow.libs/libtiff-13a02c81.so.6.1.0 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:007f36ed9297e1fffe0e962feba0442dcce486455d6cd98b2c58a57bcbd15605 +size 746233 diff --git a/.venv/lib/python3.13/site-packages/pillow.libs/libwebp-5f0275c0.so.7.1.10 b/.venv/lib/python3.13/site-packages/pillow.libs/libwebp-5f0275c0.so.7.1.10 new file mode 100644 index 0000000000000000000000000000000000000000..ce3b4688a3cf83c9d3db9d1b094dba04ff3d178e --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pillow.libs/libwebp-5f0275c0.so.7.1.10 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b3a3778927251e1ae485268cfdc16a93b20066b59ed698069b0264fb0ce14989 +size 731185 diff --git a/.venv/lib/python3.13/site-packages/pillow.libs/libxcb-64009ff3.so.1.1.0 b/.venv/lib/python3.13/site-packages/pillow.libs/libxcb-64009ff3.so.1.1.0 new file mode 100644 index 0000000000000000000000000000000000000000..50d8dbbeb6524f9a4679c30c15c56df5fca4d606 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pillow.libs/libxcb-64009ff3.so.1.1.0 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7437ed16bae7ac4498049fd14e10d1bd1c3e7d15d0e5eab1d2ead42a83a49d1 +size 251425 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_acero.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_acero.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..4d9148eca6ad93272c056dfe4c6ba39ad9679b1b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_acero.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb92be418d3fbd8bae626ab13c5cb7715d902464c4004747e19089ea499fe3dc +size 287168 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_azurefs.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_azurefs.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..4f2ad0e021b5ddc647343781299beba19db03cf2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_azurefs.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:508330b9f4b17ca325c9f6d6044ea10449a6b459a90c41630dbe66c1c196839c +size 139320 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_compute.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_compute.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..10585aeba5ffd4bca14800c2a531994c06f35535 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_compute.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f065dff867538a0edfe364b4634e1fc4d0f486ee6f381540f8da022706cc516 +size 1293312 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_csv.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_csv.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..00c0f942dc9e219e2a9e94c8d9856abd2cf40117 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_csv.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9170eac7e0243a408dc91122a39919681d2df9fb8800e220a8b479bce2c81565 +size 357816 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_dataset.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_dataset.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..75d5cd120a86ad97c7a075a60f9e2ece980a6d72 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_dataset.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:88bf759f31d9e53bef70adbdccc48574d7bbd07f154f68655515cc7d4e659217 +size 988984 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_dataset_parquet.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_dataset_parquet.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..f318d14dc9dd2b368e10757c5f7a99cfccceeaf7 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_dataset_parquet.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d90500be05c0b11b962c55cf1a628aaf18aac34c23cce5fd7378312cbdb19a0a +size 360296 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_dataset_parquet_encryption.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_dataset_parquet_encryption.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..4acd660d1698a792426c6767eab5a5cc588a62bc --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_dataset_parquet_encryption.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7aa5c7ad0e766efb55a491171965328b89ff971ef935d576daecec1e58c84e90 +size 120064 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_feather.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_feather.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..282d3c2d85c2110929f7741d7bd4b76b190e69d9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_feather.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0005d33f44b02ab657a73bc9358c2a9172053cd6951bc01403baa2685f9e588a +size 112392 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_flight.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_flight.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..4c564bf4cf441fe6c7d2925d0ef3bb76c7325d0a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_flight.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1842f80d28701ae9597263728a9e7a4d88c6d3a10fa30a262d5e35f41373ca4f +size 1201464 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_gcsfs.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_gcsfs.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..a04c74409952060c9338b36600b712a3d48142d6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_gcsfs.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aedab1aaf103f4d7de0a5c985bffe9ba4066005dacabb914d57c4c23d2c7ab57 +size 133576 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_hdfs.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_hdfs.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..b3f1435932ffc250a5aeb327acf73c3042ee487b --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_hdfs.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de32d0300960385a075090ea03a539d2dd33783e0939c53204640fbbf872e06e +size 138192 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_json.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_json.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..51dbbc18b7be262520294b11c526caba3fc8b56d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_json.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f67735f7762380e271637fad06a3d015430d4907b0407b3a3678cdf46b2cdd1e +size 133376 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_orc.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_orc.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..63073dcceea7c9b243893163e11299a3024c0c67 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_orc.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08e63bdd1f8580ccf631cdfb4f906757263548ea1f4204b0a2fd10803b05321e +size 211560 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_parquet.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_parquet.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..2943cd85e5b353e0a7e5a9be76daa64464711254 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_parquet.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:943c61d0d0e8f99c486c5259e98f62280b2050f431da25e86eaa1eefc623b21a +size 627832 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_parquet_encryption.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_parquet_encryption.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..94cb2f0c8d6186e490859b76d43e3115f2870a1a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_parquet_encryption.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:386722e0066822e96084b4d635da4e7a97729c25cee0aeb3c8733d0b4d126809 +size 335512 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_s3fs.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_s3fs.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..a329c3969bccd972f2a44ab90ed67c22e19fd662 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_s3fs.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a60595fdf78240392241eaab31fe81cb61b337924f5b8f769ebf76c871355cc1 +size 209064 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/_substrait.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/_substrait.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..018b514d98992dec9e52d5ee0a088e786040ec09 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/_substrait.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:147183fdd50c25e4f85ac8a13455c2bf060472844f428775a95819e4e3aa8810 +size 203472 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/lib.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/pyarrow/lib.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..e6a18be6d56cd9af84a81c0078ded20c3a460ac2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/lib.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82d8829515bc0527774793274b81b0096692847876f8b50a19c8e934ad116798 +size 4389392 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/libarrow_acero.so.2300 b/.venv/lib/python3.13/site-packages/pyarrow/libarrow_acero.so.2300 new file mode 100644 index 0000000000000000000000000000000000000000..a1ea8ef64d093c2b2d665e73a3466e41f33a1eb9 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/libarrow_acero.so.2300 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e9b2a0a32fc169d5d88a08d7c91f916f67355f7fd2acfe396ff4513389ce13e +size 1899056 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/libarrow_dataset.so.2300 b/.venv/lib/python3.13/site-packages/pyarrow/libarrow_dataset.so.2300 new file mode 100644 index 0000000000000000000000000000000000000000..5250b502245662755006bcd27c36bac87186eea0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/libarrow_dataset.so.2300 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2918112cd192ba108a8ea76a3dd2183b0d2fa3328a22a0c70b9aea05b8f39675 +size 2331344 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/libarrow_python.so b/.venv/lib/python3.13/site-packages/pyarrow/libarrow_python.so new file mode 100644 index 0000000000000000000000000000000000000000..2f07e103c99091714f326c66a86b1244f0554f61 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/libarrow_python.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cb586044d566dd46db5e559ec9df15ecbc4ee3c024354c24b20429ba3662eda +size 2345152 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/libarrow_python.so.2300 b/.venv/lib/python3.13/site-packages/pyarrow/libarrow_python.so.2300 new file mode 100644 index 0000000000000000000000000000000000000000..2f07e103c99091714f326c66a86b1244f0554f61 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/libarrow_python.so.2300 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cb586044d566dd46db5e559ec9df15ecbc4ee3c024354c24b20429ba3662eda +size 2345152 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/libarrow_python.so.2300.1.0 b/.venv/lib/python3.13/site-packages/pyarrow/libarrow_python.so.2300.1.0 new file mode 100644 index 0000000000000000000000000000000000000000..2f07e103c99091714f326c66a86b1244f0554f61 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/libarrow_python.so.2300.1.0 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cb586044d566dd46db5e559ec9df15ecbc4ee3c024354c24b20429ba3662eda +size 2345152 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/libarrow_python_flight.so.2300 b/.venv/lib/python3.13/site-packages/pyarrow/libarrow_python_flight.so.2300 new file mode 100644 index 0000000000000000000000000000000000000000..1fa9a57afc0b79cf36cac8018e82c3b84da235d8 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/libarrow_python_flight.so.2300 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82f5299b45afb89351ded9ae712d2a0a52a8b5a1212710978046e08e99b23794 +size 104024 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/libarrow_python_flight.so.2300.1.0 b/.venv/lib/python3.13/site-packages/pyarrow/libarrow_python_flight.so.2300.1.0 new file mode 100644 index 0000000000000000000000000000000000000000..1fa9a57afc0b79cf36cac8018e82c3b84da235d8 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/libarrow_python_flight.so.2300.1.0 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82f5299b45afb89351ded9ae712d2a0a52a8b5a1212710978046e08e99b23794 +size 104024 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/libarrow_substrait.so.2300 b/.venv/lib/python3.13/site-packages/pyarrow/libarrow_substrait.so.2300 new file mode 100644 index 0000000000000000000000000000000000000000..57cf81739101aa3300057beb0a77330640fb4df6 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/libarrow_substrait.so.2300 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:441a5d7750bc07db39b7bc0372bf3f38e7b7e2a11c5b8e6bd3e83534ee5a5eea +size 5761616 diff --git a/.venv/lib/python3.13/site-packages/pyarrow/libparquet.so.2300 b/.venv/lib/python3.13/site-packages/pyarrow/libparquet.so.2300 new file mode 100644 index 0000000000000000000000000000000000000000..476e6f382e85f26c07803931236c46443b030423 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/pyarrow/libparquet.so.2300 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05464db9f29f3e3c72bda50625b2c3ae15931b2a75dfea352a08400da4f1a14f +size 12416216 diff --git a/.venv/lib/python3.13/site-packages/referencing-0.36.2.dist-info/licenses/COPYING b/.venv/lib/python3.13/site-packages/referencing-0.36.2.dist-info/licenses/COPYING new file mode 100644 index 0000000000000000000000000000000000000000..a9f853e43069b8e3f8a156a4af2b1198a004230d --- /dev/null +++ b/.venv/lib/python3.13/site-packages/referencing-0.36.2.dist-info/licenses/COPYING @@ -0,0 +1,19 @@ +Copyright (c) 2022 Julian Berman + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/.venv/lib/python3.13/site-packages/rpds/rpds.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/rpds/rpds.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..5040eca2b0840121708e0c4f29a9f4ce32a8c840 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/rpds/rpds.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee9c73db7e52323db7b9fd81339a9baac5bac66624cdb51508934ae61d270087 +size 1061360 diff --git a/.venv/lib/python3.13/site-packages/tqdm/__pycache__/__init__.cpython-313.pyc b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..747f7fd39c5d09d0bafafeec4c2e7e1952ef0644 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/__init__.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/tqdm/__pycache__/_dist_ver.cpython-313.pyc b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/_dist_ver.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c3457194cac27da300a7e8975fb20cab6238e321 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/_dist_ver.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/tqdm/__pycache__/_monitor.cpython-313.pyc b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/_monitor.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aaecba068a6fc22ffe568fd84c1851712d6d111a Binary files /dev/null and b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/_monitor.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/tqdm/__pycache__/_tqdm_pandas.cpython-313.pyc b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/_tqdm_pandas.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a7ed1e04435acc3f926ca02daaed55c3d757f2ea Binary files /dev/null and b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/_tqdm_pandas.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/tqdm/__pycache__/asyncio.cpython-313.pyc b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/asyncio.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..edb22f5601db4e1879e1c3b6aaeb0530309c74a3 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/asyncio.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/tqdm/__pycache__/auto.cpython-313.pyc b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/auto.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ee84baa3e5657bdbd55bb68d1f79774389171a09 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/auto.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/tqdm/__pycache__/autonotebook.cpython-313.pyc b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/autonotebook.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be17bd9ffebf976fa77f0ed8f8c94a3166648c5c Binary files /dev/null and b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/autonotebook.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/tqdm/__pycache__/cli.cpython-313.pyc b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/cli.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8cfbfc9014ed0907c2e0d1332b23a543911e5ec2 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/cli.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/tqdm/__pycache__/gui.cpython-313.pyc b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/gui.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dac98c9954b8316ae1d254e8d6d2b2b4a3bcf145 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/gui.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/tqdm/__pycache__/std.cpython-313.pyc b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/std.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c2a46ad7f669d15546931b5a3f581779b6783fb7 Binary files /dev/null and b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/std.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/tqdm/__pycache__/utils.cpython-313.pyc b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/utils.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6a2683bc73eefb8fab5b55a6cefa3921c5b10a2f Binary files /dev/null and b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/utils.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/tqdm/__pycache__/version.cpython-313.pyc b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/version.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d70b67e7661f61b41483b8cd272863271b1a7b0c Binary files /dev/null and b/.venv/lib/python3.13/site-packages/tqdm/__pycache__/version.cpython-313.pyc differ diff --git a/.venv/lib/python3.13/site-packages/tqdm/contrib/__init__.py b/.venv/lib/python3.13/site-packages/tqdm/contrib/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d059461f91fb79115263c16314c3487e16ab98c2 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/tqdm/contrib/__init__.py @@ -0,0 +1,92 @@ +""" +Thin wrappers around common functions. + +Subpackages contain potentially unstable extensions. +""" +from warnings import warn + +from ..auto import tqdm as tqdm_auto +from ..std import TqdmDeprecationWarning, tqdm +from ..utils import ObjectWrapper + +__author__ = {"github.com/": ["casperdcl"]} +__all__ = ['tenumerate', 'tzip', 'tmap'] + + +class DummyTqdmFile(ObjectWrapper): + """Dummy file-like that will write to tqdm""" + + def __init__(self, wrapped): + super().__init__(wrapped) + self._buf = [] + + def write(self, x, nolock=False): + nl = b"\n" if isinstance(x, bytes) else "\n" + pre, sep, post = x.rpartition(nl) + if sep: + blank = type(nl)() + tqdm.write(blank.join(self._buf + [pre, sep]), + end=blank, file=self._wrapped, nolock=nolock) + self._buf = [post] + else: + self._buf.append(x) + + def __del__(self): + if self._buf: + blank = type(self._buf[0])() + try: + tqdm.write(blank.join(self._buf), end=blank, file=self._wrapped) + except (OSError, ValueError): + pass + + +def builtin_iterable(func): + """Returns `func`""" + warn("This function has no effect, and will be removed in tqdm==5.0.0", + TqdmDeprecationWarning, stacklevel=2) + return func + + +def tenumerate(iterable, start=0, total=None, tqdm_class=tqdm_auto, **tqdm_kwargs): + """ + Equivalent of `numpy.ndenumerate` or builtin `enumerate`. + + Parameters + ---------- + tqdm_class : [default: tqdm.auto.tqdm]. + """ + try: + import numpy as np + except ImportError: + pass + else: + if isinstance(iterable, np.ndarray): + return tqdm_class(np.ndenumerate(iterable), total=total or iterable.size, + **tqdm_kwargs) + return enumerate(tqdm_class(iterable, total=total, **tqdm_kwargs), start) + + +def tzip(iter1, *iter2plus, **tqdm_kwargs): + """ + Equivalent of builtin `zip`. + + Parameters + ---------- + tqdm_class : [default: tqdm.auto.tqdm]. + """ + kwargs = tqdm_kwargs.copy() + tqdm_class = kwargs.pop("tqdm_class", tqdm_auto) + for i in zip(tqdm_class(iter1, **kwargs), *iter2plus): + yield i + + +def tmap(function, *sequences, **tqdm_kwargs): + """ + Equivalent of builtin `map`. + + Parameters + ---------- + tqdm_class : [default: tqdm.auto.tqdm]. + """ + for i in tzip(*sequences, **tqdm_kwargs): + yield function(*i) diff --git a/.venv/lib/python3.13/site-packages/tqdm/contrib/bells.py b/.venv/lib/python3.13/site-packages/tqdm/contrib/bells.py new file mode 100644 index 0000000000000000000000000000000000000000..5b8f4b9ecd894f1edfaa08d9fe730b8d7c8b93e0 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/tqdm/contrib/bells.py @@ -0,0 +1,26 @@ +""" +Even more features than `tqdm.auto` (all the bells & whistles): + +- `tqdm.auto` +- `tqdm.tqdm.pandas` +- `tqdm.contrib.telegram` + + uses `${TQDM_TELEGRAM_TOKEN}` and `${TQDM_TELEGRAM_CHAT_ID}` +- `tqdm.contrib.discord` + + uses `${TQDM_DISCORD_TOKEN}` and `${TQDM_DISCORD_CHANNEL_ID}` +""" +__all__ = ['tqdm', 'trange'] +import warnings +from os import getenv + +if getenv("TQDM_SLACK_TOKEN") and getenv("TQDM_SLACK_CHANNEL"): + from .slack import tqdm, trange +elif getenv("TQDM_TELEGRAM_TOKEN") and getenv("TQDM_TELEGRAM_CHAT_ID"): + from .telegram import tqdm, trange +elif getenv("TQDM_DISCORD_TOKEN") and getenv("TQDM_DISCORD_CHANNEL_ID"): + from .discord import tqdm, trange +else: + from ..auto import tqdm, trange + +with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=FutureWarning) + tqdm.pandas() diff --git a/.venv/lib/python3.13/site-packages/tqdm/contrib/concurrent.py b/.venv/lib/python3.13/site-packages/tqdm/contrib/concurrent.py new file mode 100644 index 0000000000000000000000000000000000000000..cd81d622a1309df179042159a56cef4f8c309224 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/tqdm/contrib/concurrent.py @@ -0,0 +1,105 @@ +""" +Thin wrappers around `concurrent.futures`. +""" +from contextlib import contextmanager +from operator import length_hint +from os import cpu_count + +from ..auto import tqdm as tqdm_auto +from ..std import TqdmWarning + +__author__ = {"github.com/": ["casperdcl"]} +__all__ = ['thread_map', 'process_map'] + + +@contextmanager +def ensure_lock(tqdm_class, lock_name=""): + """get (create if necessary) and then restore `tqdm_class`'s lock""" + old_lock = getattr(tqdm_class, '_lock', None) # don't create a new lock + lock = old_lock or tqdm_class.get_lock() # maybe create a new lock + lock = getattr(lock, lock_name, lock) # maybe subtype + tqdm_class.set_lock(lock) + yield lock + if old_lock is None: + del tqdm_class._lock + else: + tqdm_class.set_lock(old_lock) + + +def _executor_map(PoolExecutor, fn, *iterables, **tqdm_kwargs): + """ + Implementation of `thread_map` and `process_map`. + + Parameters + ---------- + tqdm_class : [default: tqdm.auto.tqdm]. + max_workers : [default: min(32, cpu_count() + 4)]. + chunksize : [default: 1]. + lock_name : [default: "":str]. + """ + kwargs = tqdm_kwargs.copy() + if "total" not in kwargs: + kwargs["total"] = length_hint(iterables[0]) + tqdm_class = kwargs.pop("tqdm_class", tqdm_auto) + max_workers = kwargs.pop("max_workers", min(32, cpu_count() + 4)) + chunksize = kwargs.pop("chunksize", 1) + lock_name = kwargs.pop("lock_name", "") + with ensure_lock(tqdm_class, lock_name=lock_name) as lk: + # share lock in case workers are already using `tqdm` + with PoolExecutor(max_workers=max_workers, initializer=tqdm_class.set_lock, + initargs=(lk,)) as ex: + return list(tqdm_class(ex.map(fn, *iterables, chunksize=chunksize), **kwargs)) + + +def thread_map(fn, *iterables, **tqdm_kwargs): + """ + Equivalent of `list(map(fn, *iterables))` + driven by `concurrent.futures.ThreadPoolExecutor`. + + Parameters + ---------- + tqdm_class : optional + `tqdm` class to use for bars [default: tqdm.auto.tqdm]. + max_workers : int, optional + Maximum number of workers to spawn; passed to + `concurrent.futures.ThreadPoolExecutor.__init__`. + [default: max(32, cpu_count() + 4)]. + """ + from concurrent.futures import ThreadPoolExecutor + return _executor_map(ThreadPoolExecutor, fn, *iterables, **tqdm_kwargs) + + +def process_map(fn, *iterables, **tqdm_kwargs): + """ + Equivalent of `list(map(fn, *iterables))` + driven by `concurrent.futures.ProcessPoolExecutor`. + + Parameters + ---------- + tqdm_class : optional + `tqdm` class to use for bars [default: tqdm.auto.tqdm]. + max_workers : int, optional + Maximum number of workers to spawn; passed to + `concurrent.futures.ProcessPoolExecutor.__init__`. + [default: min(32, cpu_count() + 4)]. + chunksize : int, optional + Size of chunks sent to worker processes; passed to + `concurrent.futures.ProcessPoolExecutor.map`. [default: 1]. + lock_name : str, optional + Member of `tqdm_class.get_lock()` to use [default: mp_lock]. + """ + from concurrent.futures import ProcessPoolExecutor + if iterables and "chunksize" not in tqdm_kwargs: + # default `chunksize=1` has poor performance for large iterables + # (most time spent dispatching items to workers). + longest_iterable_len = max(map(length_hint, iterables)) + if longest_iterable_len > 1000: + from warnings import warn + warn("Iterable length %d > 1000 but `chunksize` is not set." + " This may seriously degrade multiprocess performance." + " Set `chunksize=1` or more." % longest_iterable_len, + TqdmWarning, stacklevel=2) + if "lock_name" not in tqdm_kwargs: + tqdm_kwargs = tqdm_kwargs.copy() + tqdm_kwargs["lock_name"] = "mp_lock" + return _executor_map(ProcessPoolExecutor, fn, *iterables, **tqdm_kwargs) diff --git a/.venv/lib/python3.13/site-packages/tqdm/contrib/discord.py b/.venv/lib/python3.13/site-packages/tqdm/contrib/discord.py new file mode 100644 index 0000000000000000000000000000000000000000..574baa84bbbeb5afce4a49f23edac894d680ca82 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/tqdm/contrib/discord.py @@ -0,0 +1,156 @@ +""" +Sends updates to a Discord bot. + +Usage: +>>> from tqdm.contrib.discord import tqdm, trange +>>> for i in trange(10, token='{token}', channel_id='{channel_id}'): +... ... + +![screenshot](https://tqdm.github.io/img/screenshot-discord.png) +""" +from os import getenv +from warnings import warn + +from requests import Session +from requests.utils import default_user_agent + +from ..auto import tqdm as tqdm_auto +from ..std import TqdmWarning +from ..version import __version__ +from .utils_worker import MonoWorker + +__author__ = {"github.com/": ["casperdcl", "guigoruiz1"]} +__all__ = ['DiscordIO', 'tqdm_discord', 'tdrange', 'tqdm', 'trange'] + + +class DiscordIO(MonoWorker): + """Non-blocking file-like IO using a Discord Bot.""" + API = "https://discord.com/api/v10" + UA = f"tqdm (https://tqdm.github.io, {__version__}) {default_user_agent()}" + + def __init__(self, token, channel_id): + """Creates a new message in the given `channel_id`.""" + super().__init__() + self.token = token + self.channel_id = channel_id + self.session = Session() + self.text = self.__class__.__name__ + self.message_id + + @property + def message_id(self): + if hasattr(self, '_message_id'): + return self._message_id + try: + res = self.session.post( + f'{self.API}/channels/{self.channel_id}/messages', + headers={'Authorization': f'Bot {self.token}', 'User-Agent': self.UA}, + json={'content': f"`{self.text}`"}).json() + except Exception as e: + tqdm_auto.write(str(e)) + else: + if res.get('error_code') == 429: + warn("Creation rate limit: try increasing `mininterval`.", + TqdmWarning, stacklevel=2) + else: + self._message_id = res['id'] + return self._message_id + + def write(self, s): + """Replaces internal `message_id`'s text with `s`.""" + if not s: + s = "..." + s = s.replace('\r', '').strip() + if s == self.text: + return # avoid duplicate message Bot error + message_id = self.message_id + if message_id is None: + return + self.text = s + try: + future = self.submit( + self.session.patch, + f'{self.API}/channels/{self.channel_id}/messages/{message_id}', + headers={'Authorization': f'Bot {self.token}', 'User-Agent': self.UA}, + json={'content': f"`{self.text}`"}) + except Exception as e: + tqdm_auto.write(str(e)) + else: + return future + + def delete(self): + """Deletes internal `message_id`.""" + try: + future = self.submit( + self.session.delete, + f'{self.API}/channels/{self.channel_id}/messages/{self.message_id}', + headers={'Authorization': f'Bot {self.token}', 'User-Agent': self.UA}) + except Exception as e: + tqdm_auto.write(str(e)) + else: + return future + + +class tqdm_discord(tqdm_auto): + """ + Standard `tqdm.auto.tqdm` but also sends updates to a Discord Bot. + May take a few seconds to create (`__init__`). + + - create a discord bot (not public, no requirement of OAuth2 code + grant, only send message permissions) & invite it to a channel: + <https://discordpy.readthedocs.io/en/latest/discord.html> + - copy the bot `{token}` & `{channel_id}` and paste below + + >>> from tqdm.contrib.discord import tqdm, trange + >>> for i in tqdm(iterable, token='{token}', channel_id='{channel_id}'): + ... ... + """ + def __init__(self, *args, **kwargs): + """ + Parameters + ---------- + token : str, required. Discord bot token + [default: ${TQDM_DISCORD_TOKEN}]. + channel_id : int, required. Discord channel ID + [default: ${TQDM_DISCORD_CHANNEL_ID}]. + + See `tqdm.auto.tqdm.__init__` for other parameters. + """ + if not kwargs.get('disable'): + kwargs = kwargs.copy() + self.dio = DiscordIO( + kwargs.pop('token', getenv('TQDM_DISCORD_TOKEN')), + kwargs.pop('channel_id', getenv('TQDM_DISCORD_CHANNEL_ID'))) + super().__init__(*args, **kwargs) + + def display(self, **kwargs): + super().display(**kwargs) + fmt = self.format_dict + if fmt.get('bar_format', None): + fmt['bar_format'] = fmt['bar_format'].replace( + '<bar/>', '{bar:10u}').replace('{bar}', '{bar:10u}') + else: + fmt['bar_format'] = '{l_bar}{bar:10u}{r_bar}' + self.dio.write(self.format_meter(**fmt)) + + def clear(self, *args, **kwargs): + super().clear(*args, **kwargs) + if not self.disable: + self.dio.write("") + + def close(self): + if self.disable: + return + super().close() + if not (self.leave or (self.leave is None and self.pos == 0)): + self.dio.delete() + + +def tdrange(*args, **kwargs): + """Shortcut for `tqdm.contrib.discord.tqdm(range(*args), **kwargs)`.""" + return tqdm_discord(range(*args), **kwargs) + + +# Aliases +tqdm = tqdm_discord +trange = tdrange diff --git a/.venv/lib/python3.13/site-packages/tqdm/contrib/itertools.py b/.venv/lib/python3.13/site-packages/tqdm/contrib/itertools.py new file mode 100644 index 0000000000000000000000000000000000000000..e67651a41a6b8760d9b928ea48239e4611d70315 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/tqdm/contrib/itertools.py @@ -0,0 +1,35 @@ +""" +Thin wrappers around `itertools`. +""" +import itertools + +from ..auto import tqdm as tqdm_auto + +__author__ = {"github.com/": ["casperdcl"]} +__all__ = ['product'] + + +def product(*iterables, **tqdm_kwargs): + """ + Equivalent of `itertools.product`. + + Parameters + ---------- + tqdm_class : [default: tqdm.auto.tqdm]. + """ + kwargs = tqdm_kwargs.copy() + tqdm_class = kwargs.pop("tqdm_class", tqdm_auto) + try: + lens = list(map(len, iterables)) + except TypeError: + total = None + else: + total = 1 + for i in lens: + total *= i + kwargs.setdefault("total", total) + with tqdm_class(**kwargs) as t: + it = itertools.product(*iterables) + for i in it: + yield i + t.update() diff --git a/.venv/lib/python3.13/site-packages/tqdm/contrib/logging.py b/.venv/lib/python3.13/site-packages/tqdm/contrib/logging.py new file mode 100644 index 0000000000000000000000000000000000000000..e06febe37b5d70b5296804c55dca48a397c250e3 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/tqdm/contrib/logging.py @@ -0,0 +1,126 @@ +""" +Helper functionality for interoperability with stdlib `logging`. +""" +import logging +import sys +from contextlib import contextmanager + +try: + from typing import Iterator, List, Optional, Type # noqa: F401 +except ImportError: + pass + +from ..std import tqdm as std_tqdm + + +class _TqdmLoggingHandler(logging.StreamHandler): + def __init__( + self, + tqdm_class=std_tqdm # type: Type[std_tqdm] + ): + super().__init__() + self.tqdm_class = tqdm_class + + def emit(self, record): + try: + msg = self.format(record) + self.tqdm_class.write(msg, file=self.stream) + self.flush() + except (KeyboardInterrupt, SystemExit): + raise + except: # noqa pylint: disable=bare-except + self.handleError(record) + + +def _is_console_logging_handler(handler): + return (isinstance(handler, logging.StreamHandler) + and handler.stream in {sys.stdout, sys.stderr}) + + +def _get_first_found_console_logging_handler(handlers): + for handler in handlers: + if _is_console_logging_handler(handler): + return handler + + +@contextmanager +def logging_redirect_tqdm( + loggers=None, # type: Optional[List[logging.Logger]], + tqdm_class=std_tqdm # type: Type[std_tqdm] +): + # type: (...) -> Iterator[None] + """ + Context manager redirecting console logging to `tqdm.write()`, leaving + other logging handlers (e.g. log files) unaffected. + + Parameters + ---------- + loggers : list, optional + Which handlers to redirect (default: [logging.root]). + tqdm_class : optional + + Example + ------- + ```python + import logging + from tqdm import trange + from tqdm.contrib.logging import logging_redirect_tqdm + + LOG = logging.getLogger(__name__) + + if __name__ == '__main__': + logging.basicConfig(level=logging.INFO) + with logging_redirect_tqdm(): + for i in trange(9): + if i == 4: + LOG.info("console logging redirected to `tqdm.write()`") + # logging restored + ``` + """ + if loggers is None: + loggers = [logging.root] + original_handlers_list = [logger.handlers for logger in loggers] + try: + for logger in loggers: + tqdm_handler = _TqdmLoggingHandler(tqdm_class) + orig_handler = _get_first_found_console_logging_handler(logger.handlers) + if orig_handler is not None: + tqdm_handler.setFormatter(orig_handler.formatter) + tqdm_handler.stream = orig_handler.stream + logger.handlers = [ + handler for handler in logger.handlers + if not _is_console_logging_handler(handler)] + [tqdm_handler] + yield + finally: + for logger, original_handlers in zip(loggers, original_handlers_list): + logger.handlers = original_handlers + + +@contextmanager +def tqdm_logging_redirect( + *args, + # loggers=None, # type: Optional[List[logging.Logger]] + # tqdm=None, # type: Optional[Type[tqdm.tqdm]] + **kwargs +): + # type: (...) -> Iterator[None] + """ + Convenience shortcut for: + ```python + with tqdm_class(*args, **tqdm_kwargs) as pbar: + with logging_redirect_tqdm(loggers=loggers, tqdm_class=tqdm_class): + yield pbar + ``` + + Parameters + ---------- + tqdm_class : optional, (default: tqdm.std.tqdm). + loggers : optional, list. + **tqdm_kwargs : passed to `tqdm_class`. + """ + tqdm_kwargs = kwargs.copy() + loggers = tqdm_kwargs.pop('loggers', None) + tqdm_class = tqdm_kwargs.pop('tqdm_class', std_tqdm) + with tqdm_class(*args, **tqdm_kwargs) as pbar: + with logging_redirect_tqdm(loggers=loggers, tqdm_class=tqdm_class): + yield pbar diff --git a/.venv/lib/python3.13/site-packages/tqdm/contrib/slack.py b/.venv/lib/python3.13/site-packages/tqdm/contrib/slack.py new file mode 100644 index 0000000000000000000000000000000000000000..9bca8ee98904ce869a4f8d6417bbdc4f00b38751 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/tqdm/contrib/slack.py @@ -0,0 +1,120 @@ +""" +Sends updates to a Slack app. + +Usage: +>>> from tqdm.contrib.slack import tqdm, trange +>>> for i in trange(10, token='{token}', channel='{channel}'): +... ... + +![screenshot](https://tqdm.github.io/img/screenshot-slack.png) +""" +import logging +from os import getenv + +try: + from slack_sdk import WebClient +except ImportError: + raise ImportError("Please `pip install slack-sdk`") + +from ..auto import tqdm as tqdm_auto +from .utils_worker import MonoWorker + +__author__ = {"github.com/": ["0x2b3bfa0", "casperdcl"]} +__all__ = ['SlackIO', 'tqdm_slack', 'tsrange', 'tqdm', 'trange'] + + +class SlackIO(MonoWorker): + """Non-blocking file-like IO using a Slack app.""" + def __init__(self, token, channel): + """Creates a new message in the given `channel`.""" + super().__init__() + self.client = WebClient(token=token) + self.text = self.__class__.__name__ + try: + self.message = self.client.chat_postMessage(channel=channel, text=self.text) + except Exception as e: + tqdm_auto.write(str(e)) + self.message = None + + def write(self, s): + """Replaces internal `message`'s text with `s`.""" + if not s: + s = "..." + s = s.replace('\r', '').strip() + if s == self.text: + return # skip duplicate message + message = self.message + if message is None: + return + self.text = s + try: + future = self.submit(self.client.chat_update, channel=message['channel'], + ts=message['ts'], text='`' + s + '`') + except Exception as e: + tqdm_auto.write(str(e)) + else: + return future + + +class tqdm_slack(tqdm_auto): + """ + Standard `tqdm.auto.tqdm` but also sends updates to a Slack app. + May take a few seconds to create (`__init__`). + + - create a Slack app with the `chat:write` scope & invite it to a + channel: <https://api.slack.com/authentication/basics> + - copy the bot `{token}` & `{channel}` and paste below + >>> from tqdm.contrib.slack import tqdm, trange + >>> for i in tqdm(iterable, token='{token}', channel='{channel}'): + ... ... + """ + def __init__(self, *args, **kwargs): + """ + Parameters + ---------- + token : str, required. Slack token + [default: ${TQDM_SLACK_TOKEN}]. + channel : int, required. Slack channel + [default: ${TQDM_SLACK_CHANNEL}]. + mininterval : float, optional. + Minimum of [default: 1.5] to avoid rate limit. + + See `tqdm.auto.tqdm.__init__` for other parameters. + """ + if not kwargs.get('disable'): + kwargs = kwargs.copy() + logging.getLogger("HTTPClient").setLevel(logging.WARNING) + self.sio = SlackIO( + kwargs.pop('token', getenv("TQDM_SLACK_TOKEN")), + kwargs.pop('channel', getenv("TQDM_SLACK_CHANNEL"))) + kwargs['mininterval'] = max(1.5, kwargs.get('mininterval', 1.5)) + super().__init__(*args, **kwargs) + + def display(self, **kwargs): + super().display(**kwargs) + fmt = self.format_dict + if fmt.get('bar_format', None): + fmt['bar_format'] = fmt['bar_format'].replace( + '<bar/>', '`{bar:10}`').replace('{bar}', '`{bar:10u}`') + else: + fmt['bar_format'] = '{l_bar}`{bar:10}`{r_bar}' + if fmt['ascii'] is False: + fmt['ascii'] = [":black_square:", ":small_blue_diamond:", ":large_blue_diamond:", + ":large_blue_square:"] + fmt['ncols'] = 336 + self.sio.write(self.format_meter(**fmt)) + + def clear(self, *args, **kwargs): + super().clear(*args, **kwargs) + if not self.disable: + self.sio.write("") + + +def tsrange(*args, **kwargs): + """Shortcut for `tqdm.contrib.slack.tqdm(range(*args), **kwargs)`.""" + return tqdm_slack(range(*args), **kwargs) + + +# Aliases +tqdm = tqdm_slack +trange = tsrange diff --git a/.venv/lib/python3.13/site-packages/tqdm/contrib/telegram.py b/.venv/lib/python3.13/site-packages/tqdm/contrib/telegram.py new file mode 100644 index 0000000000000000000000000000000000000000..019151800bc0c4c4fc543314b6398aa602b0692a --- /dev/null +++ b/.venv/lib/python3.13/site-packages/tqdm/contrib/telegram.py @@ -0,0 +1,153 @@ +""" +Sends updates to a Telegram bot. + +Usage: +>>> from tqdm.contrib.telegram import tqdm, trange +>>> for i in trange(10, token='{token}', chat_id='{chat_id}'): +... ... + +![screenshot](https://tqdm.github.io/img/screenshot-telegram.gif) +""" +from os import getenv +from warnings import warn + +from requests import Session + +from ..auto import tqdm as tqdm_auto +from ..std import TqdmWarning +from .utils_worker import MonoWorker + +__author__ = {"github.com/": ["casperdcl"]} +__all__ = ['TelegramIO', 'tqdm_telegram', 'ttgrange', 'tqdm', 'trange'] + + +class TelegramIO(MonoWorker): + """Non-blocking file-like IO using a Telegram Bot.""" + API = 'https://api.telegram.org/bot' + + def __init__(self, token, chat_id): + """Creates a new message in the given `chat_id`.""" + super().__init__() + self.token = token + self.chat_id = chat_id + self.session = Session() + self.text = self.__class__.__name__ + self.message_id + + @property + def message_id(self): + if hasattr(self, '_message_id'): + return self._message_id + try: + res = self.session.post( + self.API + '%s/sendMessage' % self.token, + data={'text': '`' + self.text + '`', 'chat_id': self.chat_id, + 'parse_mode': 'MarkdownV2'}).json() + except Exception as e: + tqdm_auto.write(str(e)) + else: + if res.get('error_code') == 429: + warn("Creation rate limit: try increasing `mininterval`.", + TqdmWarning, stacklevel=2) + else: + self._message_id = res['result']['message_id'] + return self._message_id + + def write(self, s): + """Replaces internal `message_id`'s text with `s`.""" + if not s: + s = "..." + s = s.replace('\r', '').strip() + if s == self.text: + return # avoid duplicate message Bot error + message_id = self.message_id + if message_id is None: + return + self.text = s + try: + future = self.submit( + self.session.post, self.API + '%s/editMessageText' % self.token, + data={'text': '`' + s + '`', 'chat_id': self.chat_id, + 'message_id': message_id, 'parse_mode': 'MarkdownV2'}) + except Exception as e: + tqdm_auto.write(str(e)) + else: + return future + + def delete(self): + """Deletes internal `message_id`.""" + try: + future = self.submit( + self.session.post, self.API + '%s/deleteMessage' % self.token, + data={'chat_id': self.chat_id, 'message_id': self.message_id}) + except Exception as e: + tqdm_auto.write(str(e)) + else: + return future + + +class tqdm_telegram(tqdm_auto): + """ + Standard `tqdm.auto.tqdm` but also sends updates to a Telegram Bot. + May take a few seconds to create (`__init__`). + + - create a bot <https://core.telegram.org/bots#6-botfather> + - copy its `{token}` + - add the bot to a chat and send it a message such as `/start` + - go to <https://api.telegram.org/bot`{token}`/getUpdates> to find out + the `{chat_id}` + - paste the `{token}` & `{chat_id}` below + + >>> from tqdm.contrib.telegram import tqdm, trange + >>> for i in tqdm(iterable, token='{token}', chat_id='{chat_id}'): + ... ... + """ + def __init__(self, *args, **kwargs): + """ + Parameters + ---------- + token : str, required. Telegram token + [default: ${TQDM_TELEGRAM_TOKEN}]. + chat_id : str, required. Telegram chat ID + [default: ${TQDM_TELEGRAM_CHAT_ID}]. + + See `tqdm.auto.tqdm.__init__` for other parameters. + """ + if not kwargs.get('disable'): + kwargs = kwargs.copy() + self.tgio = TelegramIO( + kwargs.pop('token', getenv('TQDM_TELEGRAM_TOKEN')), + kwargs.pop('chat_id', getenv('TQDM_TELEGRAM_CHAT_ID'))) + super().__init__(*args, **kwargs) + + def display(self, **kwargs): + super().display(**kwargs) + fmt = self.format_dict + if fmt.get('bar_format', None): + fmt['bar_format'] = fmt['bar_format'].replace( + '<bar/>', '{bar:10u}').replace('{bar}', '{bar:10u}') + else: + fmt['bar_format'] = '{l_bar}{bar:10u}{r_bar}' + self.tgio.write(self.format_meter(**fmt)) + + def clear(self, *args, **kwargs): + super().clear(*args, **kwargs) + if not self.disable: + self.tgio.write("") + + def close(self): + if self.disable: + return + super().close() + if not (self.leave or (self.leave is None and self.pos == 0)): + self.tgio.delete() + + +def ttgrange(*args, **kwargs): + """Shortcut for `tqdm.contrib.telegram.tqdm(range(*args), **kwargs)`.""" + return tqdm_telegram(range(*args), **kwargs) + + +# Aliases +tqdm = tqdm_telegram +trange = ttgrange diff --git a/.venv/lib/python3.13/site-packages/tqdm/contrib/utils_worker.py b/.venv/lib/python3.13/site-packages/tqdm/contrib/utils_worker.py new file mode 100644 index 0000000000000000000000000000000000000000..2a03a2a8930001e37938836196e0d15b649b07a8 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/tqdm/contrib/utils_worker.py @@ -0,0 +1,38 @@ +""" +IO/concurrency helpers for `tqdm.contrib`. +""" +from collections import deque +from concurrent.futures import ThreadPoolExecutor + +from ..auto import tqdm as tqdm_auto + +__author__ = {"github.com/": ["casperdcl"]} +__all__ = ['MonoWorker'] + + +class MonoWorker(object): + """ + Supports one running task and one waiting task. + The waiting task is the most recent submitted (others are discarded). + """ + def __init__(self): + self.pool = ThreadPoolExecutor(max_workers=1) + self.futures = deque([], 2) + + def submit(self, func, *args, **kwargs): + """`func(*args, **kwargs)` may replace currently waiting task.""" + futures = self.futures + if len(futures) == futures.maxlen: + running = futures.popleft() + if not running.done(): + if len(futures): # clear waiting + waiting = futures.pop() + waiting.cancel() + futures.appendleft(running) # re-insert running + try: + waiting = self.pool.submit(func, *args, **kwargs) + except Exception as e: + tqdm_auto.write(str(e)) + else: + futures.append(waiting) + return waiting diff --git a/.venv/lib/python3.13/site-packages/wrapt/_wrappers.cpython-313-x86_64-linux-gnu.so b/.venv/lib/python3.13/site-packages/wrapt/_wrappers.cpython-313-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..e1d02b35fb4f8589c7de3f4f7fb50e5856be4b16 --- /dev/null +++ b/.venv/lib/python3.13/site-packages/wrapt/_wrappers.cpython-313-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f68192bff6a95d5654a482833be025c14c8bee026ff0c6647a99d521b986f38 +size 218040 diff --git a/.venv/share/jupyter/nbextensions/pydeck/index.js.map b/.venv/share/jupyter/nbextensions/pydeck/index.js.map new file mode 100644 index 0000000000000000000000000000000000000000..cf8196e34bf8a94ec8da13f5c7177408dd28f222 --- /dev/null +++ b/.venv/share/jupyter/nbextensions/pydeck/index.js.map @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c68edb43974e7e3ed2fa54dd95d026296585d27b8d603efef0176ba541c347a +size 11792363 diff --git a/eval_agent/__pycache__/ev2_service_standalone.cpython-313.pyc b/eval_agent/__pycache__/ev2_service_standalone.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d8ca1208fa08fb93a1ef6d01235531424476c4b1 --- /dev/null +++ b/eval_agent/__pycache__/ev2_service_standalone.cpython-313.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6fd3041c86b05f15f805311a5d1ed0f79f5ccb3d7164250af04a635abf59ce67 +size 122909 diff --git a/py311/lib/python3.11/site-packages/click/__pycache__/core.cpython-311.pyc b/py311/lib/python3.11/site-packages/click/__pycache__/core.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c38ec031b5fa3d6157cb4ae8004b883d9b45bf92 --- /dev/null +++ b/py311/lib/python3.11/site-packages/click/__pycache__/core.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d16c5208647ff559098e3c5018a1df6005d7dccaa0a5dbb289088f68f7c2369 +size 143419 diff --git a/py311/lib/python3.11/site-packages/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz b/py311/lib/python3.11/site-packages/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..ff62a934a5009337271c60501278a7a34913a20b --- /dev/null +++ b/py311/lib/python3.11/site-packages/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3ea52e7b6e968de0d884df1288193596fa95b803db4f92a18279a7398004475 +size 156400 diff --git a/py311/lib/python3.11/site-packages/google/_upb/_message.abi3.so b/py311/lib/python3.11/site-packages/google/_upb/_message.abi3.so new file mode 100644 index 0000000000000000000000000000000000000000..f322b7608ed969375e56beab0e69a8130187de52 --- /dev/null +++ b/py311/lib/python3.11/site-packages/google/_upb/_message.abi3.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca062fce5f0e0f53a1d439c93b4bd3be77b4af07727379634f68039b89d0cdf1 +size 390920 diff --git a/py311/lib/python3.11/site-packages/google/ai/generativelanguage_v1beta/services/retriever_service/__pycache__/client.cpython-311.pyc b/py311/lib/python3.11/site-packages/google/ai/generativelanguage_v1beta/services/retriever_service/__pycache__/client.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eecf89959c2571a168d8859f52e4009a9137256d --- /dev/null +++ b/py311/lib/python3.11/site-packages/google/ai/generativelanguage_v1beta/services/retriever_service/__pycache__/client.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af3848d588ea2c15044e1236f7b2b2673b638d700aeb0058628e0a8cc62f339d +size 111252 diff --git a/py311/lib/python3.11/site-packages/google/ai/generativelanguage_v1beta/services/retriever_service/transports/__pycache__/rest.cpython-311.pyc b/py311/lib/python3.11/site-packages/google/ai/generativelanguage_v1beta/services/retriever_service/transports/__pycache__/rest.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c2b031aa22aaed21055952dab1c48bf209505bd3 --- /dev/null +++ b/py311/lib/python3.11/site-packages/google/ai/generativelanguage_v1beta/services/retriever_service/transports/__pycache__/rest.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:073ea4d7b11969053b7c9c433115cba8b50d9c45513a9bd86175e62d791d46c5 +size 146084 diff --git a/py311/lib/python3.11/site-packages/google/genai/__pycache__/models.cpython-311.pyc b/py311/lib/python3.11/site-packages/google/genai/__pycache__/models.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff9a453ca5f2e38144cd006c2f0115bbcbde7cce --- /dev/null +++ b/py311/lib/python3.11/site-packages/google/genai/__pycache__/models.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44fabc94c0c0bd079cbba428054281d92d2208d569bb290a78fff53f62d18e80 +size 267107 diff --git a/py311/lib/python3.11/site-packages/google/genai/__pycache__/types.cpython-311.pyc b/py311/lib/python3.11/site-packages/google/genai/__pycache__/types.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad02fbb286c19f90fe959cf155b9115170c53a7b --- /dev/null +++ b/py311/lib/python3.11/site-packages/google/genai/__pycache__/types.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1167e007f1295a5c93145004f6451f745f37e709941204fb1df343aa06410c1 +size 696869 diff --git a/py311/lib/python3.11/site-packages/google/protobuf/__pycache__/descriptor_pb2.cpython-311.pyc b/py311/lib/python3.11/site-packages/google/protobuf/__pycache__/descriptor_pb2.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf4278a749d70b7ce9dc14669d842bc63f45c1e5 --- /dev/null +++ b/py311/lib/python3.11/site-packages/google/protobuf/__pycache__/descriptor_pb2.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:011dc20965cf95570985c05a7bfbdd2def3c1aa2d08f913c6a1de6927311b724 +size 281671 diff --git a/py311/lib/python3.11/site-packages/hydra/test_utils/configs/conf.zip b/py311/lib/python3.11/site-packages/hydra/test_utils/configs/conf.zip new file mode 100644 index 0000000000000000000000000000000000000000..774a4a563dcddb03a846c82152c2ffacac0287c6 --- /dev/null +++ b/py311/lib/python3.11/site-packages/hydra/test_utils/configs/conf.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c471e8fa9f01a1fc65507499622da66dff2be96f1bf8d00947f14332270a4bb +size 210 diff --git a/py311/lib/python3.11/site-packages/jinja2/__pycache__/compiler.cpython-311.pyc b/py311/lib/python3.11/site-packages/jinja2/__pycache__/compiler.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dbc06dc04f5dd3967d3c88c856ed21f9370f0e6e --- /dev/null +++ b/py311/lib/python3.11/site-packages/jinja2/__pycache__/compiler.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96d7ec71d0c3bba4b9f26da0d0d0637d5a941fe5bde09864c958a6f0ef6f3a29 +size 112446 diff --git a/py311/lib/python3.11/site-packages/matplotlib/__pycache__/_cm_listed.cpython-311.pyc b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/_cm_listed.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6380d29c47b8560b266b8dda7e825f10628ed41d --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/_cm_listed.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:57439b98566b3280211909431512654a9a4f8110f1039e13ceab9f7b38959186 +size 164001 diff --git a/py311/lib/python3.11/site-packages/matplotlib/__pycache__/_mathtext.cpython-311.pyc b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/_mathtext.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c47e7a4bf439144cbb201658198dda322656737d --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/_mathtext.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c6deca20ac36ef41e0111fa25a9a4022be4d4c6e8cd9edb5412485b475be67f +size 143434 diff --git a/py311/lib/python3.11/site-packages/matplotlib/__pycache__/axis.cpython-311.pyc b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/axis.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba97a144c3a5147df7d87dbad75402fcb6a23cb3 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/axis.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ab77181a478f1c036bca20c15253e1ccb700877b3116b718b9524da3e1720f9 +size 137396 diff --git a/py311/lib/python3.11/site-packages/matplotlib/__pycache__/backend_bases.cpython-311.pyc b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/backend_bases.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5f32767caf94a27096f1b70b5c033120a334e38c --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/backend_bases.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3052e4be0fc01340134f27f1565dfd8d96bb23ca646553b34b59fad20b0ca54 +size 167897 diff --git a/py311/lib/python3.11/site-packages/matplotlib/__pycache__/cbook.cpython-311.pyc b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/cbook.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c64915275e721e813a6ff55bc9916cf094adfad7 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/cbook.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02b05152154a0246d68535f02b59af90b1cde99b4e1bcd93f5d04e3b9a2e7b9f +size 107112 diff --git a/py311/lib/python3.11/site-packages/matplotlib/__pycache__/collections.cpython-311.pyc b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/collections.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1075a39245c11df32678c68c2325060fa635df8a --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/collections.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce5726575bddfad8f1581a26fd303e0824d16ccab4f4bbcca58ddadce9b3ef1c +size 133977 diff --git a/py311/lib/python3.11/site-packages/matplotlib/__pycache__/colors.cpython-311.pyc b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/colors.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..285614c34c16382ea2e1a377cb6799b337e613d0 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/colors.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb47ef830fd35e1452c8dd68b298c61e93a0f2f9d9b7311832d147c8c5ee287b +size 178903 diff --git a/py311/lib/python3.11/site-packages/matplotlib/__pycache__/figure.cpython-311.pyc b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/figure.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..99847768219a8026f74a9dfe8926992ace251f08 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/figure.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2413bd2ed00078163d527a9db27ea9f6716991b11b46b30ff8cf3de08e7c92cb +size 163125 diff --git a/py311/lib/python3.11/site-packages/matplotlib/__pycache__/patches.cpython-311.pyc b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/patches.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c8d7caa476b4506839f1f7c4eb1faa8109cc923 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/patches.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3d4bed7071c28b3ad28e0da41d4107e4e0fd3ffbf31225a24aed89f575eff45c +size 213020 diff --git a/py311/lib/python3.11/site-packages/matplotlib/__pycache__/pyplot.cpython-311.pyc b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/pyplot.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..baf940b62ea68cccc121ff95801c80ce52dbfd15 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/pyplot.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:112d6941d3e721227c5f36ed1201c48b65032ee75669db5ece09b8fd4a66c5f5 +size 162590 diff --git a/py311/lib/python3.11/site-packages/matplotlib/__pycache__/ticker.cpython-311.pyc b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/ticker.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b8fb450820752dc33530ff8e52311e0d44d0b02a --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/ticker.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d9bce2f868797ff58f014f4cca2e17143d677f5b0521a38976fb549a660b978 +size 137147 diff --git a/py311/lib/python3.11/site-packages/matplotlib/__pycache__/transforms.cpython-311.pyc b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/transforms.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f78dfc123d9657de3b10a1b594aa5c6f6d4681fc --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/transforms.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:060c2a7f8f5f7fc743d1d14d6695ca506062b7e5d4ac36a90e3135767c28d5b5 +size 143833 diff --git a/py311/lib/python3.11/site-packages/matplotlib/__pycache__/widgets.cpython-311.pyc b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/widgets.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dc8809e1c450e3ff31c2dfd165c048739f39c1d8 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/__pycache__/widgets.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1833516e5363a09c91270df3b306ad0184c9cb1dbf1b9231f81ef51c9883e8c +size 203370 diff --git a/py311/lib/python3.11/site-packages/matplotlib/axes/__pycache__/_axes.cpython-311.pyc b/py311/lib/python3.11/site-packages/matplotlib/axes/__pycache__/_axes.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4a2bda9cfe0b2f7f5aba13e1370e11efdae3611d --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/axes/__pycache__/_axes.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f54ab34bab8160e98c9d8d0ffbed5df0a66666fcddb3006fcf38e0a301b119d6 +size 372189 diff --git a/py311/lib/python3.11/site-packages/matplotlib/axes/__pycache__/_base.cpython-311.pyc b/py311/lib/python3.11/site-packages/matplotlib/axes/__pycache__/_base.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50b9578b5215aafccb29aa71a934ff8f8b8eddb3 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/axes/__pycache__/_base.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0be74fd9c2eb830e08cf6091483aa95a2a0bdf842737b06075f5a32ef13ab6a8 +size 226953 diff --git a/py311/lib/python3.11/site-packages/matplotlib/backends/_backend_agg.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/matplotlib/backends/_backend_agg.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..251a86535137e765b847900a5be8400b830e780b --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/backends/_backend_agg.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:12e2efe19653282533381d2849e142cfdabdbbeef1bb0fc83fe051358f9579dc +size 771600 diff --git a/py311/lib/python3.11/site-packages/matplotlib/backends/_tkagg.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/matplotlib/backends/_tkagg.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..85f404c854a0d51cda34d383801697daf8459fce --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/backends/_tkagg.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:059dc0870fdf25012b1752b58c2b81ff3a632b1f27531113fcef9c9d42333aa2 +size 302640 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Bold.ttf b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..39699bd84ae17507955ce571caa859ad14997f4e --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Bold.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b184b89e3c1075f22f6b71575b6fc20d4972b3cfd3b23322ca6fd596dcaef167 +size 704128 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-BoldOblique.ttf b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-BoldOblique.ttf new file mode 100644 index 0000000000000000000000000000000000000000..cfd64ecefe8e5cdf2a0ea7d128019650a68ee682 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-BoldOblique.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6edf0283160186af451cbee71e7b845f2e4cabf264bb992ce668c83c25465e6f +size 641720 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Oblique.ttf b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Oblique.ttf new file mode 100644 index 0000000000000000000000000000000000000000..4ddf1fabb8648ac811ba05df9980121ec6a36452 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Oblique.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ccdf74b350f11fd3dd5774de50e5e6346a1a5da1f5b7d5fb83590665e97a5213 +size 633840 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f47aa8cffd396d3ac221ad7a2a518bc9a554c9ce --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3fdf69cabf06049ea70a00b5919340e2ce1e6d02b0cc3c4b44fb6801bd1e0d22 +size 756072 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Bold.ttf b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..fb4675de56d8c2b2b09734578191896c7bf6948e --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Bold.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:baada9a5172fe20886251aff0433fc38461912d5daf07287e7bee56620a8da96 +size 331536 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-BoldOblique.ttf b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-BoldOblique.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ee85d0dc6915489b236e932ab89838b200443aba --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-BoldOblique.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a69081c15c76c827e0a27a5a7f5c74b6135c843499955495ffa8c20d3a98288b +size 253116 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Oblique.ttf b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Oblique.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ba2147393770bbb669b1a6c735190f3cf6e732a8 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Oblique.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28052813f7a709fc89f52d192dc995ef4f0fdc5c3d7b73a49d6849b1916d0cd0 +size 251472 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono.ttf b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono.ttf new file mode 100644 index 0000000000000000000000000000000000000000..60f42148ea53bf551fc77faef9d6382ff0efcb16 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:602ec86b8948cfcd956482fe64f94c36c867770149ef2f791d4613f443bcecb3 +size 340240 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Bold.ttf b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..0137479cb3e30823976d9137d9e75ed8e225c57f --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Bold.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c3753f2ed6bc673f15846dc45addbeb3b9c872f32fb18fd53a21f1bef1ed7676 +size 355692 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-BoldItalic.ttf b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-BoldItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..b89793b3fe00a3510c0a22b54d9ee7735e5e0803 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-BoldItalic.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d93efec7a9d2e826768d1a2ee95b95870e15e29599a84f3484af1de1cec2e181 +size 347064 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Italic.ttf b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..c1a70e8374879a0c04e370eb5c57861c4fd5abce --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Italic.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e7994fbc54fa10ce3352a42d548fadd7d9cadb69cb1109bc9d960f6dac57f04 +size 345612 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif.ttf b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif.ttf new file mode 100644 index 0000000000000000000000000000000000000000..73a4204e08a49a83ab7336cb55add8b32200ae24 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:107244956e9962b9e96faccdc551825e0ae0898ae13737133e1b921a2fd35ffa +size 379740 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneral.ttf b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneral.ttf new file mode 100644 index 0000000000000000000000000000000000000000..cbf159757c5c0a47f1d8f2b984f0c20f52b7e25b --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneral.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:167378031e2dddc6216d67819c9260e9a06ffc4c478e4e23cb98a6fd44b183c2 +size 448228 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralBol.ttf b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralBol.ttf new file mode 100644 index 0000000000000000000000000000000000000000..64ca51419ec522ee78c91e6f36f57fdb3bde290b --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralBol.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8533dc7083fa346bda1933d60ea4a83b67d0945bceaf1b3541f82b4a0e2c6a0 +size 237360 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralBolIta.ttf b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralBolIta.ttf new file mode 100644 index 0000000000000000000000000000000000000000..585e03c626a96775f018e690fc6e10f6cd3e4047 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralBolIta.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98788fd4ba48dfbb2bd026c0e20a247a8b06c7372879628b7a6bb0d5bb09736c +size 181152 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralItalic.ttf b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..67ce0a807f6ae1dc2b4f7b863ce99620d29e6cb7 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralItalic.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cfcb333d22b7c3c623bdfd40174f14c85c3d6731ca6166c1edc80140eae8527 +size 175040 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/sample_data/axes_grid/bivariate_normal.npy b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/sample_data/axes_grid/bivariate_normal.npy new file mode 100644 index 0000000000000000000000000000000000000000..a76ff8b1f63c970d5e02b481a16b3231408aebe4 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/sample_data/axes_grid/bivariate_normal.npy @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e9599f6e74087aa2ca58aa77846b6ec3e8491180e445c07a2c69c65756ef7c5 +size 1880 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/sample_data/goog.npz b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/sample_data/goog.npz new file mode 100644 index 0000000000000000000000000000000000000000..bd82e71bf7d72da7db030381c31f769a3d9736bb --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/sample_data/goog.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:400917cf30e6b664f7b0da93d7c745860d3aa9008da8b7f160d2dd12e6a318b1 +size 22845 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/sample_data/jacksboro_fault_dem.npz b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/sample_data/jacksboro_fault_dem.npz new file mode 100644 index 0000000000000000000000000000000000000000..065732313f852fe861ea6852a84f8c59666c90b1 --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/sample_data/jacksboro_fault_dem.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d493f50a33e82a4420494c54d1fca1539d177bdc27ab190bc5fe6e92f62fb637 +size 174061 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/sample_data/s1045.ima.gz b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/sample_data/s1045.ima.gz new file mode 100644 index 0000000000000000000000000000000000000000..29d1c7f70afaa882d9673861bc3d17a4ffd7235d --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/sample_data/s1045.ima.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32b424d64f62b7e71cb24d29fd53938ad5664d608055a67ab2b2af4369f8b89e +size 33229 diff --git a/py311/lib/python3.11/site-packages/matplotlib/mpl-data/sample_data/topobathy.npz b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/sample_data/topobathy.npz new file mode 100644 index 0000000000000000000000000000000000000000..67fc6c403643c5b4e0624005b7bd99ac59e856fd --- /dev/null +++ b/py311/lib/python3.11/site-packages/matplotlib/mpl-data/sample_data/topobathy.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0244e03291702df45024dcb5cacbc4f3d4cb30d72dfa7fd371c4ac61c42b4fbf +size 45224 diff --git a/py311/lib/python3.11/site-packages/mpl_toolkits/mplot3d/__pycache__/axes3d.cpython-311.pyc b/py311/lib/python3.11/site-packages/mpl_toolkits/mplot3d/__pycache__/axes3d.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8b6015ff47797c2760f58135a2402f3ab5818398 --- /dev/null +++ b/py311/lib/python3.11/site-packages/mpl_toolkits/mplot3d/__pycache__/axes3d.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fac680f4e9c15dfe696431f38587722f095dd6477e28ec54c09fd83f80fa594a +size 187563 diff --git a/py311/lib/python3.11/site-packages/omegaconf/grammar/gen/__pycache__/OmegaConfGrammarParser.cpython-311.pyc b/py311/lib/python3.11/site-packages/omegaconf/grammar/gen/__pycache__/OmegaConfGrammarParser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1e7d984430e318b053d8635907670767b6ad9f16 --- /dev/null +++ b/py311/lib/python3.11/site-packages/omegaconf/grammar/gen/__pycache__/OmegaConfGrammarParser.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c23cb23ddacc3df3068bd0b09ca50bb2abed88e82c943dbfb0306c233ccbb06c +size 101664 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/algos.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/algos.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..0b80ca2017596707e6ad4cf36cab4ec0a6f054e1 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/algos.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47c4aa04e2ddc1e0d17c49d84e1d3355b8183f0e516d669b5c14b65f660e741a +size 2196592 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/arrays.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/arrays.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..32e70acc42bf9bfca417a66edeba25b827260482 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/arrays.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1bb74618119ebd23c38a3a242c2cf678b6c7877fc42eb9e3e2e63917dbf13b6 +size 125392 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/groupby.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/groupby.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..262b08f04cc6389e07a4b94b21ff840672004f19 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/groupby.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fcb1ec962555f5937ed715b3b367f31593110c5da72397e65b84bd7872e2d36f +size 2642216 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/hashing.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/hashing.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..6cf7e713c3faf40afda55471c46735e99244e644 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/hashing.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92c0bd45643796bf5e1995571f73d24e623a4aa879482bfe5982e23ab52b21ad +size 213136 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/hashtable.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/hashtable.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..e52b13d89ae5b010782c2ad7109e07723debd7eb --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/hashtable.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b1e7bd03d9a667fb8c3252e2ec58f1b67b1d040557512e5ac6e6675a0deb434 +size 2277968 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/index.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/index.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..573a1f7917c1c8a667046ef29a891ecfe775516a --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/index.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef46caffb368bcb9946d2b33cc1b4802b813c70bde344c641bc60aa6c6d92a3e +size 898464 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/internals.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/internals.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..ff4bce032d78f26dc718084fdfe3202ccf227ec2 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/internals.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:488f94945ad2f85c38a16719cb6f7824efb947bd5625ed6e0081a55f84df4726 +size 407456 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/interval.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/interval.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..57d6765398a45357204d214402fec6dc6a5f5875 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/interval.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03f3bd30da65072695dbfa243850f99ab0bb09f4090fdebce42fd2bb1d780fea +size 1401680 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/join.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/join.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..7840b90688858848f968b003956c9c1e8a80d971 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/join.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3ef0d6f800e096ca945ac1fb3ad0b4579cd0dc152cd67f0f69e0636ca245b9a +size 1408720 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/lib.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/lib.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..45e4f138f98e9b0b5e9ea218cd5f30030453216e --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/lib.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b126bd6d836a0259d7e1809829b18eebf2bc3b3d7f35ff269ec66e3bf2354da +size 875248 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/missing.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/missing.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..8d76621a670b596bc3eaa83ce82595ed6c21e6d5 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/missing.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2409f00b3f5250d298766bc7763a7406da8f434237d2441324f9d86f2a50ebce +size 199440 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/ops.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/ops.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..9bb248086aa47697410db659b23ad027e6b4e019 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/ops.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5fe35a09f4e3cff0aaf3b4fe6e413ab10866cca0b89a32e26b3f6fb1b2d4fa0 +size 258352 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/parsers.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/parsers.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..9d37783d9ad03c9eddfeab0f1cc4dce2bfd9c3b6 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/parsers.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2106fd598f547ea1ee55e3f7060cb07b37f3383bbc845a682d7586c7c11c1f93 +size 570336 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/reshape.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/reshape.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..f5c170d5906335980b936e590d979de21daf574b --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/reshape.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9e5f7363535040f2fa64ea03d932ca3dada2fc77b76344c6d6a963aaabd3ac8 +size 312784 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/sas.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/sas.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..80d2fa0a0aadf9ef73b5a7c2b1f74bb954f0e77a --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/sas.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7c525367d2c9bbde03aff84d8fa0b9372a5224348dc0b2bc8080ccaa61b5087 +size 262896 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/sparse.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/sparse.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..89c87870d94a328e6c03085c3d8297c418cd7d35 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/sparse.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a542d68188cad47882214d3a783f2aba023086c7f4e0399581d7f117fc26c3c1 +size 1009008 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/testing.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/testing.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..b9240197cb9376da392a768fb8b8556132f70353 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/testing.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d56aefdfe0dfeaa8debc6a76c3df2a28a95c5bef661ed0abf2575c16fa22b137 +size 115536 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/tslib.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/tslib.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..9b60edaffaf1688ac3ba57ebc861c052a466fc49 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/tslib.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55bd6293a16ad3072b50cbc8f553cfcf5fff257e6be09e156bb172dc7f2c778d +size 336688 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/conversion.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/conversion.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..112600d5baa2b544a4c2c61a35a9d78d53ed510e --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/conversion.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:65926449b54e2aa010dfd3a8ca05b1796d3a789076bf79679c96fd313509df6a +size 304240 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/dtypes.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/dtypes.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..4689a39f8af8ffdab81eb435be6e248bb7f4f1d5 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/dtypes.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4592d25035d26e9c1ad504b1b5859b8cb65c2890374833c806c4874837fe9fec +size 182544 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/fields.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/fields.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..1409be9af994123f4d51f4de79aa0c4b451f087f --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/fields.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9712344820fe23b998c01eeb63b6beb4b1ff8344f78016ab4250ef34b1a4e114 +size 341040 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/nattype.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/nattype.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..f396c1b0571537d2724327e2244eeb93e16ff45f --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/nattype.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:028f54fe4c3f08c72f7e3e90ba19cca85cf3c3f2b8323a9af97175d9ef36a3e3 +size 229520 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/np_datetime.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/np_datetime.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..3a14109331226c7d7541b26d00ac18b15049226e --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/np_datetime.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d448ad529784fb4a36fc362f9f805e289f6a77f672baaf31d2406f8b7978aab8 +size 140240 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/offsets.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/offsets.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..b760ae513a001c1e51fe9f69859d903d168a8473 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/offsets.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8607a9c6ba602462f954343c53ab880c2cb6a1623a1da8080cc6df5c0ff1aa5c +size 1065696 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/parsing.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/parsing.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..18e8e84d5408317862f599b07c2a655532964f08 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/parsing.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:483cdbcfe22aa0c1d2764bc12847215150202fc259e44e1f23f2611d4814e445 +size 440768 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/period.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/period.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..9d481affb2a39a34d00515eeeb7b9d075c986c9d --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/period.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a75a3a384ef7b8e09ab363acd9411f77398e5936dbf31ee28c3be0ab3860b9a +size 507664 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/strptime.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/strptime.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..9412f2a0a7f97b3ee5815371914a7ec002fe34e8 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/strptime.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0c8c1b6913298e769d1c8e0286c53de02289c80806150d5cab8ed92877f06a0 +size 382320 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/timedeltas.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/timedeltas.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..69a8eaca3117fdbc21b31dd8b9ab2a9c18ac7f10 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/timedeltas.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfc7812816f0e67f33bbfbd1b1bd35ceeccc5cf381b71a57e98b04e91c9f9234 +size 603344 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/timestamps.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/timestamps.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..558f1a8b3381f29ef771e017e88170db6e0b03ea --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/timestamps.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ff221188cec951c917880a5365f2ba70979c065d08fec2bf29dc902ac288c1a +size 632672 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/timezones.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/timezones.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..7531622e64c8d0dc5e86c063d35340b4813576c1 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/timezones.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:68fa5d914b43be5a3cbd068a8e4a1c480fc052dface7f8b563c21c270a635097 +size 278832 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/tzconversion.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/tzconversion.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..6db4b9367d139609aa30325b12b4905b3623122a --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/tzconversion.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:abe3c73214a13a4d5c36fbc75cb441373df40522fa6d3430b0330a534b855b51 +size 328880 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/vectorized.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/vectorized.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..c879e5f109f33a76083f367e554c26415830513b --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/tslibs/vectorized.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2e68fe0efc95ac698ea4089920019cb371ea7319b0148b54a0ce8911e7964e4 +size 246384 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/window/aggregations.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/window/aggregations.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..d818dd07f9c0885c2532ad30ab4f3bf08cd79515 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/window/aggregations.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0e8e75d77dbd4fd5e96fc7c0183acf2c39b8e48a2da8c1b3f0da6335fa5e456 +size 419176 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/window/indexers.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/window/indexers.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..bbfa1df3fc5427954a715b57fcd1edc3279fe4cc --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/window/indexers.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e99bd2c3013f6ac911be57bdd6318bffdee3fd6ab0e1a9da6cea67ac849b5dc0 +size 208976 diff --git a/py311/lib/python3.11/site-packages/pandas/_libs/writers.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/pandas/_libs/writers.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..270732910663babe5cdf9a17e2823a1d54618b97 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/_libs/writers.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a8d7e8e5591743bac45f6738e953252a1856f2cf96444acede4d439b7bcf37d +size 246992 diff --git a/py311/lib/python3.11/site-packages/pandas/core/__pycache__/frame.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/__pycache__/frame.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..49f182225973dd80cde8d09e1bea3cf9828e2a7d --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/__pycache__/frame.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f72e1ff7a8b61553e59f63311b010e8b012fe25bc683aa879bd7eca368ca19e +size 479365 diff --git a/py311/lib/python3.11/site-packages/pandas/core/__pycache__/generic.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/__pycache__/generic.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7fbc38efa42d44c475ba56cae4c6119d1438a42f --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/__pycache__/generic.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac65781dab0d59783cbee39db4e4edc641a184662b6ee8defb881075293beff1 +size 494414 diff --git a/py311/lib/python3.11/site-packages/pandas/core/__pycache__/indexing.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/__pycache__/indexing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5494430c53fd9fe0ecf5b467324cf079e15808ef --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/__pycache__/indexing.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3d5d3d0d12c01b7c1962d237f92b1d43e984a63dfb4fabc7e3dd1ff75c088128 +size 116590 diff --git a/py311/lib/python3.11/site-packages/pandas/core/__pycache__/resample.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/__pycache__/resample.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4af8e7b4f465d708a721142911c540056f643a83 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/__pycache__/resample.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f9bbbf577d109fea2802c0d456a1af7786e2fe38448accb00a5d3f6c6138cd3 +size 106109 diff --git a/py311/lib/python3.11/site-packages/pandas/core/__pycache__/series.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/__pycache__/series.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06e4d496801ae76f7f3005613c0074275691f7ab --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/__pycache__/series.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47af067862581583eb0b4489f3047cdc9b8a040c7d22a210eef584447487d564 +size 235484 diff --git a/py311/lib/python3.11/site-packages/pandas/core/arrays/__pycache__/categorical.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/arrays/__pycache__/categorical.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..404e585b9b75cfbdf77dbb7dc8dd18b423b24a5d --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/arrays/__pycache__/categorical.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:70f41043f3e245cde5b489c06b778e3ad22b1a9be8bad9ead82f662b6463e68e +size 115489 diff --git a/py311/lib/python3.11/site-packages/pandas/core/arrays/__pycache__/datetimelike.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/arrays/__pycache__/datetimelike.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d7386fa3f82a96a68d15b3cd29c16ebed4dbcb9c --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/arrays/__pycache__/datetimelike.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:505a5300abbe55c7d166f11df49f4ee089ffc65fce977fb4e0ba8901299a9add +size 106470 diff --git a/py311/lib/python3.11/site-packages/pandas/core/arrays/arrow/__pycache__/array.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/arrays/arrow/__pycache__/array.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b6bf0ef40462b948f4445b18eda51c00ba4567eb --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/arrays/arrow/__pycache__/array.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75a8d9c8eae2fc167eeeb547417b64f4a751ce9dfe991cf27a322363e472bb9a +size 149850 diff --git a/py311/lib/python3.11/site-packages/pandas/core/groupby/__pycache__/generic.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/groupby/__pycache__/generic.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cec190f40d572c4171de95d441179b72a1c8352e --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/groupby/__pycache__/generic.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f8ea85d29a13eba0462376da675b2bf92e756a25ed02e731160eeaaab1cb702 +size 110131 diff --git a/py311/lib/python3.11/site-packages/pandas/core/groupby/__pycache__/groupby.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/groupby/__pycache__/groupby.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e7c8eab9000c205fb2e5f75161bc7a4c9605cbe8 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/groupby/__pycache__/groupby.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62ad72102bc6ffee4f77260663adb1d1527e0cb945b640c8f186723e1620fa5c +size 218851 diff --git a/py311/lib/python3.11/site-packages/pandas/core/indexes/__pycache__/base.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/indexes/__pycache__/base.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..626403ccc3f708f8c22def4762bf9f82bcf145e7 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/indexes/__pycache__/base.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad716f889898cb16b8df7bb355e0824d5af2907ddfed26b7b0a36dce56adf504 +size 295544 diff --git a/py311/lib/python3.11/site-packages/pandas/core/indexes/__pycache__/multi.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/indexes/__pycache__/multi.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..362d1e6cae0bf7e8a8deec97b93e2e4432c88d8e --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/indexes/__pycache__/multi.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55e8e43bf6a6a47ef5d920259abef5d9350e7eb4192ae04e9d56f2bb033a780e +size 170745 diff --git a/py311/lib/python3.11/site-packages/pandas/core/internals/__pycache__/blocks.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/internals/__pycache__/blocks.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff110b4e8d55451bc04364ca4c8de0990621c481 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/internals/__pycache__/blocks.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c0f8644c28c746247a8f2a6cb433fe56aaeb21082ba7aac2015fc648653d23e +size 104055 diff --git a/py311/lib/python3.11/site-packages/pandas/core/internals/__pycache__/managers.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/internals/__pycache__/managers.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..73ded9e9978b5f76fc836789940de8061ddc2213 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/internals/__pycache__/managers.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3868023afb2220eb1edddd956001754e3271d31359b402f10c2e0bbfd414b2a7 +size 102447 diff --git a/py311/lib/python3.11/site-packages/pandas/core/reshape/__pycache__/merge.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/reshape/__pycache__/merge.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0593b663619ae2d9c311a6964485d4b85db87d6a --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/reshape/__pycache__/merge.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2256c815ae5da25b720953b5bc8d64a0595d5f1dd21c14dd454395729c8356ed +size 105096 diff --git a/py311/lib/python3.11/site-packages/pandas/core/strings/__pycache__/accessor.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/strings/__pycache__/accessor.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d393b400b7d588e7bc36d78f2655d90de0883fb --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/strings/__pycache__/accessor.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:958bd958c2a8b2996cdf21efb3e221f270b5930ac6688a8b0d39731a08057ac7 +size 128964 diff --git a/py311/lib/python3.11/site-packages/pandas/core/window/__pycache__/rolling.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/core/window/__pycache__/rolling.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed7fa769d3c481c4fdc0dd722af3ae89c87c720f --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/core/window/__pycache__/rolling.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b66ebf9e03165c3f4704f93a80585faf13bd505d095103a3c453d566d2fd210c +size 106957 diff --git a/py311/lib/python3.11/site-packages/pandas/io/__pycache__/pytables.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/io/__pycache__/pytables.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9219f3223634ca1c73a1a731a56071d07826e481 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/io/__pycache__/pytables.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ccace7e011f1baf3683e530adc0e99010de20901cd7e1b01e680045c2e00ef6 +size 230450 diff --git a/py311/lib/python3.11/site-packages/pandas/io/__pycache__/sql.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/io/__pycache__/sql.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3f58a42003e8c0a882fa6f9a145d10d496b7b16f --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/io/__pycache__/sql.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:029c192591eaa10806fa4f1e4dd9c8e5a4025ce615866233869535959eb9e5a1 +size 115546 diff --git a/py311/lib/python3.11/site-packages/pandas/io/__pycache__/stata.cpython-311.pyc b/py311/lib/python3.11/site-packages/pandas/io/__pycache__/stata.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..251156eb8b21a5331e0c9ff7f334f09619512f38 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pandas/io/__pycache__/stata.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:22b952325d626f5f0c190f5a0382662d5156a811b5c3254083d6e9222f65c676 +size 174279 diff --git a/py311/lib/python3.11/site-packages/pydantic/__pycache__/json_schema.cpython-311.pyc b/py311/lib/python3.11/site-packages/pydantic/__pycache__/json_schema.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe7a64e27d8336b511284c34a358637b6c7a2cb1 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pydantic/__pycache__/json_schema.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0e94aaa942b26e44af1ebd3f45e1408ab6a6f2933727e0d3a10e411dbf0c364 +size 134576 diff --git a/py311/lib/python3.11/site-packages/pydantic/__pycache__/types.cpython-311.pyc b/py311/lib/python3.11/site-packages/pydantic/__pycache__/types.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9b7cefd300f206ea18689bdce226265f2504d4d8 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pydantic/__pycache__/types.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba13897b40c90d895624ed58fd142e1b6abd84e1eb37e66640df6ee064d62a74 +size 104129 diff --git a/py311/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_generate_schema.cpython-311.pyc b/py311/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_generate_schema.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..38651ba999f691c935ca42b83930939dfe76a664 --- /dev/null +++ b/py311/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_generate_schema.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9839f06503f89069437d5513e1d6e3bd2357f27786150ad6a75cff3efb38b4eb +size 144255 diff --git a/py311/lib/python3.11/site-packages/rapidfuzz/distance/_initialize_cpp.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/rapidfuzz/distance/_initialize_cpp.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..aced24f3560eed3782c5a311d03202dfe779fc9d --- /dev/null +++ b/py311/lib/python3.11/site-packages/rapidfuzz/distance/_initialize_cpp.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4563329ad44390d11badd4f7cdaa6c0a1b96283da840593b5b53e5d260582e7 +size 310488 diff --git a/py311/lib/python3.11/site-packages/rapidfuzz/distance/metrics_cpp.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/rapidfuzz/distance/metrics_cpp.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..568ce2407972cb09028c05cabddff7236868e0e8 --- /dev/null +++ b/py311/lib/python3.11/site-packages/rapidfuzz/distance/metrics_cpp.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0e7c52cf1c141bea82acd27234719f8ae184561373cc769502a00ee8c8e3722 +size 2988424 diff --git a/py311/lib/python3.11/site-packages/rapidfuzz/distance/metrics_cpp_avx2.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/rapidfuzz/distance/metrics_cpp_avx2.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..41049cb56c3c9c623db5798ffb9f71fc69f147be --- /dev/null +++ b/py311/lib/python3.11/site-packages/rapidfuzz/distance/metrics_cpp_avx2.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c0cb12dff44a64713eb11de4cc48d268b1cad1755bb534a7c05ce0495a24677 +size 3062120 diff --git a/py311/lib/python3.11/site-packages/rich/__pycache__/_emoji_codes.cpython-311.pyc b/py311/lib/python3.11/site-packages/rich/__pycache__/_emoji_codes.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c64a9a45f54670c9c57efa641df3f736713a8b10 --- /dev/null +++ b/py311/lib/python3.11/site-packages/rich/__pycache__/_emoji_codes.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:31303f676acfa5414b8f22d7b81079656be144d718a0b4c5a00afd8033c5017b +size 208518 diff --git a/py311/lib/python3.11/site-packages/rich/__pycache__/console.cpython-311.pyc b/py311/lib/python3.11/site-packages/rich/__pycache__/console.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2091e8683cb83d8efb2df627110b158958c23006 --- /dev/null +++ b/py311/lib/python3.11/site-packages/rich/__pycache__/console.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:419193eb52be04d5cadefec86dbf460b798e0020aba3352aa1092dbe320b56fc +size 125276 diff --git a/py311/lib/python3.11/site-packages/scipy/_lib/_uarray/_uarray.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/_lib/_uarray/_uarray.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..f5e17f86dd4dae54f55d4eab4c0f6e185e120867 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/_lib/_uarray/_uarray.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df29055dbb67bcbbf69e2eeb2c00a92912477a8b86706066a797a277fe75e146 +size 111000 diff --git a/py311/lib/python3.11/site-packages/scipy/constants/__pycache__/_codata.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/constants/__pycache__/_codata.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..15a418bdda35ae40e617f47b0aab9fd1275461dc --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/constants/__pycache__/_codata.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4873dd479a3dea8c233c1b1289c6b72249caeb464967affc978ccb05023bcb23 +size 205213 diff --git a/py311/lib/python3.11/site-packages/scipy/fft/_pocketfft/pypocketfft.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/fft/_pocketfft/pypocketfft.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..53d54c08c299d89d686d5499d080ca52d7ce984d --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/fft/_pocketfft/pypocketfft.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61da7e809d8e5cdf88ee2840894111d2e9c73b8e0c010378aeee36454c993051 +size 1208728 diff --git a/py311/lib/python3.11/site-packages/scipy/fftpack/tests/fftw_double_ref.npz b/py311/lib/python3.11/site-packages/scipy/fftpack/tests/fftw_double_ref.npz new file mode 100644 index 0000000000000000000000000000000000000000..e1e3d620400746177b560b9193efce03c2841e99 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/fftpack/tests/fftw_double_ref.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a60c649415b645223924d8342ccc5c097801c86901287a369e53fc9259f5ec4e +size 162120 diff --git a/py311/lib/python3.11/site-packages/scipy/fftpack/tests/fftw_longdouble_ref.npz b/py311/lib/python3.11/site-packages/scipy/fftpack/tests/fftw_longdouble_ref.npz new file mode 100644 index 0000000000000000000000000000000000000000..b1a646889c9889541e8d368c8c2d96520d183dc4 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/fftpack/tests/fftw_longdouble_ref.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a406cbd4dad04d0c59dd38f54416fb49424c82229c1a074b6a44ec0cde2000e3 +size 296072 diff --git a/py311/lib/python3.11/site-packages/scipy/fftpack/tests/fftw_single_ref.npz b/py311/lib/python3.11/site-packages/scipy/fftpack/tests/fftw_single_ref.npz new file mode 100644 index 0000000000000000000000000000000000000000..a42748dba14b7ff0d2f53ce4cd5a86a4f08e5d93 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/fftpack/tests/fftw_single_ref.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:276a9141318e6fc36e4ab6ff54a61b64054ef8849b660f17359e5f541b43c526 +size 95144 diff --git a/py311/lib/python3.11/site-packages/scipy/fftpack/tests/test.npz b/py311/lib/python3.11/site-packages/scipy/fftpack/tests/test.npz new file mode 100644 index 0000000000000000000000000000000000000000..1e5a4e06615c6bcc58f0feff20f73e83439a937d --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/fftpack/tests/test.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:36de804a22d8fdea054590ce49ddf3c859838b7d89193c56b3bcb660cbf43797 +size 11968 diff --git a/py311/lib/python3.11/site-packages/scipy/integrate/__pycache__/_lebedev.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/integrate/__pycache__/_lebedev.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f490ac9e60ec54a1a5e6c294f0a250126ef2827e --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/integrate/__pycache__/_lebedev.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e3fcd4d3e7d1cc00034ec2913dde661a1dbd32829abb94f3295b775237d3574 +size 190054 diff --git a/py311/lib/python3.11/site-packages/scipy/interpolate/__pycache__/_bsplines.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/interpolate/__pycache__/_bsplines.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..302e78e8e7343cfd3d4f04c68b916e59eb8a7835 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/interpolate/__pycache__/_bsplines.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:917fdd931bd2f34908dbae2dd757970550d8656e912a17cefc5fb77b3eb61c8c +size 108889 diff --git a/py311/lib/python3.11/site-packages/scipy/interpolate/__pycache__/_fitpack2.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/interpolate/__pycache__/_fitpack2.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..86869124467b0b7a157a6afdbb2a4c3bfe0c883c --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/interpolate/__pycache__/_fitpack2.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9444bc95a70f6a392950c70d8ddeffc6fe2a567d8f13a46b7ac39a96a8d80ee1 +size 108327 diff --git a/py311/lib/python3.11/site-packages/scipy/interpolate/__pycache__/_interpolate.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/interpolate/__pycache__/_interpolate.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..43a21a25c65b1d9d44049e320445ffaecbcf7a66 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/interpolate/__pycache__/_interpolate.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7498d3e121510579ef97a103683a3f638d4fbe47f15fdc9d3d34ef414573d7b +size 101051 diff --git a/py311/lib/python3.11/site-packages/scipy/interpolate/tests/data/bug-1310.npz b/py311/lib/python3.11/site-packages/scipy/interpolate/tests/data/bug-1310.npz new file mode 100644 index 0000000000000000000000000000000000000000..8bddf805c36b29dc449556c27a2b489691f841af --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/interpolate/tests/data/bug-1310.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d6803c0b398f2704c236f1d1b9e8e5ede06bd165a0abb0f228281abbd455ae9 +size 2648 diff --git a/py311/lib/python3.11/site-packages/scipy/interpolate/tests/data/estimate_gradients_hang.npy b/py311/lib/python3.11/site-packages/scipy/interpolate/tests/data/estimate_gradients_hang.npy new file mode 100644 index 0000000000000000000000000000000000000000..c5ef8f63f263a476823ddeacf2571551c2fe4690 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/interpolate/tests/data/estimate_gradients_hang.npy @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:406c10857417ff5ea98d8cd28945c9d0e4f5c24f92a48ad0e8fab955bf2477f1 +size 35680 diff --git a/py311/lib/python3.11/site-packages/scipy/interpolate/tests/data/gcvspl.npz b/py311/lib/python3.11/site-packages/scipy/interpolate/tests/data/gcvspl.npz new file mode 100644 index 0000000000000000000000000000000000000000..50e9348dcca79eae861e67092add93cdb8ff1ca3 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/interpolate/tests/data/gcvspl.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03ce8155a6cba0c1bf0a2441a10c228191f916dec36cb820723429811296bba8 +size 3138 diff --git a/py311/lib/python3.11/site-packages/scipy/io/_fast_matrix_market/_fmm_core.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/io/_fast_matrix_market/_fmm_core.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..897f0839f7dd18fc61c8cd6f654c67c4af48b3fd --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/io/_fast_matrix_market/_fmm_core.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0b74c02bd2fa62de60d6cafba1803c4a16bea0f90249936bab0930435d48093 +size 4058784 diff --git a/py311/lib/python3.11/site-packages/scipy/io/matlab/_mio5_utils.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/io/matlab/_mio5_utils.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..3cafcf37e830189a1bae8320a3707afc63f75b1b --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/io/matlab/_mio5_utils.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:decc5e3ffee59f3e92574db637f3adc0408e16ea7f4b47f19ea4cc6a35e9d8f1 +size 231528 diff --git a/py311/lib/python3.11/site-packages/scipy/io/matlab/_streams.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/io/matlab/_streams.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..7bb69004eaf66520802a5c3b42146a9fef3e9a0b --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/io/matlab/_streams.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6996e6d1fa4f511e4951c4fd4fa8c1598bf2c3895e07757bc13ebc2f71996aa +size 131352 diff --git a/py311/lib/python3.11/site-packages/scipy/linalg/_cythonized_array_utils.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/linalg/_cythonized_array_utils.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..265d1777eb2a6c885edd3ad7e196a8fe5e60b0a2 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/linalg/_cythonized_array_utils.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18fc439056a75862cef1b78491a314d55ef185c7cc4280e65130d5ce913bf880 +size 321656 diff --git a/py311/lib/python3.11/site-packages/scipy/linalg/_decomp_interpolative.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/linalg/_decomp_interpolative.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..d3760b73ad8909cefdeee629fcb5207832cad3fa --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/linalg/_decomp_interpolative.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5377cb508949352ebdb9db9011fad69e0e21b8c1ba276447dccc038428e6ee3 +size 766224 diff --git a/py311/lib/python3.11/site-packages/scipy/linalg/_decomp_lu_cython.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/linalg/_decomp_lu_cython.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..d1f08dc691602fbb1e609c495cd19bd5ae489aab --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/linalg/_decomp_lu_cython.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc69d66a07f6c911503a42defb0db539db0f4121e71a7da217bfed2d2592e134 +size 116568 diff --git a/py311/lib/python3.11/site-packages/scipy/linalg/_flapack.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/linalg/_flapack.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..6c2a74409afc49e3cfe2da9c53b179bf9a9e0572 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/linalg/_flapack.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11dfc94def173c44ba43707f0f6f9fd05423f0bfe84555c94aa03b4e009173df +size 2560561 diff --git a/py311/lib/python3.11/site-packages/scipy/linalg/_linalg_pythran.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/linalg/_linalg_pythran.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..94da356c3e318253f53eca82b0c45533be071913 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/linalg/_linalg_pythran.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97df8980ad36f16e6d623e4721a7f0f9f621daff221d9365b73e0cb5113be0c3 +size 122792 diff --git a/py311/lib/python3.11/site-packages/scipy/linalg/_matfuncs_schur_sqrtm.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/linalg/_matfuncs_schur_sqrtm.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..44a1772422a5d65ec0cdd41cb34e4a1768122bc2 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/linalg/_matfuncs_schur_sqrtm.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29ef0f77a6e1fe99956b92fd60acb30f6c3bfb52ea5a65480bc7947ae987dca6 +size 486881 diff --git a/py311/lib/python3.11/site-packages/scipy/linalg/_solve_toeplitz.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/linalg/_solve_toeplitz.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..806cc9355a97186b2902637e2a795e5be0739226 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/linalg/_solve_toeplitz.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0127ca632eeb6e362fe27a8acae419b0748b5af5d6c6f02ba89b659355da2cc3 +size 124640 diff --git a/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/carex_15_data.npz b/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/carex_15_data.npz new file mode 100644 index 0000000000000000000000000000000000000000..660bbb41b7fad43ed945dc701693451ceb60166c --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/carex_15_data.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13f3e1491a876bbf59d7ea10ad29c1f9b5996a2ab99216f31d5bfcd659012c1e +size 34462 diff --git a/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/carex_18_data.npz b/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/carex_18_data.npz new file mode 100644 index 0000000000000000000000000000000000000000..0b3d569a1a65e9b5ff153ae4121a6a5a69409f7c --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/carex_18_data.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59f839467f2752b7df6fb6d4094396edd32a5929b764f7ffa1e6666431e6cac6 +size 161487 diff --git a/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/carex_19_data.npz b/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/carex_19_data.npz new file mode 100644 index 0000000000000000000000000000000000000000..90168ad4e888fba29a772ee13798ec126016140e --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/carex_19_data.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:38e8fc7b041df0b23d7e5ca15ead1a065e6467611ef9a848cc7db93f80adfd87 +size 34050 diff --git a/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/carex_20_data.npz b/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/carex_20_data.npz new file mode 100644 index 0000000000000000000000000000000000000000..87266deb46238307347362b63a4878f2565baf56 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/carex_20_data.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:14e222d34a7118c7284a1675c6feceee77b84df951a5c6ba2a5ee9ff3054fa1d +size 31231 diff --git a/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/carex_6_data.npz b/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/carex_6_data.npz new file mode 100644 index 0000000000000000000000000000000000000000..35d1681786c95602c4f0d5260fc5ad0ff4236189 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/carex_6_data.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b2a0736b541ebf5c4b9b4c00d6dab281e73c9fb9913c6e2581a781b37b602f9 +size 15878 diff --git a/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/gendare_20170120_data.npz b/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/gendare_20170120_data.npz new file mode 100644 index 0000000000000000000000000000000000000000..ff967f2ca0d0868aacf7d7e67402599e64bab817 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/linalg/tests/data/gendare_20170120_data.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3dfab451d9d5c20243e0ed85cd8b6c9657669fb9a0f83b5be165585783d55b5 +size 2164 diff --git a/py311/lib/python3.11/site-packages/scipy/ndimage/__pycache__/_morphology.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/ndimage/__pycache__/_morphology.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8dbb24ba96d7a865bd263a3b95bf5100016f1652 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/ndimage/__pycache__/_morphology.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc9febd3d53f352cfd0778dc1ea80a4195200b59f038a3fd85d87f99724652f6 +size 106090 diff --git a/py311/lib/python3.11/site-packages/scipy/optimize/__pycache__/_optimize.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/optimize/__pycache__/_optimize.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..750a6841df2559b23482b5310ab887c66948be52 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/optimize/__pycache__/_optimize.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34d05f9623b8614062bf8693a5eba34289b9082584887873639dddf57d716140 +size 158585 diff --git a/py311/lib/python3.11/site-packages/scipy/optimize/_highspy/_core.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/optimize/_highspy/_core.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..44766f1354fa969fff90c49ac85e05dd0d4edf83 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/optimize/_highspy/_core.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b274cf40a0e77eb483c02c30f54cc8271877baba3bc4d44a875872905a073911 +size 6326528 diff --git a/py311/lib/python3.11/site-packages/scipy/optimize/_highspy/_highs_options.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/optimize/_highspy/_highs_options.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..6691721064b0aa37e21f7f5f5c729e4d1303cdce --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/optimize/_highspy/_highs_options.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:121f8929dda9e00e127420304e475817f5c91ea6d99f414c345f6edad3e065e6 +size 357960 diff --git a/py311/lib/python3.11/site-packages/scipy/optimize/_trlib/_trlib.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/optimize/_trlib/_trlib.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..27c27bbb7c105d618bd75abaa20741b10fc1b259 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/optimize/_trlib/_trlib.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3bb95a61ee1002aadfd43c00b0405e3654a95f7927e8ac15bff739ac57cfc046 +size 212457 diff --git a/py311/lib/python3.11/site-packages/scipy/sparse/__pycache__/_coo.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/sparse/__pycache__/_coo.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..70685c5761be17d53eb351a7609bd3c0c7b76c8a --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/sparse/__pycache__/_coo.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3c31804e9a97ec088832f1e8c121fe1d32d86e81854f398c746d26e973d5c90 +size 100253 diff --git a/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_flow.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_flow.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..7ea8261d48016476dc2308d8a540c8e5a84d7033 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_flow.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:376002611dc1d28a2d192e778f23d57dfde322626e3092beccee83b242f84d97 +size 197256 diff --git a/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_matching.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_matching.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..b119b6f506b6a1242dbdd771b87fe9b4f6f829c1 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_matching.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bafa3100c184314f44f539632255a1b6b8f470fa7f0ef41dae74614043c1630a +size 192984 diff --git a/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_reordering.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_reordering.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..a2a47a44e706a7810fd3421fe3d0e8235e0360dd --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_reordering.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7568de05abd45e54e08493d89eab4188699078345ea3d44c99307261934232f4 +size 155312 diff --git a/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_shortest_path.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_shortest_path.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..61d364f9e265dc270efbedb57f6b1f7624dd143f --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_shortest_path.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0702d9202bd8767c624b512394d031f375d35703a7cf0a070fe86ee0854c8f61 +size 554416 diff --git a/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_tools.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_tools.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..99eff4217aba2f334b9fd6e72ec4b55dea18858a --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_tools.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3b2d2f2239c02d123879f4519c13cf0f01f813a1c8451cfb4ae2b2704d41769 +size 185440 diff --git a/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_traversal.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_traversal.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..eb85b156260189be10fcadd4d8b673bc25dec30f --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/sparse/csgraph/_traversal.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea85b51ef4d6f8f32e3845eab1414e6ef39b8d7a16a8784902129362dcdc7cc3 +size 344336 diff --git a/py311/lib/python3.11/site-packages/scipy/sparse/linalg/_dsolve/_superlu.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/sparse/linalg/_dsolve/_superlu.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..2193bdaf551aabe16c7ba360ce458a729bbd031c --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/sparse/linalg/_dsolve/_superlu.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d190577110967f76305c7742b4d224016fba2b377de6268001930ab3279496e4 +size 835729 diff --git a/py311/lib/python3.11/site-packages/scipy/sparse/linalg/_eigen/arpack/_arpacklib.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/sparse/linalg/_eigen/arpack/_arpacklib.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..da19a24ecc49a8af9826bfac35d646ce51eaa9f8 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/sparse/linalg/_eigen/arpack/_arpacklib.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3539cc36bd8a6ea49c79fe1b114d1d275272368363cce1c0c083fed16e369b57 +size 609793 diff --git a/py311/lib/python3.11/site-packages/scipy/sparse/linalg/_propack.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/sparse/linalg/_propack.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..8d20e7e5f3a678bc645c3d5929177a904c6f1cd8 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/sparse/linalg/_propack.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ebc5b8e185331c73cf4b0eeccaf65b79d93ee7f8c4ee1f8715576f4965b44226 +size 552529 diff --git a/py311/lib/python3.11/site-packages/scipy/sparse/linalg/tests/propack_test_data.npz b/py311/lib/python3.11/site-packages/scipy/sparse/linalg/tests/propack_test_data.npz new file mode 100644 index 0000000000000000000000000000000000000000..0bf01015610346655c749ead87a47d5575e2b67b --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/sparse/linalg/tests/propack_test_data.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfe34d9a92353e08f400f3837136e553a8e91d441186913d39b59bf8a627bba3 +size 600350 diff --git a/py311/lib/python3.11/site-packages/scipy/sparse/tests/data/csc_py2.npz b/py311/lib/python3.11/site-packages/scipy/sparse/tests/data/csc_py2.npz new file mode 100644 index 0000000000000000000000000000000000000000..d4459ff2786fabe4bcf4653d880cbf0afd4bfdcf --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/sparse/tests/data/csc_py2.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bac27f1a3eb1fdd102dae39b7dd61ce83e82f096388e344e14285071984d01fa +size 846 diff --git a/py311/lib/python3.11/site-packages/scipy/sparse/tests/data/csc_py3.npz b/py311/lib/python3.11/site-packages/scipy/sparse/tests/data/csc_py3.npz new file mode 100644 index 0000000000000000000000000000000000000000..e40a38584bc4647621601075d946ce46a8e065dc --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/sparse/tests/data/csc_py3.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b1b84315c7077417e720512d086a5a6217c2875b818d27704ae9b7237c69dfe +size 851 diff --git a/py311/lib/python3.11/site-packages/scipy/spatial/__pycache__/distance.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/spatial/__pycache__/distance.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55209be94d3aff874d85f28a4e6ccf3553ff4d81 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/spatial/__pycache__/distance.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:881363a8231fa2600c9c78ff8bc3538467bbbd806c90928970c303c7aebb1716 +size 104889 diff --git a/py311/lib/python3.11/site-packages/scipy/spatial/tests/data/degenerate_pointset.npz b/py311/lib/python3.11/site-packages/scipy/spatial/tests/data/degenerate_pointset.npz new file mode 100644 index 0000000000000000000000000000000000000000..4f22bd3a3c941a683747944a0f12c7914f4b3f07 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/spatial/tests/data/degenerate_pointset.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:048abc1ddd924bf2d4d1f216015552ed9431f9e99546fbf382768eda58788175 +size 22548 diff --git a/py311/lib/python3.11/site-packages/scipy/spatial/transform/__pycache__/_rotation.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/spatial/transform/__pycache__/_rotation.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..830e284e7f26c5c3d0f6a23c52beb16fe7b4c22b --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/spatial/transform/__pycache__/_rotation.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c699780aa18c797c9a02f1203b642f89480846b3137ecfa386bca815954b54f +size 115642 diff --git a/py311/lib/python3.11/site-packages/scipy/spatial/transform/_rigid_transform_cy.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/spatial/transform/_rigid_transform_cy.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..d5b36e54819785d90b11361e14e24a9d4288edb1 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/spatial/transform/_rigid_transform_cy.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:176b20b088772a6592e27837add1d448de45dedab744eeb7344595990f65c124 +size 254072 diff --git a/py311/lib/python3.11/site-packages/scipy/spatial/transform/_rotation_cy.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/spatial/transform/_rotation_cy.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..beb92e9c710cca88fb28f886daeecf6333998e8b --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/spatial/transform/_rotation_cy.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9486243380975a36c6ac7e59852b2f9f1a9b997edea21ef3a1f9e4b4c0cbbf0c +size 605328 diff --git a/py311/lib/python3.11/site-packages/scipy/special/__pycache__/_basic.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/special/__pycache__/_basic.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1aae22ca45799a6d3fcdc714fdf88ab7b2070b9a --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/special/__pycache__/_basic.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fef6f67947d8a8b7ff0af88815d330a988370c2163c88c2b807a99d8e32036d3 +size 121955 diff --git a/py311/lib/python3.11/site-packages/scipy/special/tests/data/boost.npz b/py311/lib/python3.11/site-packages/scipy/special/tests/data/boost.npz new file mode 100644 index 0000000000000000000000000000000000000000..6ada4fe916077ff0349c07c92407a647f5ab81d8 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/special/tests/data/boost.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:57b5c2b67ee01c741536aae6ad9f8f128106b7fdff152afcf3d8f774b0645844 +size 1270643 diff --git a/py311/lib/python3.11/site-packages/scipy/special/tests/data/gsl.npz b/py311/lib/python3.11/site-packages/scipy/special/tests/data/gsl.npz new file mode 100644 index 0000000000000000000000000000000000000000..a4e2a204e7cfdc7b251d0dea3b810dba42c20fe3 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/special/tests/data/gsl.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbf1afdd27999806a710279910a2eb2f9f7f559033c7ecb796deaa10c44feb31 +size 51433 diff --git a/py311/lib/python3.11/site-packages/scipy/special/tests/data/local.npz b/py311/lib/python3.11/site-packages/scipy/special/tests/data/local.npz new file mode 100644 index 0000000000000000000000000000000000000000..7d8bcb0730326acedc98a112af6c2fc752602fe1 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/special/tests/data/local.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c29e58ce827084f84db9f1bba96045a61ce69f1d3ea3d7c828a79c133cf88f2 +size 203438 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_continuous_distns.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_continuous_distns.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d6cca649892ed0e49a5b2029fc6bd8b1ba677b5 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_continuous_distns.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8183d23be3ea7421514f63f59cf7f6af8d95041da48aaf1db3602c48afbf9e4 +size 625311 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_discrete_distns.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_discrete_distns.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..29353229511317aabbb39d831cbdca04d62739f7 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_discrete_distns.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e3c62b2ae7b0b852dbcfcbeff3dd7fccd2bd10de8dcc7140aaa56aedb806226 +size 104023 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_distn_infrastructure.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_distn_infrastructure.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3c7e874f6a7f04ebeb4de01a4ca92b55847d681f --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_distn_infrastructure.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc60445c62d3dad960a7abde944a41c930221e328f3706ac2b9a24030b8cbc8d +size 190007 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_distribution_infrastructure.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_distribution_infrastructure.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7f44aa3f3f45472be0660bf71358471a81965c57 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_distribution_infrastructure.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:521c4c2a4d4ec18de86bffc3f268b62fc0754b7297aac4732ad0e6a5f5415733 +size 286108 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_hypotests.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_hypotests.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f315dc489ce01f9ccd14dfe922c5fb03fb06be4f --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_hypotests.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4eca175abc14f0c8b8ba814f10baf71ff4646cd982c825581c79f4e3b5d71019 +size 100420 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_morestats.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_morestats.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c68c64cbde1e48b69db0bd77c640d5c6560a818 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_morestats.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b60c40e395539d88a2bbe11af168ce323ce2ba4455f86e637ef8ada43f8bc6f4 +size 217829 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_mstats_basic.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_mstats_basic.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c14daf208374229956407acf13e4a44d0bb30bc0 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_mstats_basic.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc9f264b7d68a0480cb4e38d10cc0da67a7bc52f914da4d76aaddea17dbb4371 +size 160471 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_multivariate.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_multivariate.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e76965c607db21508b843333d2b33a3fb3514df6 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_multivariate.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a9683b68b5819420b96f50513f8273049a1b3dc58c544251a9f65ebd9f05043 +size 338518 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_qmc.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_qmc.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..673d30f87a8ef1cde0cd2d9efbfa6d6f60cc17fa --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_qmc.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85ded7300c74c80e569894f737c560466530d1354cacb041e07c462261dbc1dd +size 125626 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_resampling.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_resampling.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f31a5c9a6c60d551c2affcbd2d16351373876427 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_resampling.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97999ed4edec88c333531a2f92273b4c83803ee38c2c173d137453950be03796 +size 116872 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_stats_py.cpython-311.pyc b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_stats_py.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2e75bb27e62540005d47183545d27129c3cc8667 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/__pycache__/_stats_py.cpython-311.pyc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18b6d5e77ffff10048317f9eaf293143069544abe214c8072f604fa2e8bdd902 +size 465404 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/_rcont/rcont.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/stats/_rcont/rcont.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..2f1c5f3bea51b2e17e52cf612d03a32220329469 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/_rcont/rcont.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ade47b36607da5d05e29d5db00ef7c88e3947160563c2f9efd479206b50fcae +size 104296 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/_unuran/unuran_wrapper.cpython-311-x86_64-linux-gnu.so b/py311/lib/python3.11/site-packages/scipy/stats/_unuran/unuran_wrapper.cpython-311-x86_64-linux-gnu.so new file mode 100644 index 0000000000000000000000000000000000000000..ce93bc537ac2bb724d7646ad82284a82bbf0d561 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/_unuran/unuran_wrapper.cpython-311-x86_64-linux-gnu.so @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d1922dbc23f2158886dc45215165b61de33872be8a588c2b209bd5942b946bc +size 1342200 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/tests/data/jf_skew_t_gamlss_pdf_data.npy b/py311/lib/python3.11/site-packages/scipy/stats/tests/data/jf_skew_t_gamlss_pdf_data.npy new file mode 100644 index 0000000000000000000000000000000000000000..721749bcd853fa5c5efe5a1f5ba6e105658395dc --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/tests/data/jf_skew_t_gamlss_pdf_data.npy @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:254d2dee4a4d547b9331c60243c6fcfcaffd26c8b104d08d4f6045a7645b3bba +size 4064 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/tests/data/levy_stable/stable-Z1-cdf-sample-data.npy b/py311/lib/python3.11/site-packages/scipy/stats/tests/data/levy_stable/stable-Z1-cdf-sample-data.npy new file mode 100644 index 0000000000000000000000000000000000000000..adda664a7b5442fc0977ddbaa572c864ddd31f08 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/tests/data/levy_stable/stable-Z1-cdf-sample-data.npy @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf18c1f2d65a232bf2c7121282df31bf2a8be827afafc4ed810ed37457ee898a +size 183728 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/tests/data/levy_stable/stable-Z1-pdf-sample-data.npy b/py311/lib/python3.11/site-packages/scipy/stats/tests/data/levy_stable/stable-Z1-pdf-sample-data.npy new file mode 100644 index 0000000000000000000000000000000000000000..6c41166721b891a801cdc6828804c6da7233d625 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/tests/data/levy_stable/stable-Z1-pdf-sample-data.npy @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fee99512bab4ccc6569b47b924e4b034e1cdbab5624fafc7e120648bd5f7a128 +size 183688 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/tests/data/levy_stable/stable-loc-scale-sample-data.npy b/py311/lib/python3.11/site-packages/scipy/stats/tests/data/levy_stable/stable-loc-scale-sample-data.npy new file mode 100644 index 0000000000000000000000000000000000000000..0a1460e407521836a9b73a081609af4ccdb6deae --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/tests/data/levy_stable/stable-loc-scale-sample-data.npy @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3c719edd5431fb9e7b9ecb6d19e3ca7a9095298bd19f226685b0fca40f0c073 +size 9328 diff --git a/py311/lib/python3.11/site-packages/scipy/stats/tests/data/rel_breitwigner_pdf_sample_data_ROOT.npy b/py311/lib/python3.11/site-packages/scipy/stats/tests/data/rel_breitwigner_pdf_sample_data_ROOT.npy new file mode 100644 index 0000000000000000000000000000000000000000..80dde74dcda9a23dcdbf9a2f677eb9c98337b0a7 --- /dev/null +++ b/py311/lib/python3.11/site-packages/scipy/stats/tests/data/rel_breitwigner_pdf_sample_data_ROOT.npy @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eef4dc702dd8c6e31c18c74e1f81284c3e9ca2ab50282de39c9ad30b7bb8e76d +size 38624